Удаление файла в 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.

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


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

Я также использую метод 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 здесь .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.