Früher oder später muss deine Access-Anwendung raus aus der Datenbank und ran ans Dateisystem: einen Exportordner anlegen, eine CSV einlesen, ein Backup kopieren, alte Protokolldateien wegräumen. Das komfortabelste Werkzeug dafür ist das FileSystemObject (kurz FSO) aus der Microsoft Scripting Runtime.
Verweis setzen oder spät binden
Es gibt zwei Wege, das FSO zu nutzen.
Früh gebunden (mit Verweis) — im VBE unter Extras → Verweise → „Microsoft Scripting Runtime" anhaken. Dann bekommst du IntelliSense und kannst sauber typisieren:
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
Spät gebunden (ohne Verweis) — kein Häkchen nötig, dafür kein IntelliSense. Ideal, wenn du die Datenbank an viele Rechner weitergibst:
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Für weitergegebene Datenbanken ist
CreateObjectdie robustere Wahl: Ein fehlender oder verschobener Verweis führt sonst beim Kunden zu „Fehler beim Kompilieren". In den Beispielen unten nutzen wir späte Bindung.
Existiert das schon? FileExists und FolderExists
Bevor du etwas anlegst, kopierst oder löschst, prüfst du die Existenz — das erspart dir Laufzeitfehler:
Public Sub PruefePfade()
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FolderExists("C:\Export") Then
Debug.Print "Ordner ist da."
Else
Debug.Print "Ordner fehlt."
End If
If fso.FileExists("C:\Export\kunden.csv") Then
Debug.Print "Datei gefunden."
End If
Set fso = Nothing
End Sub
Ordner anlegen
CreateFolder erzeugt einen Ordner. Achtung: Es legt nur eine Ebene an und wirft
einen Fehler, wenn der Ordner schon existiert — deshalb immer vorher prüfen:
Public Sub OrdnerSicherstellen(ByVal pfad As String)
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(pfad) Then
fso.CreateFolder pfad
Debug.Print "Angelegt: "; pfad
End If
Set fso = Nothing
End Sub
Kopieren, Verschieben, Löschen
Drei Methoden decken den Alltag ab. Alle arbeiten direkt mit Pfaden:
Public Sub DateiOperationen()
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
' Kopieren – letzter Parameter True = vorhandene Datei überschreiben
fso.CopyFile "C:\Daten\quelle.xlsx", "C:\Backup\quelle.xlsx", True
' Verschieben (= umbenennen, wenn nur der Name anders ist)
fso.MoveFile "C:\Export\temp.csv", "C:\Export\fertig.csv"
' Löschen – zweiter Parameter True = auch schreibgeschützte Dateien
If fso.FileExists("C:\Export\alt.log") Then
fso.DeleteFile "C:\Export\alt.log", True
End If
Set fso = Nothing
End Sub
MoveFileundDeleteFilescheitern mit Laufzeitfehler, wenn die Zieldatei gesperrt ist (z. B. in Excel geöffnet) oder nicht existiert. In Produktivcode gehört hier eineOn Error-Behandlung dazu.
Textdatei schreiben
Zum Schreiben öffnest du einen TextStream. CreateTextFile legt eine neue Datei an
(zweiter Parameter True = überschreiben), WriteLine schreibt eine Zeile inklusive
Zeilenumbruch:
Public Sub LogSchreiben()
Dim fso As Object, ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.CreateTextFile("C:\Export\log.txt", True)
ts.WriteLine "Start: " & Now
ts.WriteLine "Datensätze verarbeitet: 42"
ts.Close ' Puffer leeren – Datei erst dann vollständig
Set ts = Nothing
Set fso = Nothing
End Sub
Willst du an eine bestehende Datei anhängen statt zu überschreiben, nutzt du
OpenTextFile mit dem Modus 8 (ForAppending):
' 8 = ForAppending, True = anlegen falls nicht vorhanden
Set ts = fso.OpenTextFile("C:\Export\log.txt", 8, True)
ts.WriteLine "Weiterer Eintrag: " & Now
ts.Close
Textdatei zeilenweise lesen
Zum Lesen öffnest du die Datei im Modus 1 (ForReading) und läufst mit
ReadLine bis AtEndOfStream durch:
Public Sub CsvEinlesen()
Dim fso As Object, ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists("C:\Export\kunden.csv") Then Exit Sub
Set ts = fso.OpenTextFile("C:\Export\kunden.csv", 1) ' 1 = ForReading
Do Until ts.AtEndOfStream
Dim zeile As String
zeile = ts.ReadLine
Dim felder() As String
felder = Split(zeile, ";")
Debug.Print "Name: " & felder(0) & " | Ort: " & felder(1)
Loop
ts.Close
Set ts = Nothing
Set fso = Nothing
End Sub
Die drei Öffnungsmodi im Überblick:
| Konstante | Wert | Bedeutung |
|---|---|---|
ForReading | 1 | Lesen |
ForWriting | 2 | Neu schreiben (überschreibt) |
ForAppending | 8 | Anhängen |
Über alle Dateien eines Ordners iterieren
Mit GetFolder bekommst du ein Ordner-Objekt, dessen Files-Auflistung du
durchläufst. Jedes File-Objekt kennt Name, Path, Size und DateLastModified:
Public Sub AlleCsvVerarbeiten()
Dim fso As Object, ordner As Object, f As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ordner = fso.GetFolder("C:\Export")
For Each f In ordner.Files
If LCase(fso.GetExtensionName(f.Name)) = "csv" Then
Debug.Print f.Name; " – "; f.Size; " Bytes – "; f.DateLastModified
End If
Next f
Set ordner = Nothing
Set fso = Nothing
End Sub
Analog gibt dir ordner.SubFolders alle Unterordner.
Die schlanke Alternative: Dir()
Für einfache Fälle brauchst du das FSO gar nicht — die eingebaute Funktion Dir()
liefert Dateinamen passend zu einem Muster. Beim ersten Aufruf übergibst du den
Pfad, danach rufst du Dir() ohne Argument für den nächsten Treffer auf:
Public Sub DirBeispiel()
Dim datei As String
datei = Dir("C:\Export\*.csv")
Do While datei <> ""
Debug.Print datei
datei = Dir ' nächster Treffer
Loop
End Sub
Dir() ist schnell und verweisfrei, kennt aber keine Datei-Eigenschaften wie Größe
oder Änderungsdatum und lässt sich nicht schachteln. Sobald du mehr willst als reine
Namen, greifst du zum FileSystemObject.
Zusammengefasst
- FSO per
CreateObject("Scripting.FileSystemObject")(spät gebunden, robust) oder per Verweis auf Microsoft Scripting Runtime (mit IntelliSense). - Vor jeder Aktion mit
FileExists/FolderExistsprüfen — das verhindert Laufzeitfehler. CopyFile,MoveFile,DeleteFilefür Dateioperationen;CreateFolderlegt nur eine Ebene an.- Textdateien über
OpenTextFile/CreateTextFilemitReadLine/WriteLine; Modi 1/2/8 für Lesen/Schreiben/Anhängen, und immerClosenicht vergessen. - Über
GetFolder(...).Filesiterierst du samt Eigenschaften;Dir()ist die schlanke Alternative für reine Namenslisten.