Usuwanie pliku w VBA

Odpowiedzi:

168

1.) Sprawdź tutaj . Zasadniczo zrób to:

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

Zostawię ci ustalenie różnych potrzebnych do obsługi błędów, ale są to jedne z rzeczy, które rozważałem:

  • Sprawdź, czy przekazywany jest pusty ciąg.
  • Sprawdź, czy w nazwie pliku / ścieżce nie ma ciągu zawierającego niedozwolone znaki

2.) Jak usunąć plik. Popatrz na to. Zasadniczo użyj polecenia Kill, ale musisz uwzględnić możliwość, że plik jest tylko do odczytu. Oto funkcja dla Ciebie:

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

Ponownie pozostawię obsługę błędów Tobie i ponownie rozważę następujące kwestie:

  • Czy powinno to zachowywać się inaczej w przypadku katalogu niż pliku? Czy użytkownik powinien wyraźnie wskazać, że chce usunąć katalog?

  • Czy chcesz, aby kod automatycznie resetował atrybut tylko do odczytu, czy też użytkownik powinien otrzymać jakąś wskazówkę, że ustawiono atrybut tylko do odczytu?


EDYCJA: Oznacz tę odpowiedź jako wiki społeczności, aby każdy mógł ją zmodyfikować, jeśli zajdzie taka potrzeba.

Onorio Catenacci
źródło
dziękuję - a co, jeśli istnieją dwa pliki o tej samej nazwie, które istnieją, czy subwoofer DeleteFile zabije oba z nich, czy tylko jeden? każda rada bardzo ceniona.
BKSpurgeon
6
Nie możesz mieć dwóch plików o tej samej nazwie w katalogu.
Onorio Catenacci
53

Alternatywnym sposobem zakodowania odpowiedzi Brettskiego, z którym w przeciwnym razie całkowicie się zgadzam, może być

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

Ten sam efekt, ale mniej (no cóż, żadnych) deklaracji zmiennych.

FileSystemObject to naprawdę przydatne narzędzie, z którym warto się zaprzyjaźnić. Poza wszystkim innym, zapisywanie plików tekstowych może czasami być szybsze niż starsza alternatywa, co może zaskoczyć kilka osób. (Przynajmniej z mojego doświadczenia, YMMV).

Mike Woodhouse
źródło
7
Używając tej składni bez deklarowania obiektu skryptowego pliku, należy dodać odniesienie do programu Microsoft Scripting Runtime, w przeciwnym razie: Dim fs As New Scripting.FileSystemObject
pghcpa
5
musisz również odwołać się do biblioteki skryptów. zobacz tutaj: stackoverflow.com/questions/3233203/…
ekkis
Ponieważ nie ma zmiennej, którą można ustawić na Nothing, czy istnieje ryzyko, że FileSystemObject pozostanie w pamięci, powodując wyciek lub inny problem?
johny why
Nie, zostanie odrzucone po „Zakończ na”. Ponieważ nie jest przypisany do zmiennej, efekt jest podobny do tego, że obiekt został przypisany do zmiennej, która została ustawiona na „Nothing”.
jony
15

Prawdopodobnie zostanę za to podpalony, ale jaki jest sens testowania istnienia, jeśli zamierzasz go usunąć? Jednym z moich głównych irytujących zwierząt jest aplikacja wyświetlająca okno dialogowe błędu z komunikatem „Nie można usunąć pliku, nie istnieje!”

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.

Jeśli plik nie istnieje w pierwszej kolejności, misja zakończona!

JohnFx
źródło
4
Masz rację, ale myślę, że jak większość rzeczy, będzie to zależało od kontekstu i czasami po prostu posiadanie funkcji „Plik istnieje” jest przydatna poza usunięciem.
Onorio Catenacci,
3
+1: być może użytkownik aplikacji chce zostać zapytany przed usunięciem pliku: na przykład użycie ActiveWorkbook.SaveCopyAsnie jest w stanie nadpisać, więc najpierw musisz usunąć istniejący plik o tej samej nazwie.
Joël
ale nigdy nie powinieneś używać On Error Resume Next, a przynajmniej tak mi powiedziano: D Oczywiście to absurdalna rada, a twoja odpowiedź jest poprawna.
johny why
Len(dir(...))Część nie jest wyłącznie w celu sprawdzenia istnienia. To jest również sprawdzenie, czy plik jest ukryty , ponieważ ukryty plik zwróci pusty ciąg nawet jeśli istnieje (i nie będzie w stanie go usunąć) Dir(hiddenFile) = "". Dlatego część SetAttr FileToDelete, vbNormalelokwentnie zajmuje się tym za Ciebie.
elektrykalAJ
11

Aby sprawdzić, czy plik istnieje, a następnie go usunąć, można użyć poniższych instrukcji.

Dim aFile As String
aFile = "c:\file_to_delete.txt"
If Len(Dir$(aFile)) > 0 Then
     Kill aFile
End If 
Rich Adams
źródło
3
Wiem, że to pytanie i odpowiedź są stare, pomyślałem tylko, że dodam, że użycie Len () do testowania ciągów (i funkcji, które zwracają ciągi) wydaje się być szybsze niż dosłowne porównywanie ciągów w VBA.
JimmyPena,
7
Powodem, dla którego Len()(i LenB(), co jest jeszcze szybsze) są szybsze niż porównywanie ciągów, jest to, że w pamięci ciągi VB są poprzedzone ich długością. Len / LenB po prostu pobierają długość z tego miejsca w pamięci, nie muszą iterować ciągu, aby poznać jego długość. Z drugiej strony, użycie porównania ciągów wymaga znacznie więcej pracy. Ponadto unikaj używania ""w VB, ponieważ zawsze przydziela nowy ciąg. Użyj vbNullStringzamiast tego, ponieważ jest to stała i nie zużywa więcej pamięci.
Renaud Bompuis,
7

W VB normalnie Dirznajduje się katalog pliku. Jeśli nie jest puste, to istnieje, a następnie użyj, Killaby pozbyć się pliku.

test = Dir(Filename)
If Not test = "" Then
    Kill (Filename)
End If
Leo Moore
źródło
6

ustaw odniesienie do biblioteki Scripting.Runtime, a następnie użyj FileSystemObject:

Dim fso as New FileSystemObject, aFile as File

if (fso.FileExists("PathToFile")) then
    aFile = fso.GetFile("PathToFile")
    aFile.Delete
End if
Brettski
źródło
Używam również metody FileSystemObject, ponieważ Kill nie może usunąć plików / folderów z
diakrytami
To jest metoda, której używam. Ktoś, kto to zaimplementuje, chce użyć sprawdzania błędów i DisplayAlerts = false. (Plik nie zostanie usunięty, jeśli jest używany, więc musi mieć pułapkę błędów)
Gregg Burns
3

Oto wskazówka: czy ponownie używasz nazwy pliku, czy planujesz zrobić coś, co wymaga natychmiastowego usunięcia?

Nie?

Możesz sprawić, aby VBA uruchamiał polecenie DEL "C: \ TEMP \ scratchpad.txt" / F z wiersza poleceń asynchronicznie za pomocą VBA.Shell:

Shell „DEL” & chr (34) & strPath & chr (34) & „/ F”, vbHide

Zwróć uwagę na podwójne cudzysłowy (znak ASCII 34) wokół nazwy pliku: Zakładam, że masz ścieżkę sieciową lub długą nazwę pliku zawierającą spacje.

Jeśli jest to duży plik lub ma wolne połączenie sieciowe, opuść i zapomnij. Oczywiście nigdy nie zobaczysz, czy to zadziałało, czy nie; ale natychmiast wznawiasz VBA i są chwile, kiedy jest to lepsze niż czekanie na sieć.

Nile
źródło
To świetna alternatywa, jeśli potrzebujesz asynchronii.
johny why
2

Można ustawić odwołanie do biblioteki Scripting.Runtime, a następnie użyć obiektu FileSystemObject. Ma metodę DeleteFile i metodę FileExists.

Zobacz artykuł MSDN tutaj .

Darrel Miller
źródło