Удаление файла в VBA

93

Используя VBA, как я могу:

  • проверьте, существует ли файл, и если да,
  • удалить его?
Теги:
file-io
delete-file
file-exists

9 ответов

130
Лучший ответ

1.) Проверьте здесь. В основном это:

Function FileExists(ByVal FileToTest As String) As Boolean
   FileExists = (Dir(FileToTest) <> "")
End Function

Я оставлю это вам, чтобы выяснить, нужна ли обработка ошибок, но они относятся к обработке ошибок, которые я бы рассматривал:

  • Проверьте, не прошла ли пустая строка.
  • Проверьте, что строка, содержащая символы, незаконна в имени файла/пути

2.) Как удалить файл. Посмотрите на this. В основном используйте команду Kill, но вам нужно разрешить доступ к файлу только для чтения. Здесь функция для вас:

Sub DeleteFile(ByVal FileToDelete As String)
   If FileExists(FileToDelete) Then 'See above          
      ' First remove readonly attribute, if set
      SetAttr FileToDelete, vbNormal          
      ' Then delete the file
      Kill FileToDelete
   End If
End Sub

Опять же, я оставлю вам обработку ошибок, и снова это то, что я подумал бы:

  • Должно ли это вести себя по-другому для каталога или файла? Должен ли пользователь явно указывать, что он хочет удалить каталог?

  • Вы хотите, чтобы код автоматически reset атрибут только для чтения или пользователь должен был указать какой-то признак того, что атрибут только для чтения установлен?


EDIT: Отметьте этот ответ как вики сообщества, чтобы любой мог его изменить, если это необходимо.

  • 0
    спасибо - что, если существуют два файла с одинаковыми именами, подпункт DeleteFile убьет их обоих или только один? Любой совет высоко ценится.
  • 6
    Вы не можете иметь два файла с одинаковым именем в каталоге.
Показать ещё 1 комментарий
41

Альтернативный способ кодирования ответа Бреттского, с которым я в целом согласен, может быть

With New FileSystemObject
    If .FileExists(yourFilePath) Then
        .DeleteFile yourFilepath
    End If
End With

Тот же эффект, но меньше (ну, вообще-то) никаких объявлений переменных.

FileSystemObject - действительно полезный инструмент, и стоит позаботиться о дружелюбности. Помимо всего прочего, для написания текстовых файлов это может иногда быть быстрее, чем альтернатива, которая может удивить некоторых людей. (По моему опыту, по крайней мере, YMMV).

  • 5
    Используя этот синтаксис без объявления объекта сценария файла, необходимо добавить ссылку на Microsoft Scripting Runtime, иначе: Dim fs As New Scripting.FileSystemObject
  • 3
    вам также нужно обратиться к библиотеке сценариев. смотрите здесь: stackoverflow.com/questions/3233203/…
Показать ещё 2 комментария
10

Я, вероятно, поплачу за это, но в чем смысл тестирования на существование, если вы просто собираетесь его удалить? Одним из моих главных мошенников для домашних животных является приложение, отображающее диалоговое окно с ошибкой с чем-то вроде "Не удалось удалить файл, его не существует!"

On Error Resume Next
aFile = "c:\file_to_delete.txt"
Kill aFile
On Error Goto 0
return Len(Dir$(aFile)) > 0 ' Make sure it actually got deleted.

Если файл не существует в первую очередь, миссия выполнена!

  • 3
    Вы подняли хороший вопрос, но, как и большинство вещей, я думаю, что это будет зависеть от контекста, и иногда просто иметь функцию «Файл существует» удобно, кроме удаления.
  • 2
    +1: может быть, пользователь приложения хочет получить запрос перед удалением файла: например, с помощью ActiveWorkbook.SaveCopyAs не может перезаписать, поэтому сначала необходимо удалить существующий файл с тем же именем файла.
Показать ещё 2 комментария
9

Для проверки наличия файла можно использовать следующее: а затем удалить его.

Dim aFile As String
aFile = "c:\file_to_delete.txt"
If Len(Dir$(aFile)) > 0 Then
     Kill aFile
End If 
  • 3
    Я знаю, что этот вопрос и ответ старые, но я подумал, что добавлю, что использование Len () для проверки строк (и функций, возвращающих строки) кажется быстрее, чем сравнение буквенных строк в VBA.
  • 6
    Причина того, что Len()LenB() , что даже быстрее) быстрее, чем сравнение строк, заключается в том, что в памяти строкам VB предшествует их длина. Len / LenB просто извлекают длину из этой ячейки памяти, им не нужно перебирать строку, чтобы узнать ее длину. С другой стороны, использование сравнения строк имеет гораздо больше работы. Кроме того, избегайте использования "" в VB, поскольку он всегда выделяет новую строку. vbNullString этого используйте vbNullString поскольку он является константой и не использует больше памяти.
6

В VB его обычно Dir найти каталог файла. Если он не пуст, он существует, а затем используйте Kill, чтобы избавиться от файла.

test = Dir(Filename)
If Not test = "" Then
    Kill (Filename)
End If
4

установите ссылку на библиотеку Scripting.Runtime, а затем используйте FileSystemObject:

Dim fso as New FileSystemObject, aFile as File

if (fso.FileExists("PathToFile")) then
    aFile = fso.GetFile("PathToFile")
    aFile.Delete
End if
  • 0
    Я тоже использую метод FileSystemObject, так как Kill не может удалить файлы / папки с диакритом
3

Вот совет: вы повторно используете имя файла или планируете сделать что-то, требующее немедленного удаления?

Нет?

Вы можете заставить VBA запускать команду DEL "C:\TEMP\scratchpad.txt" /F из командной строки асинхронно с помощью VBA.Shell:

  Shell "DEL" и chr (34) и strPath и chr (34) и "/F", vbHide

Обратите внимание на двойные кавычки (символ ASCII 34) вокруг имени файла: я предполагаю, что у вас есть сетевой путь или длинное имя файла, содержащее пробелы.

Если это большой файл, или он при медленном сетевом подключении, это способ пойти и забыть.  Конечно, вы никогда не узнаете, работает ли это или нет; но вы немедленно возобновляете свой VBA, и есть моменты, когда это лучше, чем ждать сети.

  • 0
    Это отличная альтернатива, если вы хотите asynch.
2

Вы можете установить ссылку на библиотеку Scripting.Runtime, а затем использовать FileSystemObject. Он имеет метод DeleteFile и метод FileExists.

См. статью MSDN здесь.

0

2 строки кода в VBA..

Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists(strPath) Then FSO.DeleteFile ("" & strPath & "")

Ещё вопросы

Сообщество Overcoder
Наверх
Меню