Für viele Fälle reichen die in VBA integrierten Befehle wie Dir, MkDir, Kill oder Copy aus. Manchmal stoßen Sie damit aber an die Grenzen der VBA-Bibliothek. In diesem Fall hilft möglicherweise das FileSystemObject weiter. Es bietet umfangreiche Möglichkeiten, auf Laufwerke, Verzeichnisse und Dateien zuzugreifen. Dieser Beitrag zeigt, wie Sie das FileSystemObject verfügbar machen und welche interessanten Aktionen Sie damit durchführen können.
Das FileSystemObject ist Bestandteil der Bibliothek Microsoft Scripting Runtime, die Sie zur einfacheren Programmierung per IntelliSense per Verweis einbinden (s. Bild 1). Den Verweise-Dialog öffnen Sie über den Menübefehl Extras|Verweise des VBA-Editors.
Bild 1: Verweis auf die Microsoft Scripting Runtime
Objekte
Das Objekt FileSystemObject ist das Hauptobjekt für den Zugriff auf Laufwerke, Verzeichnisse und Dateien. Wenn Sie auf eines dieser Objekte zugreifen möchten, benötigen Sie meist eine der Methoden des FileSystemObjects. Um das FileSystemObject zu nutzen, deklarieren und instanzieren Sie es zuvor:
Dim objFSO As Scripting.FileSystemObject Set objFSO = New Scripting.FileSystemObject
Danach greifen Sie per IntelliSense bequem auf seine Eigenschaften und Methoden zu.
Existenz von Laufwerken, Verzeichnissen und Dateien prüfen
In vielen Fällen werden Sie vor einer Aktion mit dem jeweiligen Objekt prüfen, ob dieses überhaupt existiert.
Beim Laufwerk liefert die Funktion DriveExists die notwendige Information. Das folgende Beispiel zeigt für einen modernen Rechner, dass es zwar ein Laufwerk mit dem Buchstaben c gibt, aber keines mit dem Buchstaben a:
Dim objFSO As Scripting.FileSystemObject Set objFSO = New Scripting.FileSystemObject Debug.Print objFSO.DriveExists("a") Debug.Print objFSO.DriveExists("c")
Bei Verzeichnissen ist die Funktion FolderExists für die Prüfung der Existenz verantwortlich. Die folgenden Zeilen belegen, dass das Verzeichnis, in dem sich die aktuelle Datenbank befindet, tatsächlich vorhanden ist:
Debug.Print objFSO.FolderExists(CurrentProject.Path)
ähnlich sieht es bei den Dateien aus – hier muss die Funktion FileExists Ihren Dienst verrichten. Die folgende Zeile liefert hoffentlich den Wert True zurück:
Debug.Print objFSO.FileExists(CurrentDb.Name)
Laufwerke
Auf die Laufwerke können Sie direkt mithilfe der Auflistung Drives des FileSystemObject-Objekts zugreifen. Die Anzahl der Laufwerke ermitteln Sie mit der Eigenschaft Drives.Count.
Den Zugriff auf die einzelnen Laufwerk-Objekte über die Item-Eigenschaft erhalten Sie nur durch Angabe des Laufwerkbuchstabens:
With objFSO Debug.Print "Laufwerke: ", .Drives.Count Debug.Print .Drives.Item("c").VolumeName End With
Wenn Sie alle Laufwerke samt Laufwerksbuchstabe und weiteren Informationen ermitteln möchten, greifen Sie per For Each-Schleife darauf zu.
Beispiele für den Zugriff auf die Elemente der Drives-Auflistung haben wir im Formular frmLaufwerke und dessen Klassenmodul untergebracht.
Als erstes soll das Kombinationsfeld mit dem Laufwerksbuchstaben in der gebundenen, unsichtbaren Spalte und dem Pfad als sichtbarem Eintrag gefüllt werden.
Dies erledigt die folgende Prozedur, die zunächst in einer For Each-Schleife alle Laufwerke des aktuellen Systems durchläuft. Dabei trägt Sie die für die Anzeige im Kombinationsfeld nötigen Daten zusammen. Das Ergebnis sieht etwa so aus:
C;C:;D;D:;E;E:;F;F:;G;G:;
Es wird also für jedes Laufwerk zunächst der einzelne Buchstabe und dann der Pfad ausgegeben. Da das Kombinationsfeld den Wert Wertliste für die Eigenschaft Herkunftsart sowie die Werte 2 und 0cm für die Eigenschaften Spaltenanzahl und Spaltenbreiten enthält, zeigt es genau die Pfade an (s. Bild 2).
Bild 2: Formular zur Anzeige von Laufwerksdaten
Der erste Eintrag wird gleich beim Laden des Formulars ausgewählt und die Prozedur DatenLesen ausgeführt, die das Formular mit weiteren Laufwerkseigenschaften füllt (s. Listing 1).
Listing 1: Einlesen von Informationen über das aktuell ausgewählte Laufwerk
Private Sub Form_Load() Dim objDrive As Scripting.Drive Dim strDrives As String Set objFSO = New Scripting.FileSystemObject For Each objDrive In objFSO.Drives With objDrive strDrives = strDrives & objDrive.DriveLetter & ";" & objDrive.Path & ";" End With Next objDrive Me!cboLaufwerke.RowSource = strDrives Me!cboLaufwerke = Me!cboLaufwerke.ItemData(0) DatenLesen End Sub
Die Prozedur DatenLesen wird nicht nur beim Laden, sondern auch nach dem Auswählen eines anderen Eintrags im Kombinationsfeld cboLaufwerke aufgerufen. Sie füllt die Textfelder des Formulars mit weiteren Informationen, die allesamt das jeweilige Drive-Objekt bereitstellt (s. Listing 2).
Listing 2: Einlesen von Informationen über das aktuell ausgewählte Laufwerk
Private Sub DatenLesen() Dim objDrive As Scripting.Drive Set objDrive = objFSO.Drives(Me!cboLaufwerke) With objDrive Me!txtDriveletter = .DriveLetter Me!txtDriveType = .DriveType Me!txtPath = .Path Me!txtShareName = .ShareName If .IsReady Then Me!txtFileSystem = .FileSystem Me!txtFreeSpace = .FreeSpace Me!txtRootFolder = .RootFolder Me!txtSerialNumber = .SerialNumber Me!txtTotalSize = .TotalSize Me!txtVolumename = .VolumeName Else MsgBox "Laufwerk ''" & Me!cboLaufwerke.Column(1) & "'' nicht bereit." Me!txtFileSystem = Null Me!txtFreeSpace = Null Me!txtRootFolder = Null Me!txtSerialNumber = Null Me!txtTotalSize = Null Me!txtVolumename = Null End If End With End Sub
Sollte das jeweilige Laufwerk nicht bereit sein, was beispielsweise bei CD- oder DVD-Laufwerken geschieht, die gerade keinen Datenträger enthalten, erscheint eine Meldung und es werden entsprechend weniger Informationen im Formular angezeigt. Diesen Zustand fragen Sie übrigens mit der Eigenschaft IsReady ab.
Verzeichnisse lesen
Prinzipiell ist c:\ auch ein Verzeichnis, zumindest wenn man der Nomenklatur des Objektmodells unterhalt des FileSystemObject-Objekts glaubt. Die Eigenschaft RootFolder liefert nämlich genau diese Information. Allerdings tut sie das nur, weil RootFolder ein eigenes Objekt mit der Eigenschaft Name als Standardeigenschaft ist. Mit der Eigenschaft RootFolder können Sie also auch ein Objekt des Typs Folder referenzieren – und zwar zum Beispiel c:\.
Unterhalb eines Laufwerks gibt es in der Regel einen oder mehrere Verzeichnisse. Auf diese greifen Sie über die Folders-Auflistung des Drive-Objekts zu.
Wenn Sie zuvor das RootFolder-Objekt eines Verzeichnisses ermitteln, in diesem Fall c:, greifen Sie wie folgt auf die unterhalb von c:\ liegenden Verzeichnisse zu und geben diese im Direktfenster aus (s. Listing 3).
Listing 3: Verzeichnisse eines Laufwerks ausgeben
Public Sub Verzeichnisse() Dim objFSO As Scripting.FileSystemObject Dim objDrive As Scripting.Drive Dim objRootFolder As Scripting.Folder Dim objFolder As Scripting.Folder Set objFSO = New Scripting.FileSystemObject Set objDrive = objFSO.Drives("c") Set objRootFolder = objDrive.RootFolder For Each objFolder In objRootFolder.SubFolders Debug.Print objFolder.path Next objFolder End Sub
Wenn Sie der For Each-Schleife dieser Prozedur noch die Anweisung
VerzeichnisseRek objFolder
hinzufügen und die folgende Prozedur erstellen, geben beide Prozeduren rekursiv alle Verzeichnisse des Laufwerks aus (s. Listing 4).
Listing 4: Verzeichnisse eines Laufwerks rekursiv ausgeben
Public Sub VerzeichnisseRek(objParentFolder As Scripting.Folder) Dim objFolder As Scripting.Folder For Each objFolder In objParentFolder.SubFolders Debug.Print objFolder.path VerzeichnisseRek objFolder Next objFolder End Sub
Sollten Sie dies mit Laufwerk c: ausprobieren, merken Sie sich schonmal die Tastenkombination Strg + Rollen zum Abbrechen des Vorgangs vor – dieser kann nämlich eine Weile dauern.
Normalerweise tritt auch schnell ein Fehler auf, und zwar beim Versuch, Elemente spezieller Verzeichnisse wie etwa Systemverzeichnisse einzulesen.
Ob ein Verzeichnis ein Systemverzeichnis ist, finden Sie mit der Eigenschaft Attributes heraus. Dieses enthält einen Zahlenwert, der sich aus den Zahlenwerten verschiedener Konstanten zusammensetzt. In diesem Fall lautete der Wert der Eigenschaft Attributes 22.
Dieser Wert enthält die Werte 16 (Directory), 4 (System) und 2 (Hidden). System und Hidden – das ist kein Verzeichnis, dessen Inhalt wohl nur von System-Instanzen gelesen werden sollte.
Solche Informationen erhalten Sie übrigens im Objektkatalog des VBA-Editors (s. Bild 3).
Bild 3: Konstanten des FileSystemObject-Objekts im Objektkatalog des VBA-Editors
Dateien lesen
Jedes Folder-Objekt hat eine Files-Auflistung, mit der Sie auf die im jeweiligen Verzeichnis gespeicherten Dateien zugreifen können.
Für das Rootverzeichnis c:\ gelingt dies beispielsweise mit der Prozedur aus Listing 5.
Listing 5: Auflisten aller Dateien eines Verzeichnisses
Public Sub Dateien() Dim objFSO As Scripting.FileSystemObject Dim objFolder As Scripting.Folder Dim objFile As Scripting.File Set objFSO = New Scripting.FileSystemObject Set objFolder = objFSO.Drives("c").RootFolder For Each objFile In objFolder.Files Debug.Print objFile.Name Next objFile End Sub
Dateiinformationen anzeigen
Wenn Sie eine Datei referenziert haben, greifen Sie leicht auf die Informationen dieser Datei zu. Das Formular frmAktuelleDatenbankdatei (s. Bild 4) zeigt beispielsweise die Daten zur aktuell geöffneten Datenbankdatei an. Dazu ist der Aufruf der Prozedur aus Listing 6 beim Laden des Formulars nötig.
Listing 6: Einlesen von Informationen zur aktuellen Access-Datei
Private Sub Form_Load() Dim objFSO As Scripting.FileSystemObject Dim objFile As Scripting.File Set objFSO = New Scripting.FileSystemObject Set objFile = objFSO.GetFile(CurrentDb.Name) With objFile Me!txtAttributes = .Attributes Me!txtDateCreated = .DateCreated Me!txtDateLastAccessed = .DateLastAccessed Me!txtDateLastModified = .DateLastModified Me!txtDrive = .Drive Me!txtName = .Name Me!txtParentFolder = .ParentFolder Me!txtPath = .Path Me!txtShortName = .ShortName Me!txtShortPath = .ShortPath Me!txtSize = .Size Me!txtType = .Type End With End Sub
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