Löschen einer Datei in VBA

121

Wie kann ich mit VBA:

  1. Testen Sie, ob eine Datei vorhanden ist, und wenn ja,
  2. Lösche es?
ZygD
quelle

Antworten:

168

1.) Überprüfen Sie hier . Grundsätzlich tun Sie dies:

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

Ich überlasse es Ihnen, die verschiedenen erforderlichen Fehlerbehandlungen herauszufinden, aber diese gehören zu den Fehlern, die ich in Betracht ziehen würde:

  • Überprüfen Sie, ob eine leere Zeichenfolge übergeben wird.
  • Suchen Sie nach einer Zeichenfolge mit unzulässigen Zeichen in einem Dateinamen / Pfad

2.) So löschen Sie eine Datei. Schau dir das an . Verwenden Sie grundsätzlich den Befehl Kill, aber Sie müssen die Möglichkeit berücksichtigen, dass eine Datei schreibgeschützt ist. Hier ist eine Funktion für Sie:

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

Wieder überlasse ich die Fehlerbehandlung Ihnen und wieder sind dies die Dinge, die ich berücksichtigen würde:

  • Sollte sich dies für ein Verzeichnis anders verhalten als für eine Datei? Sollte ein Benutzer explizit angeben müssen, dass er ein Verzeichnis löschen möchte?

  • Möchten Sie, dass der Code das schreibgeschützte Attribut automatisch zurücksetzt, oder sollte dem Benutzer eine Art Hinweis gegeben werden, dass das schreibgeschützte Attribut festgelegt ist?


BEARBEITEN: Markieren Sie diese Antwort als Community-Wiki, damit jeder sie bei Bedarf ändern kann.

Onorio Catenacci
quelle
danke - was ist, wenn zwei gleichnamige Dateien existieren, wird das DeleteFile-Sub beide oder nur eine töten? Jeder Rat sehr geschätzt.
BKSpurgeon
6
Sie können nicht zwei Dateien mit demselben Namen in einem Verzeichnis haben.
Onorio Catenacci
52

Eine alternative Möglichkeit, Brettskis Antwort zu codieren, der ich ansonsten völlig zustimme, könnte sein

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

Gleicher Effekt, aber weniger (naja, überhaupt keine) Variablendeklarationen.

Das FileSystemObject ist ein wirklich nützliches Tool und es lohnt sich, sich damit vertraut zu machen. Abgesehen von allem anderen kann das Schreiben von Textdateien manchmal sogar schneller sein als die herkömmliche Alternative, was einige Leute überraschen kann. (Zumindest nach meiner Erfahrung YMMV).

Mike Woodhouse
quelle
7
Wenn Sie diese Syntax verwenden, ohne ein
Dateiskriptobjekt
5
Sie müssen auch auf die Skriptbibliothek verweisen. siehe hier: stackoverflow.com/questions/3233203/…
ekkis
Besteht das Risiko, dass das FileSystemObject im Speicher verbleibt und ein Leck oder ein anderes Problem verursacht, da keine Variable auf Nothing gesetzt werden kann.
Johny, warum
Nein, es wird nach dem "Ende mit" verworfen. Da es keiner Variablen zugewiesen ist, ähnelt der Effekt dem Objekt, das einer Variablen zugewiesen wurde, die auf "Nichts" gesetzt wurde.
Jony
15

Ich werde wahrscheinlich dafür in Flammen stehen, aber was bringt es, auf Existenz zu testen, wenn Sie es einfach löschen wollen? Eine meiner größten Herausforderungen ist eine App, die einen Fehlerdialog mit dem Titel "Datei konnte nicht gelöscht werden, existiert nicht!" Auslöst.

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.

Wenn die Datei überhaupt nicht existiert, ist die Mission erfüllt!

JohnFx
quelle
4
Sie sprechen einen guten Punkt an, aber wie die meisten Dinge denke ich, dass dies vom Kontext abhängt und manchmal ist es neben dem Löschen praktisch, einfach eine "File Exists" -Funktion zu haben.
Onorio Catenacci
3
+1: Möglicherweise möchte der Benutzer der Anwendung gefragt werden, bevor eine Datei entfernt wird. Beispielsweise kann using ActiveWorkbook.SaveCopyAsnicht überschreiben, sodass Sie zuerst eine vorhandene Datei mit demselben Dateinamen entfernen müssen.
Joël
Aber du solltest es niemals benutzen On Error Resume Next, oder so wurde mir gesagt: D Natürlich ist das ein lächerlicher Rat, und deine Antwort ist richtig.
Johny, warum
Der Len(dir(...))Teil ist nicht NUR auf Existenz zu prüfen. Es wird auch überprüft, ob die Datei VERSTECKT ist, da eine versteckte Datei eine leere Zeichenfolge zurückgibt, selbst wenn sie vorhanden ist (und Sie sie nicht löschen können) : Dir(hiddenFile) = "". Daher SetAttr FileToDelete, vbNormalkümmert sich der Teil eloquent darum für Sie.
elektrykalAJ
11

Das Folgende kann verwendet werden, um die Existenz einer Datei zu testen und sie dann zu löschen.

Dim aFile As String
aFile = "c:\file_to_delete.txt"
If Len(Dir$(aFile)) > 0 Then
     Kill aFile
End If 
Rich Adams
quelle
3
Ich weiß, dass diese Frage und Antwort alt sind. Ich dachte nur, ich würde hinzufügen, dass die Verwendung von Len () zum Testen von Zeichenfolgen (und Funktionen, die Zeichenfolgen zurückgeben) schneller zu sein scheint als wörtliche Zeichenfolgenvergleiche in VBA.
JimmyPena
7
Der Grund dafür, dass Len()(und LenB(), was noch schneller ist) schneller als der Zeichenfolgenvergleich sind, ist, dass im Speicher VB-Zeichenfolgen ihre Länge vorangestellt ist. Len / LenB ziehen nur die Länge von diesem Speicherort, sie müssen nicht durch die Zeichenfolge iterieren, um ihre Länge zu kennen. Auf der anderen Seite hat die Verwendung des Zeichenfolgenvergleichs viel mehr Arbeit zu erledigen. Vermeiden Sie außerdem die Verwendung ""in VB, da immer eine neue Zeichenfolge zugewiesen wird. Verwenden Sie vbNullStringstattdessen, da es sich um eine Konstante handelt und nicht mehr Speicher benötigt.
Renaud Bompuis
7

In VB ist es normalerweise Dir, das Verzeichnis der Datei zu finden. Wenn es nicht leer ist, existiert es und wird verwendet Kill, um die Datei zu entfernen.

test = Dir(Filename)
If Not test = "" Then
    Kill (Filename)
End If
Leo Moore
quelle
6

Legen Sie einen Verweis auf die Scripting.Runtime-Bibliothek fest und verwenden Sie dann das FileSystemObject:

Dim fso as New FileSystemObject, aFile as File

if (fso.FileExists("PathToFile")) then
    aFile = fso.GetFile("PathToFile")
    aFile.Delete
End if
Brettski
quelle
Ich benutze auch die FileSystemObject-Methode, da Kill Dateien / Ordner mit Diakritis nicht löschen kann
mauek unak
Dies ist eine Methode, die ich verwende. Jemand, der dies implementiert, möchte die Fehlerprüfung und DisplayAlerts = false verwenden. (Die Datei wird nicht gelöscht, wenn sie verwendet wird, muss also eine Fehlerfalle haben)
Gregg Burns
3

Hier ist ein Tipp: Verwenden Sie den Dateinamen erneut oder planen Sie etwas, das sofort gelöscht werden muss?

Nein?

Sie können VBA veranlassen, den Befehl DEL "C: \ TEMP \ Scratchpad.txt" / F asynchron an der Eingabeaufforderung auszulösen mit VBA.Shell auszulösen:

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

Beachten Sie die doppelten Anführungszeichen (ASCII-Zeichen 34) um den Dateinamen: Ich gehe davon aus, dass Sie einen Netzwerkpfad oder einen langen Dateinamen mit Leerzeichen haben.

Wenn es sich um eine große Datei handelt oder eine langsame Netzwerkverbindung besteht, ist Fire-and-Forget der richtige Weg. Natürlich kann man nie sehen, ob dies funktioniert hat oder nicht. Sie setzen Ihren VBA jedoch sofort fort, und manchmal ist dies besser, als auf das Netzwerk zu warten.

Nil
quelle
Dies ist eine großartige Alternative, wenn Sie Asynchrone wünschen.
Johny, warum
2

Sie können einen Verweis auf die Scripting.Runtime-Bibliothek festlegen und dann das FileSystemObject verwenden. Es verfügt über eine DeleteFile-Methode und eine FileExists-Methode.

Siehe den MSDN-Artikel hier .

Darrel Miller
quelle