Dateisystem im Griff mit dem FileSystemObject

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.

pic001.png

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

pic002.png

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

pic003.png

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

pic004.png

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