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

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

  1. проверить, существует ли файл, и если да,
  2. удали это?

person Community    schedule 15.09.2008    source источник


Ответы (8)


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

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

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

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


РЕДАКТИРОВАТЬ: пометить этот ответ как вики сообщества, чтобы каждый мог его изменить при необходимости.

person Community    schedule 15.09.2008
comment
спасибо - что, если существуют два файла с одинаковым именем, убьет ли суб-файл DeleteFile их оба или только один? любой совет очень ценится. - person BKSpurgeon; 02.08.2016
comment
В каталоге не может быть двух файлов с одинаковыми именами. - person Onorio Catenacci; 02.08.2016

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

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

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

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

person Mike Woodhouse    schedule 16.09.2008
comment
Используя этот синтаксис без объявления объекта сценария файла, необходимо добавить ссылку для Microsoft Scripting Runtime, иначе: Dim fs As New Scripting.FileSystemObject - person pghcpa; 04.03.2015
comment
вам также необходимо сослаться на библиотеку сценариев. см. здесь: stackoverflow.com/ questions / 3233203 / - person ekkis; 14.05.2015
comment
Поскольку нет переменной, для которой нужно установить значение Nothing, существует ли риск того, что FileSystemObject останется в памяти, что приведет к утечке или другой проблеме? - person johny why; 24.09.2016
comment
Нет, он будет удален после окончания с. Поскольку он не назначен переменной, эффект аналогичен объекту, назначенному переменной, для которой установлено значение Nothing. - person jony; 01.01.2017

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

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.

Если файл вообще не существует, миссия выполнена!

person JohnFx    schedule 15.09.2008
comment
Вы поднимаете хороший вопрос, но, как и большинство вещей, я думаю, что это будет зависеть от контекста, и иногда просто наличие функции File Exists удобно, помимо удаления. - person Onorio Catenacci; 16.09.2008
comment
+1: возможно, пользователь приложения хочет, чтобы его спросили перед удалением файла: например, использование ActiveWorkbook.SaveCopyAs не может перезаписать, поэтому вам сначала нужно удалить существующий файл с тем же именем файла. - person Joël; 07.11.2013
comment
но вы никогда не должны использовать On Error Resume Next, по крайней мере, мне так сказали: D Конечно, это нелепый совет, и ваш ответ правильный. - person johny why; 23.09.2016
comment
Часть Len(dir(...)) НЕ ТОЛЬКО для проверки существования. Он также проверяет, является ли файл СКРЫТЫМ, потому что скрытый файл вернет пустую строку, даже если он существует (и вы не сможете его удалить): Dir(hiddenFile) = "". Следовательно, часть SetAttr FileToDelete, vbNormalэто часто заботится об этом за вас. - person elektrykalAJ; 07.02.2019

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

Dim aFile As String
aFile = "c:\file_to_delete.txt"
If Len(Dir$(aFile)) > 0 Then
     Kill aFile
End If 
person Rich Adams    schedule 15.09.2008
comment
Я знаю, что этот вопрос и ответ старые, просто подумал, что добавлю, что использование Len () для проверки строк (и функций, возвращающих строки) кажется быстрее, чем сравнение буквальных строк в VBA. - person JimmyPena; 18.11.2011
comment
Причина того, что Len()LenB(), что даже быстрее) быстрее, чем сравнение строк, заключается в том, что в памяти строкам VB предшествует их длина. Len / LenB просто извлекают длину из этой ячейки памяти, им не нужно перебирать строку, чтобы узнать ее длину. С другой стороны, при использовании сравнения строк нужно сделать гораздо больше. Кроме того, избегайте использования "" в VB, поскольку он всегда выделяет новую строку. Вместо этого используйте vbNullString, поскольку он является константой и не использует больше памяти. - person Renaud Bompuis; 12.11.2014

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

test = Dir(Filename)
If Not test = "" Then
    Kill (Filename)
End If
person Leo Moore    schedule 15.09.2008

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

Dim fso as New FileSystemObject, aFile as File

if (fso.FileExists("PathToFile")) then
    aFile = fso.GetFile("PathToFile")
    aFile.Delete
End if
person Brettski    schedule 15.09.2008
comment
Я также использую метод FileSystemObject, так как Kill не может удалять файлы / папки с диакритом. - person mauek unak; 21.10.2015
comment
Это метод, который я использую. Кто-то, кто его реализует, хочет использовать проверку ошибок и DisplayAlerts = false. (Файл не будет удален, если он используется, поэтому должен иметь ловушку ошибок) - person Gregg Burns; 25.10.2019

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

No?

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

Оболочка "DEL" & chr (34) & strPath & chr (34) & "/ F", vbHide

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

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

person Community    schedule 02.10.2014
comment
Это отличная альтернатива, если асинхронный - это то, что вам нужно. - person johny why; 23.09.2016

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

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

person Darrel Miller    schedule 15.09.2008