Dateimanagement mit dem FileSystemObject

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).

Verweis auf die Bibliothek Microsoft Scripting Runtime hinzufügen

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).

Die Elemente der Klasse FileSystemObject in der Übersicht im Objektkatalog

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

Schreibe einen Kommentar