Möchtest Du den gesamten Artikel lesen? Und vielleicht sogar den Artikel im PDF-Format und die Beispieldateien herunterladen? Dann hole Dir den Artikel gleich hier - völlig kostenlos!
VBA bietet bereits einige Befehle, mit denen wir Dateioperationen ausführen können. Wir können mit MkDir neue Verzeichnisse erstellen, mit Dir prüfen, ob Dateien oder Verzeichnisse vorhanden sind oder mit Kill Dateien löschen. Diese Befehle sind aber recht kompliziert in der Handhabung. Daher schauen wir uns in diesem Artikel einmal die Klasse “FileSystemObject” an, mit der wir deutlich komfortabler mit Dateien und Verzeichnissen arbeiten können. Damit lässt sich alles erledigen, was mit dem Anlegen, Kopieren, Verschieben und Löschen zusammenhängt – und vieles mehr.
Definition
Im Rahmen dieses Artikels werden wir folgende Bezeichnungen verwenden:
Verzeichnis: Laufwerksbuchstabe plus Unterverzeichnisse, zum Beispiel c:\Temp
Dateiname: Nur der Dateiname ohne Verzeichnisse, also beispielsweise Test.txt
Pfad: Verzeichnis plus Dateiname, hier also c:\Temp\Test.txt
Die Klasse FileSystemObject
Die Klasse FileSystemObject ist Teil der Bibliothek Microsoft Scripting Runtime, die wir als Erstes referenzieren müssen.
Dazu öffnen wir im VBA-Editor den Verweise-Dialog und fügen den entsprechenden Eintrag hinzu (siehe Bild 1).
Bild 1: Verweis auf die Bibliothek Microsoft Scripting Runtime hinzufügen
Danach können wir den Objektkatalog öffnen und finden alle Elemente der Klasse FileSystemObject vor (siehe Bild 2).
Bild 2: Die Elemente der Klasse FileSystemObject in der Übersicht im Objektkatalog
Hier steigen wir nun ein und schauen uns die verschiedenen Elemente erst einmal in der Übersicht an – später gehen wir detailliert auf jedes einzelne ein:
- BuildPath: Stellt aus Verzeichnis und Dateinamen einen Pfad zusammen und ergänzt gegebenenfalls das fehlende Backslash-Zeichen zwischen den beiden Elementen.
- CopyFile: Kopiert eine Datei.
- CopyFolder: Kopiert ein Verzeichnis.
- CreateFolder: Erstellt ein Verzeichnis.
- CreateTextFile: Erstellt eine Textdatei.
- DeleteFile: Löscht eine Datei.
- DeleteFolder: Löscht ein Verzeichnis.
- DriveExists: Prüft, ob ein Laufwerk vorhanden ist.
- Drives: Liefert eine Auflistung von Drive-Objekten, die Informationen zu den einzelnen Laufwerken liefern.
- FileExists: Prüft, ob eine Datei vorhanden ist.
- FolderExists: Prüft, ob ein Verzeichnis vorhanden ist.
- GetAbsolutePathname: Holt einen absoluten Pfadnamen.
- GetBaseName: Holt den Basisdateinamen ohne Dateiendung.
- GetDrive: Ermittelt ein Drive-Objekte auf Basis eines Laufwerksbuchstabens, des Laufwerksverzeichnisses oder des Rootverzeichnisses.
- GetDriveName: Ermittelt das Verzeichnis eines Laufwerkes auf Basis eines Verzeichnisses, das auch Unterordner enthalten kann.
- GetExtensionName: Holt die Dateinamenerweiterung.
- GetFile: Holt ein File-Objekt.
- GetFileName: Ermittelt einen Dateinamen.
- GetFileVersion: Ermittelt die Version einer Datei.
- GetFolder: Holt ein Folder-Objekt.
- GetParentFolderName: Ermittelt das übergeordnete Verzeichnis.
- GetSpecialFolder: Ermittelt ein Folder-Objekt zu einem Spezialverzeichnis.
- GetStandardStream: Liefert ein Stream-Objekt auf Basis einer Datei.
- GetTempName: Liefert einen zufälligen temporären Dateinamen.
- MoveFile: Verschiebt eine Datei.
- MoveFolder: Verschiebt ein Verzeichnis.
- OpenTextFile: Öffnet eine Textdatei.
Die Klasse FileSystemObject nutzen
Um die Elemente der Klasse FileSystemObjekt zu nutzen, müssen wir zunächst ein Objekt auf Basis dieser Klasse erstellen.
Das erledigen wir bei Early Binding, also mit vorhandenem Verweis auf die Bibliothek Microsoft Scripting Runtime, wie folgt:
Dim fso As Scripting.FileSystemObject Set fso = New Scripting.FileSystemObject
Wenn wir Late Binding nutzen, also ohne Verweis arbeiten wollen, nutzen wir:
Dim fso As Object Set fso = CreateObject("Scripting.FileSystemObject")
Der Vorteil von Early Binding liegt darin, dass wir während der Entwicklung die Funktionen von IntelliSense nutzen können.
Wir nutzen hier eine Objektvariable mit der Bezeichnung fso. Man könnte auch beispielsweise objFileSystemObject nutzen, damit man direkt weiß, welche Klasse damit referenziert wird.
Wir verwenden hier aus Platzgründen die kürzere Variante (eine Alternative ist objFSO).
Laufwerksinformationen ermitteln mit Drive
Die Drives-Auflistung liefert uns Informationen über die verschiedenen Laufwerke. Wir können folgende Informationen erhalten:
- AvailableSpace: Liefert den freien Speicherplatz in Bytes.
- DriveLetter: Liefert nur den Laufwerksbuchstaben, also beispielsweise c.
- DriveType: Liefert den Typ des Laufwerks als Zahlenwert mit den möglichen Werten 0 (Unknown Type), 1 (Removable), 2 (Fixed), 3 (Remote), 4 (CDRom) oder 5 (RamDisk).
- FileSystem: Liefert beispielsweise den Wert FAT32 oder NTFS.
- FreeSpace: Liefert den freien Speicherplatz für den aktuellen Benutzer. Dieser kann identisch sein mit dem Wert von AvailableSpace.
- IsReady: Gibt an, ob das Laufwerk verfügbar ist.
- Path: Gibt den Laufwerkbuchstaben gefolgt von einem Doppelpunkt an, zum Beispiel c:.
- RootFolder: Gibt den Laufwerkbuchstaben gefolgt von einem Doppelpunkt und einem Backslash an, zum Beispiel c:\.
- SerialNumber: Gibt die Seriennummer des Laufwerks an.
- ShareName: Liefert den Namen der Windows-Freigabe, wenn das Laufwerk ein Netzlaufwerk ist. Anderenfalls liefert es eine leere Zeichenkette.
- TotalSize: Gibt den gesamten Speicherplatz des Laufwerks in Bytes zurück.
- VolumeName: Beschriftung des Laufwerks, wie er im Windows Explorer angezeigt wird.
Mit der Prozedur aus Listing 1 geben wir alle Informationen aller Laufwerke aus, indem wir diese in einer For Each-Schleife über die Drives-Auflistung durchlaufen. Dabei weisen wir die einzelnen Elemente einer Objektvariablen namens objDrive mit dem Typ FileSystemObject.Drive zu.
Public Sub LaufwerksbuchstabenErmitteln() Dim fso As Scripting.FileSystemObject Dim objDrive As Scripting.Drive Set fso = New Scripting.FileSystemObject For Each objDrive In fso.Drives Debug.Print "AvailbableSpace: " & objDrive.AvailableSpace Debug.Print "DriveLetter:" & objDrive.DriveLetter Debug.Print "DriveType:" & objDrive.DriveType Debug.Print "FileSystem:" & objDrive.FileSystem Debug.Print "FreeSpace:" & objDrive.FreeSpace Debug.Print "IsReady:" & objDrive.IsReady Debug.Print "Path:" & objDrive.Path Debug.Print "RootFolder:" & objDrive.RootFolder Debug.Print "SerialNumber:" & objDrive.SerialNumber Debug.Print "ShareName:" & objDrive.ShareName Debug.Print "TotalSize:" & objDrive.TotalSize Debug.Print "VolumeName:" & objDrive.VolumeName Next objDrive End Sub
Listing 1: Prozedur zur Ausgabe von Laufwerksinformationen im Direktbereich
Für das Laufwerk C:\ erhalten wir beispielsweise folgende Ausgabe im Direktbereich:
AvailbableSpace: 207972556800 DriveLetter:C DriveType:2 FileSystem:NTFS FreeSpace:207972556800 IsReady:Wahr Path:C: RootFolder:C:\ SerialNumber:-966946150 ShareName: TotalSize:1999516987392 VolumeName:Hauptlaufwerk
Laufwerk referenzieren mit GetDrive
Mit der Funktion GetDrive können wir ein Drive-Objekt zu einem Ausdruck wie c, c: oder c:\ ermitteln.
Im folgenden Beispiel deklarieren wir eine Drive-Variable namens objDrive und weisen ihr das Ergebnis der GetDrive-Funktion für c:\ zu.
Danach geben wir den verfügbaren Speicherplatz dieses Laufwerks aus:
Public Sub LaufwerkReferenzieren() Dim fso As Scripting.FileSystemObject Dim objDrive As Scripting.Drive Set fso = New Scripting.FileSystemObject Set objDrive = fso.GetDrive("c:\") Debug.Print objDrive.AvailableSpace End Sub
Die Standardeigenschaft der Drive-Klasse ist die Eigenschaft Path.
Wir können c: also auch einfach so ausgeben lassen:
Debug.Print objDrive
Name eines Laufwerks ermitteln mit GetDriveName
Mit der Funktion GetDriveName können wir den Namen eines Laufwerks für einen beliebigen Pfad ermitteln.
Wenn wir also etwas das Laufwerk benötigen, auf dem sich die aktuelle Datenbankdatei befindet, nutzen wir die folgenden Anweisungen (siehe Funktion LaufwerkNameErmitteln), der wir CurrentProject.Path als Parameter übergeben:
Dim fso As Scripting.FileSystemObject Dim objDrive As Scripting.Drive Set fso = New Scripting.FileSystemObject Debug.Print fso.GetDriveName(CurrentProject.Path)
Mit DriveExists prüfen, ob ein Laufwerk existiert
Die Funktion DriveExists prüft, ob ein Laufwerk existiert. Dazu können wir den Laufwerksbuchstaben (c), das Verzeichnis (c:) oder das Rootverzeichnis (c:\) übergeben. Für das Laufwerk d: liefert die folgende Prozedur beispielsweise den Wert False, wenn kein entsprechendes Laufwerk vorhanden ist:
Dim fso As Scripting.FileSystemObject Dim objDrive As Scripting.Drive Set fso = New Scripting.FileSystemObject Debug.Print fso.DriveExists("d:\")
Mit Verzeichnissen arbeiten
Nachdem wir die Funktionen für die Laufwerke erledigt haben, kommen wir zu den Funktionen für den Umgang mit Verzeichnissen. Hier können wir Verzeichnisse erstellen, prüfen, ob ein Verzeichnis existiert, Verzeichnisse löschen, kopieren oder verschieben, Eigenschaften von Verzeichnissen auslesen und übergeordnete Verzeichnisse oder Spezialverzeichnisse ermitteln.
Verzeichnisse erstellen mit CreateFolder
Mit der Methode CreateFolder können wir ein Verzeichnis erstellen. Dazu geben wir einfach den kompletten Pfad zum Verzeichnis an, zum Beispiel c:\Temp\Ordner 1:
fso.CreateFolder "c:\Temp\Ordner 1"
Wenn wir versuchen, einen Ordner zu erstellen, der bereits vorhanden ist, erhalten wir Fehler 58, Datei existiert bereits. Um dies zu verhindern, können wir mit FolderExists vorab prüfen, ob das Verzeichnis bereits vorhanden ist (siehe weiter unten).
Wir können mit CreateFolder immer nur ein Verzeichnis gleichzeitig erstellen. Um c:\Temp\Ordner 1\Ordner 2 zu erstellen, benötigen wir zwei Anweisungen:
fso.CreateFolder "c:\Temp\Ordner 1" fso.CreateFolder "c:\Temp\Ordner 1\Ordner 2"
Wir können auch das Ergebnis von CreateFolder mit einer Folder-Variablen referenzieren, um dann die Operationen der Folder-Klasse auszuführen – mehr dazu weiter unten (dort finden wir eine weitere Methode zum Anlegen von Verzeichnissen):
Dim objFolder As Scripting.Folder Set objFolder = fso.CreateFolder("c:\Temp\Ordner 1")
Mit FolderExists prüfen, ob ein Verzeichnis existiert
Mit der Funktion FolderExists können wir prüfen, ob ein Verzeichnis bereits existiert. Dieser Funktion übergeben wir den vollständigen Pfad bis zu dem zu untersuchenden Verzeichnis:
Debug.Print fso.FolderExists("c:\Temp\Ordner 1")
Vor den verschiedenen Operationen auf Basis eines Verzeichnisses sollten wir in einer If…Then-Bedingung prüfen, ob das Verzeichnis überhaupt vorhanden ist:
If fso.FolderExists("c:\Temp\Ordner 1") Then ''... Operationen mit diesem Verzeichnis End If
Verzeichnisse löschen mit DeleteFolder
Mit der Methode DeleteFolder können wir Verzeichnisse löschen.
fso.DeleteFolder "c:\Temp\Ordner 1"
Wenn sich im Verzeichnis beispielsweise eine aktuell geöffneten Access-Datenbank befindet, liefert DeleteFolder Fehler 70, Zugriff verweigert. Das Gleiche ist der Fall, wenn der Ordner schreibgeschützt ist.
Wenn wir ein solches Verzeichnis dennoch löschen wollen, können wir DeleteFolder für den zweiten Parameter Force den Wert True übergeben:
fso.DeleteFolder "c:\Temp\Ordner 1", True
Dies löscht jedoch nur schreibgeschützte Elemente, eine geöffnete Access-Datenbank oder andere durch das System schreibgeschützten Elemente lassen sich auch auf diese Weise nicht löschen.
Verzeichnisse kopieren mit CopyFolder
Die Methode CopyFolder kopiert das mit dem ersten Parameter angegebene Verzeichnis in das Verzeichnis aus dem zweiten Parameter. Dabei werden auch alle enthaltenen Unterverzeichnisse und Dateien kopiert.
Wenn wir also den Inhalt von Ordner 1 in einen neuen Ordner 2 kopieren wollen, der gleichzeitig angelegt wird, verwenden wir diesen Aufruf:
fso.CopyFolder "c:\Temp\Ordner 1", "c:\temp\Ordner 2"
Wenn wir das Verzeichnis Ordner 1 in Ordner 2 kopieren wollen, sodass Ordner 2 unterhalb von Ordner 1 angelegt wird, nutzen wir:
fso.CopyFolder "c:\Temp\Ordner 1", "c:\temp\Ordner 2\"
Mit dem dritten Parameter OverwriteFiles können wir noch angeben, dass eventuell vorhandene Dateien und Verzeichnisse gleichen Namens überschrieben werden sollen.
Verzeichnisse verschieben mit MoveFolder
Auf die gleiche Weise arbeitet MoveFolder, nur dass das ursprüngliche Verzeichnis bei diesem Vorgang gelöscht wird:
fso.MoveFolder "c:\Temp\Ordner 1", "c:\temp\Ordner 2\"
Folder-Objekt holen mit GetFolder
Die FileSystemObject-Klasse bietet nicht nur eine Drive-Klasse mit weiteren Eigenschaften eines Laufwerks, sondern auch entsprechende Klassen für Verzeichnisse (Folder) und Dateien (File).
Das Folder-Objekt liefert weitere Methoden und Eigenschaften für Verzeichnisse.
Um ein solches zu erhalten, nutzen wir zum Beispiel die GetFolder-Funktion. Das Ergebnis weisen wir einer Variablen des Typs Folder zu, die wir zuvor deklarieren:
Dim objFolder As Scripting.Folder Set objFolder = fso.GetFolder("c:\Temp\Ordner 1") Debug.Print objFolder
Danach können wir die Methoden und Eigenschaften von objFolder nutzen – mehr dazu weiter unten. Hier geben wir nur die Standardeigenschaft aus, nämlich den Pfad zu diesem Verzeichnis:
c:\Temp\Ordner 1
Übergeordnetes Verzeichnis ermitteln mit GetParentFolderName
Mit der Funktion GetParentFolderName der FileSystemObject-Klasse ermitteln wir das übergeordnete Verzeichnis eines Verzeichnisses:
Debug.Print fso.GetParentFolderName("c:\Temp\Ordner 1")
Dies liefert:
c:\Temp
Spezialverzeichnisse ermitteln mit GetSpecialFolder
Mit der Funktion GetSpecialFolder können wir verschiedene Standardverzeichnisse ermitteln. Dazu übergeben wir einen der folgenden Werte:
- SystemFolder (1): Liefert standardmäßig C:\Windows\System32.
- TemporaryFolder (2): Liefert standardmäßig C:\Users\User\AppData\Local\Temp.
- WindowsFolder (0): Liefert standardmäßig C:\Windows.
Die Funktion rufen wir wie folgt auf:
Debug.Print fso.GetSpecialFolder(SystemFolder) Debug.Print fso.GetSpecialFolder(TemporaryFolder) Debug.Print fso.GetSpecialFolder(WindowsFolder)
Das Ergebnis lautet:
C:\Windows\System32 C:\Users\User\AppData\Local\Temp C:\Windows
Hier ist zu beachten, dass GetSpecialFolder jeweils ein Folder-Objekt liefert und die Debug.Print-Anweisungen wieder den Wert der Standardeigenschaft liefern.
Wie können das Ergebnis also auch einer Folder-Objektvariablen zuweisen und damit weitere Operationen ausführen (siehe weiter unten).
Operationen der Folder-Klasse
Wenn wir beispielsweise mit GetFolder oder GetSpecialFolder einen Verweis auf ein Folder-Objekt geholt haben, können wir dessen Methoden und Eigenschaften nutzen, die wir in den folgenden Abschnitten vorstellen. Diese liefert die folgenden Elemente:
- Attributes: Liefert einen Zahlenwert, der verschiedene Attribute kombiniert.
- Copy: Kopiert das Verzeichnis in das angegebene Verzeichnis.
- CreateTextFile: Erstellt eine Textdatei im Verzeichnis.
- DateCreated: Liefert das Erstellungsdatum des Verzeichnisses.
- DateLastAccessed: Liefert das Datum des letzten lesenden Zugriffs.
- DateLastModified: Liefert das Datum des letzten schreibenden Zugriffs.
- Delete: Löscht das Verzeichnis.
- Drive: Ermittelt einen Verweis auf das Drive-Objekt des Verzeichnisses.
- Files: Liefert die Files-Auflistung des Verzeichnisses.
- IsRootFolder: Gibt an, ob es sich bei dem Verzeichnis um das Rootverzeichnis handelt, also beispielsweise c:\.
- Move: Verschiebt das Verzeichnis in das angegebene Verzeichnis.
- Name: Liefert den Namen des Verzeichnisses.
- ParentFolder: Liefert ein Folder-Objekt für das übergeordnete Verzeichnis.
- Path: Liefert den Pfad zu dem Verzeichnis.
- ShortName: Liefert den kurzen Namen des Verzeichnisses.
- ShortPath: Liefert den kurzen Pfad des Pfades zum Verzeichnis.
- Size: Liefert die Größe des Verzeichnisses inklusive der enthaltenen Dateien.
- SubFolders: Liefert eine Auflistung der Unterordner des Verzeichnisses.
- Type: Gibt den Typ des Verzeichnisses aus.
In den folgenden Abschnitten setzen wir voraus, dass wir objFolder zuvor mit einem Verweis auf ein Verzeichnis gefüllt haben.
Attribute eines Verzeichnisses mit Attributes ermitteln
Für ein herkömmliches Verzeichnis liefert das Attributes-Attribut den Wert 16. Die Werte können wir im Objektkatalog unter FileAttribute einsehen.
Die Werte lauten Alias (1.024), Archive (32), Compressed (2.048), Directory (16), Hidden (2), Normal (0), ReadOnly (1), System (4) und Column (8). Sie gelten gleichermaßen für das File– und das Folder-Objekt.
Ob ein Verzeichnis eines der genannten Attribute aufweist, können wir prüfen, indem wir wie folgt vorgehen – hier am Beispiel des Attributs Directory:
Dim objFolder As Scripting.Folder Set objFolder = fso.GetFolder("c:\Temp") Debug.Print objFolder.Attributes If (objFolder.Attributes And Directory) = Directory Then Debug.Print "Verzeichnis hat das Attribut ''Directory''" End If
Ermitteln, wann ein Verzeichnis erstellt, gelesen oder bearbeitet wurde
Mit den drei Eigenschaften DateCreated, DateLastAccessed und DateLastModified finden wir heraus, wann ein Verzeichnis erstellt, zuletzt gelesen und zuletzt bearbeitet wurde:
Set objFolder = fso.GetFolder("c:\Temp") Debug.Print objFolder.DateCreated Debug.Print objFolder.DateLastAccessed Debug.Print objFolder.DateLastModified
Die Ausgabe lautet beispielsweise:
22.07.2025 22:09:37 08.10.2025 22:21:56 08.10.2025 22:21:56
Weitere Verzeichniseigenschaften
Das Folder-Objekt liefert noch einige weitere Eigenschaften, die wir hier zusammenfassen und für ein Verzeichnis mit einem längeren Namen als acht Zeichen ausgeben:
Set objFolder = _ fso.CreateFolder("c:\temp\LangerVerzeichnisname") Debug.Print objFolder.IsRootFolder Debug.Print objFolder.Name Debug.Print objFolder.Path Debug.Print objFolder.ShortName Debug.Print objFolder.ShortPath Debug.Print objFolder.Size
Die Ergebnisse lauten:
Falsch ''IsRootFolder LangerVerzeichnisname ''Name C:\Temp\LangerVerzeichnisname ''Path LANGER~1 ''ShortName C:\temp\LANGER~1 ''ShortPath 0 ''Size
Verzeichnis kopieren mit Copy
Um das Verzeichnis aus objFolder in ein anderes Verzeichnis zu kopieren, rufen wir Folgendes auf:
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo