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

Ответы:

168

1.) Отметьте здесь . В основном это делают:

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

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

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

2.) Как удалить файл. Посмотри на это. В основном используйте команду 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

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

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

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


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

Онорио Катеначчи
источник
спасибо - что, если существуют два файла с одинаковыми именами, убьет ли суб-файл DeleteFile их оба или только один? любой совет очень ценится.
BKSpurgeon 01
6
В каталоге не может быть двух файлов с одинаковыми именами.
Онорио Катеначчи
53

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

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

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

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

Майк Вудхаус
источник
7
При использовании этого синтаксиса без объявления объекта сценария файла необходимо добавить ссылку на Microsoft Scripting Runtime, иначе: Dim fs As New Scripting.FileSystemObject
pghcpa
5
вам также необходимо сослаться на библиотеку сценариев. см. здесь: stackoverflow.com/questions/3233203/…
ekkis
Поскольку нет переменной, для которой нужно установить значение Nothing, существует ли риск того, что FileSystemObject останется в памяти, что приведет к утечке или другой проблеме?
johny why
Нет, он будет удален после «Завершить с». Поскольку он не назначен переменной, эффект аналогичен объекту, назначенному переменной, для которой установлено значение «Ничего».
jony
15

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

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.

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

JohnFx
источник
4
Вы поднимаете хороший вопрос, но, как и многие другие вещи, я думаю, что это будет зависеть от контекста, и иногда просто наличие функции «Файл существует», помимо удаления, удобно.
Онорио Катеначчи,
3
+1: возможно, пользователь приложения хочет, чтобы его спросили перед удалением файла: например, использование ActiveWorkbook.SaveCopyAsне может перезаписать, поэтому вам сначала нужно удалить существующий файл с тем же именем файла.
Joël
но вы никогда не должны использовать On Error Resume Next, по крайней мере, мне так сказали: D Конечно, это смешной совет, и ваш ответ правильный.
Джонни Почему
Len(dir(...))Часть не ИСКЛЮЧИТЕЛЬНО для проверки существования. Также проверить , если файл скрыт , так как скрытый файл будет возвращать пустую строку , даже если она существует (и вы не сможете удалить его): Dir(hiddenFile) = "". Следовательно, часть SetAttr FileToDelete, vbNormalкрасноречиво позаботится об этом за вас.
elektrykalAJ 07
11

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

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

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

test = Dir(Filename)
If Not test = "" Then
    Kill (Filename)
End If
Лео Мур
источник
6

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

Dim fso as New FileSystemObject, aFile as File

if (fso.FileExists("PathToFile")) then
    aFile = fso.GetFile("PathToFile")
    aFile.Delete
End if
Brettski
источник
Я также использую метод FileSystemObject, так как Kill не может удалять файлы / папки с
диакритом
Я использую этот метод. Кто-то, кто его реализует, хочет использовать проверку ошибок и DisplayAlerts = false. (Файл не будет удален, если он используется, поэтому должен иметь ловушку ошибок)
Грегг Бернс
3

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

Нет?

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

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

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

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

Нил
источник
Это отличная альтернатива, если вам нужен асинхронный режим.
johny why
2

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

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

Даррел Миллер
источник