VBA Получение ошибки времени выполнения (5) при попытке удалить существующий файл

Я получаю ошибку времени выполнения недействительной процедуры (ошибка № 5) в этой строке:

afiles(countoflines).Delete True

Я не могу понять, почему. Сохранение копии по пути работает нормально, и назначение ФСО файлам папки работает, но я не могу удалить 'х'й проиндексированный элемент в папке. Может ли кто-нибудь помочь с этим? Спасибо

Option Explicit

Private Sub Workbook_Open()

Dim aFSO As New Scripting.FileSystemObject
Dim aFolder As Object
Dim aFiles As Object

Set aFolder = aFSO.GetFolder("R:\Groups\Finance\Ops Finance\Reporting\F18 Cost Analysis\Standard Costing\Std Cost Variances\Variance Master Back-Ups\")
If aFolder Is Nothing Then MsgBox "Directory not found!", vbExclamation: Exit Sub

Set aFiles = aFolder.Files

Application.StatusBar = "Saving back up copy"

ThisWorkbook.SaveCopyAs aFolder.Path & "\" & _
VBA.Replace(ThisWorkbook.Name, ".xlsm", "") & "_copy_" & _
VBA.Format$(Now, "m-d-yyyy hhmmss AM/PM") & ".xlsm"

Call CleanUpArchive(aFolder, aFolder.Path & Chr(92), aFiles.Count)

Set aFolder = Nothing
Set aFSO = Nothing

End Sub



'Cleans up archive file by deleting the 11th file (oldest copy)
Private Function CleanUpArchive(Folder As Object, Path As String, _
CountofFiles As Integer)

Dim aFiles As Scripting.Files
Set aFiles = Folder.Files

If CountofFiles > 10 Then
aFiles(CountofFiles).Delete True
End If

Set aFiles = Nothing

End Function

person Mike Mirabelli    schedule 31.07.2018    source источник
comment
Можете ли вы попробовать использовать оператор Kill для полного пути, например: Kill "c:\path\to\file.txt"?   -  person David Zemens    schedule 31.07.2018
comment
Я также не уверен, что Files(Files.Count) представляет собой последний или самый последний файл в каталоге.   -  person David Zemens    schedule 31.07.2018
comment
Спасибо Дэвид Земенс. Убить тоже не получилось. может быть, это объект   -  person Mike Mirabelli    schedule 31.07.2018
comment
Можете ли вы обновить свой вопрос, включив в него использование оператора Kill, а также показать, каково значение пути, который вы передаете этому оператору? Это не удастся, если файл заблокирован/используется.   -  person David Zemens    schedule 31.07.2018
comment
Возможно, придется объявить вариант для циклического перебора предметов и уничтожения в зависимости от условия.   -  person Mike Mirabelli    schedule 31.07.2018
comment
Да, вам, вероятно, нужен другой способ определить, какой файл нужно удалить. Затем, предполагая, что файл не заблокирован, вы сможете его Kill.   -  person David Zemens    schedule 31.07.2018
comment
Если вы хотите реорганизовать код, вы, скорее всего, можете сделать это без FileSystemObject. См. эти недавние вопросы и ответы, в которых объясняется как использовать функцию Dir для обхода файлов, а затем использует некоторые вызовы WinAPI для определения DateLastModified (я думаю, вы также можете изменить это на DateCreated).   -  person David Zemens    schedule 31.07.2018


Ответы (1)


Непроверенный, написанный на мобильном телефоне. Приведенный ниже код не сильно отличается от вашего кода, но может делать то, что вам нужно.

Option Explicit

Private Sub Workbook_Open()

Dim folderPath as string
folderPath = dir$("R:\Groups\Finance\Ops Finance\Reporting\F18 Cost Analysis\Standard Costing\Std Cost Variances\Variance Master Back-Ups\", vbdirectory)

If Len(folderPath) = 0 then
Msgbox("Could not locate folder")
Exit sub
Elseif strcomp(right(folderPath, 1),"\", vbbinarycompare) <> 0 then ' this might be unnecessary, depends if dir() on vbdirectory returns \ at end or not, cannot remember or test'
folderPath = folderPath & "\"
End if

Dim filenames() as string
Redim filenames(1 to 2, 1 to 1000) ' 1000 = magic number, change if needed.'

Dim fileIndex as long

Dim filename as string
Filename = dir$(folderPath & "*")

Do until Len(filename) = 0

Fileindex = fileindex +1
Filename(1, fileindex) = folderPath & filename
Filenames(2, fileindex) = filedatetime(Filename(1, fileindex))
Filename = dir$()

Loop

Redim preserve filenames(1 to 2, 1 to fileindex)

ThisWorkbook.SaveCopyAs folderPath & _
VBA.Replace(ThisWorkbook.Name, ".xlsm", "_copy_" & _
VBA.Format$(Now, "m-d-yyyy hhmmss AM/PM") & ".xlsm")

Dim Oldest as Date
Dim OldestIndex as long

Oldest = filenames(2,1) ' Initialise with first value'

' Might be better to store below in dictionary -- or any key-value/associative structure. But should work nonetheless.'
For fileindex = lbound(filenames,2) to ubound(filenames,2)
If filenames(2, fileindex) < oldest then
Oldest = filenames(2, fileindex)
OldestIndex = fileindex
End if
Next fileindex

Dim fileIsOpen as Boolean

On error resume next
Open filenames(1, OldestIndex) For Input Lock Read As #1
fileIsOpen = err.number <> 0
On error goto 0
Close #1

If fileIsOpen then
msgbox("Attempted to delete file at:" & filenames(1, OldestIndex) & " but file may be open elsewhere or by another user.")
Exit sub
Else
' In theory, the file could go from not-in-use to in-use between the check above and the delete below. Might be better just to try to kill without checking but with on error resume, and then checking if file still exists or is open.'
Kill filenames(1, OldestIndex)
End if

End sub
person chillin    schedule 31.07.2018
comment
Спасибо за это, это похоже на хорошее решение. Тем не менее, я использовал функцию Dir(), как упомянул Дэвид Земенс, и сделал Kill на основе сравнения текущей даты и даты, созданной для каждой даты, и удаления тех, которые старше «x» дней. Спасибо хоть. - person Mike Mirabelli; 01.08.2018