{"id":55001583,"date":"2026-02-01T00:00:00","date_gmt":"2026-02-06T13:35:39","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1583"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Ordner_und_Dateien_in_AccessTabellen_einlesen","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/","title":{"rendered":"Ordner und Dateien in Access-Tabellen einlesen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg01.met.vgwort.de\/na\/694b7a4402934b5396dfd534d93dd302\" width=\"1\" height=\"1\" alt=\"\"><b>Es gibt verschiedene Gr&uuml;nde, warum man Ordner und Dateien aus dem Filesystem in eine entsprechende Datenstruktur einlesen sollte. Der Erste ist offensichtlich: Weil man die Laufwerke, Ordner und Dateien oder auch nur Teile davon innerhalb der Datenbank anzeigen m&ouml;chte, beispielsweise um zu sehen, welche Dateien zu einem bestimmten Projekt oder Kunden geh&ouml;ren. Der erste Schritt auf dem Weg zu einer solchen Anzeige ist das Einlesen der gew&uuml;nschten Struktur &#8211; unabh&auml;ngig davon, ob man den kompletten Inhalt einer Festplatte in seinen Tabellen abbilden m&ouml;chte oder auch nur den Inhalt eines Unterverzeichnisses. Zum Einlesen von Laufwerken, Ordnern und Dateien gibt es verschiedene M&ouml;glichkeiten auf beiden Seiten. Auf der Seite des Dateisystems k&ouml;nnen wir mit der Dir-Funktion oder alternativ mit dem FileSystemObject arbeiten, und beim Schreiben in die Tabellen der Datenbank bietet sich unter DAO das Schreiben mit AddNew\/Update oder mit der Execute-Methode an. In diesem Artikel stellen wir die schnellsten Versionen vor, damit das Einlesen umfangreicher Verzeichnis- und Dateistrukturen nicht unn&ouml;tig lange dauert. <\/b><\/p>\n<h2>Alles oder nur einen Teil einlesen?<\/h2>\n<p>Technisch haben wir alle M&ouml;glichkeiten. Wir k&ouml;nnen mit den Elementen und Methoden der <b>FileSystemObject<\/b>-Klasse auf alle Laufwerke zugreifen und uns von dort auch durch die einzelnen Verzeichnisse arbeiten und schlie&szlig;lich die darin enthaltenen Dateien ermitteln.<\/p>\n<p>Das ist jedoch nur bedingt sinnvoll, da die Datenmengen schnell riesig werden und wir den in unserer Datenbank gespeicherten Bestand m&ouml;glichst synchron mit der Festplatte halten wollen. Das erfordert regelm&auml;&szlig;ige Aktualisierungen, was jeweils Minuten oder sogar Stunden dauern kann.<\/p>\n<p>Also entscheiden wir uns bereits an dieser Stelle, immer nur einen Teil des Dateisystems einzulesen &#8211; in diesem Fall beginnend mit der Angabe des Verzeichnisses, dessen Inhalte wir erfassen wollen.<\/p>\n<p>Den Ausgangspunkt f&uuml;r den zu entwickelnden Algorithmus bildet also die Auswahl des Verzeichnisses, dessen Unterelemente wir in unser Datenmodell &uuml;berf&uuml;hren wollen.<\/p>\n<h2>Datenmodell f&uuml;r die Erfassung von Verzeichnissen und Dateien<\/h2>\n<p>Um die Struktur des Dateisystems bez&uuml;glich des von uns gew&auml;hlten Ordners in einer Datenbank zu speichern, haben wir ebenfalls mehrere M&ouml;glichkeiten.<\/p>\n<p>Wir k&ouml;nnen einfach eine Tabelle erstellen, in die wir immer den vollst&auml;ndigen Pfad der Verzeichnisse und Dateien schreiben. Das macht es aber aufwendiger, etwa ein TreeView mit diesen Daten zu f&uuml;llen.<\/p>\n<p>Wir m&uuml;ssten uns dann mit vielen Zeichenkettenoperationen durch die einzelnen Verzeichnisebenen eines Pfades arbeiten, was sehr viel Zeit kostet. Au&szlig;erdem ist es nicht unbedingt sehr platzsparend, wenn wir immer wieder die gleichen &uuml;bergeordneten Verzeichnisse in einem Datensatz ablegen.<\/p>\n<p>Also w&auml;hlen wir die Alternative, die aus einem Satz von drei Tabellen besteht. Hier ben&ouml;tigen wir zun&auml;chst eine Tabelle, um die Verzeichnisse zu speichern, beginnend mit den Verzeichnissen der ersten Ebene. Die dazu ben&ouml;tigten Felder lauten beispielsweise <b>FolderID <\/b>und <b>Foldername<\/b>. Damit sind wir allerdings darauf beschr&auml;nkt, nur Ordnernamen speichern zu k&ouml;nnen &#8211; wir m&uuml;ssen also noch einen Weg finden, die Zuordnung der einzelnen Verzeichnisse zum jeweils &uuml;bergeordneten Verzeichnis zu markieren.<\/p>\n<p>Also f&uuml;gen wir der Tabelle noch ein Feld namens <b>ParentID <\/b>hinzu, mit dem wir f&uuml;r einen Ordner jeweils den Datensatz mit dem &uuml;bergeordneten Ordner angeben k&ouml;nnen. Wir speichern also in einer Tabelle sowohl die Ordnernamen als auch die Information &uuml;ber die Hierarchie dieser Ordner.<\/p>\n<p>&Uuml;ber das Feld <b>ParentID<\/b> erzeugen wir eine reflexive Beziehung der Datens&auml;tze der Tabelle auf sich selbst. Schlie&szlig;lich f&uuml;gen wir der Tabelle, die wir <b>tblFolder <\/b>nennen und deren Entwurf wie in Bild 1 aussieht, noch ein Feld namens <b>UID <\/b>hinzu.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_01\/pic_1583_001.png\" alt=\"Tabelle zum Speichern der Ordner\" width=\"549,6265\" height=\"373,9264\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Tabelle zum Speichern der Ordner<\/span><\/b><\/p>\n<p>In NTFS-Dateisystemen (New Technology File System), die bereits mit Windows 3.1 eingef&uuml;hrt wurden, k&ouml;nnen wir mit API-Funktionen eine eindeutige ID f&uuml;r Ordner und Dateien ermitteln. Wozu wir diese ben&ouml;tigen und wie wir diese auslesen, erl&auml;utern wir sp&auml;ter.<\/p>\n<p>Zun&auml;chst k&uuml;mmern wir uns aber um die Tabelle zum Speichern der Dateiinformationen. Diese enth&auml;lt wiederum ein Prim&auml;rschl&uuml;sselfeld (<b>FileID<\/b>), ein Feld zum Speichern des Dateinamens (<b>Filename<\/b>) sowie ein Feld, mit dem wir die Beziehung zu dem Ordner herstellen, in dem sich die Datei befindet, und die wir wiederum <b>ParentID <\/b>nennen. Au&szlig;erdem f&uuml;gen wir auch hier ein Feld namens UID f&uuml;r den eindeutigen Identifizierer f&uuml;r die Datei sowie zwei Felder zum Speichern der Dateigr&ouml;&szlig;e und des Anlage- beziehungsweise letzten &Auml;nderungsdatums hinzu (siehe Bild 2).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_01\/pic_1583_002.png\" alt=\"Tabelle zum Speichern der Dateien\" width=\"549,6265\" height=\"406,5979\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Tabelle zum Speichern der Dateien<\/span><\/b><\/p>\n<p>Schlie&szlig;lich f&uuml;gen wir im Beziehungen-Fenster noch die notwendigen Beziehungen hinzu (siehe Bild 3). Hier ziehen wir zun&auml;chst die Tabelle <b>tblFolder<\/b> zwei Mal hinein und erstellen eine Beziehung des Feldes <b>ParentID<\/b> des im Beziehungen-Fenster mit <b>tblFolders_1 <\/b>benannten zweiten Exemplars der Tabelle <b>tblFolders <\/b>zu dem mit <b>tblFolder <\/b>benannten Exemplar. Damit realisieren wir die Beziehung von Unterordnern zum &uuml;bergeordneten Ordner. Au&szlig;erdem ziehen wir noch einen Beziehungspfeil vom Feld <b>ParentID <\/b>der Tabelle <b>tblDateien <\/b>zum Feld <b>FolderID <\/b>der Tabelle <b>tblFolders<\/b>.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_01\/pic_1583_004.png\" alt=\"Beziehungen zwischen den Tabellen\" width=\"424,6267\" height=\"385,9292\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Beziehungen zwischen den Tabellen<\/span><\/b><\/p>\n<h2>Einlesen der Ordner und Dateien<\/h2>\n<p>Die intuitive Vorgehensweise zum Einlesen der Ordner und Dateien des gew&uuml;nschten Ordners w&uuml;rde sich nach dem Aufbau des Dateisystems und unserer Tabellenstruktur richten.<\/p>\n<p>Wir w&uuml;rden also etwa die Klassen und Methoden der <b>FileSystemObject<\/b>-Klasse nutzen, um ausgehend vom Basisordner zun&auml;chst die darin enthaltenen Ordner einzulesen und in die Tabelle <b>tblOrdner <\/b>zu schreiben. Beim Durchlaufen dieser Ordner w&uuml;rden wir in einer rekursiven Prozedur die untergeordneten Ordner und die Dateien dieses Ordners einlesen und so weiter.<\/p>\n<p>Diese Vorgehensweise ist jedoch nicht schnell genug. Beim Einlesen umfangreicher Ordnerstrukturen wollen wir schlie&szlig;lich nicht ewig warten. Deshalb w&auml;hlen wir hier einen alternativen Ansatz, der allerdings etwas komplexer ist und wie in Listing 1 beginnt.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>OrdnerUndDateienEinlesen(ByVal strRoot<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>wrk<span style=\"color:blue;\"> As <\/span>DAO.Workspace\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rstFolders<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>rstFiles<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>colTodo<span style=\"color:blue;\"> As <\/span>Collection\r\n     <span style=\"color:blue;\">Dim <\/span>strPfad<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strEintrag<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strVollPfad<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngAttr<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngCounter<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strUID<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngParentID<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngCurrentFolderID<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>lngTimer<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>booIsRoot<span style=\"color:blue;\"> As Boolean<\/span>\r\n     \r\n     lngTimer = Timer\r\n     \r\n     <span style=\"color:blue;\">If <\/span>Right$(strRoot, 1) = \"\\\"<span style=\"color:blue;\"> Then<\/span>\r\n         strRoot = Left$(strRoot, <span style=\"color:blue;\">Len<\/span>(strRoot) - 1)\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> wrk = DBEngine(0)\r\n     <span style=\"color:blue;\">Set<\/span> db = wrk.Databases(0)\r\n     \r\n     <span style=\"color:blue;\">Call<\/span> TabellenZuruecksetzen(db)\r\n     \r\n     <span style=\"color:blue;\">Set<\/span> rstFolders = db.OpenRecordset(\"tblFolders\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Set<\/span> rstFiles = db.OpenRecordset(\"tblFiles\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Set<\/span> colTodo = <span style=\"color:blue;\">New<\/span> Collection\r\n     <span style=\"color:blue;\">Call<\/span> TodoAdd(colTodo, strRoot, 0)\r\n     bolIsRoot = <span style=\"color:blue;\">True<\/span>\r\n     DoCmd.Echo <span style=\"color:blue;\">False<\/span>\r\n     DoCmd.Hourglass <span style=\"color:blue;\">True<\/span>\r\n     wrk.BeginTrans\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> Fehler\r\n     ...<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Die Prozedur OrdnerstrukturEinlesen (Teil 1)<\/span><\/b><\/p>\n<p>Was macht die Prozedur <b>OrdnerUndDateienEinlesen <\/b>&uuml;berhaupt?<\/p>\n<ul>\n<li>Wir haben einen Startordner (zum Beispiel <b>C:\\Buecher<\/b>).<\/li>\n<li>Darin sind Unterordner und Dateien.<\/li>\n<li>In den Unterordnern sind wieder Unterordner und Dateien. Das Ganze als Baum.<\/li>\n<li>Die Prozedur l&auml;uft durch den ganzen Baum, schreibt alle Ordner in <b>tblFolders<\/b>, schreibt alle Dateien in <b>tblFiles<\/b>, merkt sich zu jeder Datei und jedem Ordner, wo sie liegen (<b>ParentID<\/b>), und speichert au&szlig;erdem eine UID (damit wir sie sp&auml;ter wiedererkennen) und Gr&ouml;&szlig;e und Datum (f&uuml;r Dateien).<\/li>\n<\/ul>\n<p>Danach k&ouml;nnen wir mit diesen Tabellen bequem arbeiten, zum Beispiel zum F&uuml;llen eines <b>TreeView<\/b>-Steuerelements.<\/p>\n<h2>Die Prozedur OrdnerUndDateienEinlesen Schritt f&uuml;r Schritt erkl&auml;rt<\/h2>\n<p>Die Prozedur bekommt mit dem Parameter <b>strRoot <\/b>einen Startpfad. Als Erstes deklarieren wir die Variablen:<\/p>\n<ul>\n<li><b>wrk <\/b>und <b>db<\/b>: Verweise auf die aktuelle Datenbank und das <b>Workspace<\/b>-Objekt<\/li>\n<li><b>rstFolders <\/b>und <b>rstFiles<\/b>: Recordsets f&uuml;r <b>tblFolders <\/b>und <b>tblFiles<\/b><\/li>\n<li><b>colTodo<\/b>: Eine Collection als To-do-Liste mit Ordnern, die noch abgearbeitet werden m&uuml;ssen<\/li>\n<li><b>strPfad<\/b>, <b>strEintrag <\/b>und <b>strVollPfad<\/b>: String-Variablen f&uuml;r aktuelle Pfade\/Namen<\/li>\n<li><b>lngAttr<\/b>: Dateiattribute (ist es ein Ordner oder eine Datei?)<\/li>\n<li><b>lngCounter<\/b>: Wieviele Dateien haben wir schon gefunden?<\/li>\n<li><b>strUID<\/b>: Datei-\/Ordner-ID, die wir mit der Funktion <b>GetFileID <\/b>holen<\/li>\n<li><b>lngParentID <\/b>und <b>lngCurrentFolderID<\/b>: Verweise auf &uuml;bergeordnete Ordner<\/li>\n<li><b>lngTimer<\/b>: Erfassung der Laufzeit<\/li>\n<li><b>booIsRoot<\/b>: Gibt an, ob wir noch im Root-Ordner sind<\/li>\n<\/ul>\n<p>Zu Beginn speichern wir den aktuellen Timer-Wert in <b>lngTimer<\/b>, um sp&auml;ter die Gesamtzeit f&uuml;r den Vorgang ausgeben zu k&ouml;nnen. Au&szlig;erdem schneiden wir vom Root-Ordner in <b>strRoot <\/b>noch ein eventuell am Ende befindliches Backslash-Zeichen ab, falls dieses noch vorhanden ist.<\/p>\n<h2>Workspace und Transaktion f&uuml;r schnelleres Schreiben<\/h2>\n<p>Danach initialisieren wir die <b>Workspace<\/b>-Variable <b>wrk<\/b> und die <b>Database<\/b>-Variable <b>db<\/b>. Das <b>Workspace<\/b>-Objekt ben&ouml;tigen wir, weil wir damit die vielen Anlegevorg&auml;nge in einer Transaktion b&uuml;ndeln k&ouml;nnen, was wesentlich schneller funktioniert, als wenn wir jeden Vorgang einzeln durchf&uuml;hren.<\/p>\n<h2>Tabellen zur&uuml;cksetzen und leeren<\/h2>\n<p>Danach rufen wir die Prozedur <b>TabellenZuruecksetzen <\/b>auf. Diese l&ouml;scht nicht nur einfach die Daten, sondern f&uuml;gt zuvor einen neuen Datensatz in die beiden Tabellen <b>tblFolders <\/b>und <b>tblFiles <\/b>ein, der im Prim&auml;rschl&uuml;sselfeld den Wert <b>0 <\/b>enth&auml;lt. Damit setzen wir den Autowert der beiden Tabellen zur&uuml;ck, sodass beim Neuanlegen von Datens&auml;tzen nachfolgend wieder mit dem Wert <b>1 <\/b>gestartet wird. Anschlie&szlig;end l&ouml;schen wir alle Datens&auml;tze aus diesen beiden Tabellen:<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TabellenZuruecksetzen(db<span style=\"color:blue;\"> As <\/span>DAO.Database)\r\n     db.Execute _\r\n         \"INSERT INTO tblFiles(FileID, Filename) \" _\r\n         & \"VALUES(0, '''')\", dbFailOnError\r\n     db.Execute _\r\n         \"INSERT INTO tblFolders(FolderID, Foldername) \" _\r\n         & \"VALUES(0, '''')\", dbFailOnError\r\n     \r\n     db.Execute \"DELETE FROM tblFiles\", dbFailOnError\r\n     db.Execute \"DELETE FROM tblFolders\", dbFailOnError\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Weitere Initialisierungen<\/h2>\n<p>Danach &ouml;ffnen wir zwei Recordsets: <b>rstFolders <\/b>f&uuml;r die Ordner und <b>rstFiles <\/b>f&uuml;r die Dateien. Au&szlig;erdem legen wir ein <b>Collection<\/b>-Objekt namens <b>colToDo <\/b>an, mit dem wir noch zu bearbeitende Ordner speichern.<\/p>\n<p>Hier legen wir als Erstes den Startordner aus dem Parameter <b>strRoot <\/b>mit dem Wert <b>0 <\/b>ab. Das geschieht in einer weiteren Hilfsprozedur namens <b>TodoAdd<\/b>.<\/p>\n<p>Dieser &uuml;bergeben wir das <b>Collection<\/b>-Objekt, den Pfad und die ID des &uuml;bergeordneten Ordners als Parameter.<\/p>\n<p>Wir f&uuml;gen der Collection dann einen Eintrag hinzu, der aus der ID des &uuml;bergeordneten Ordners, dem Pipe-Zeichen (<b>|<\/b>) und dem Pfad besteht. Im ersten Aufruf tragen wir also den Wert <b>0|[Pfad] <\/b>ein:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>TodoAdd(ByRef col<span style=\"color:blue;\"> As <\/span>Collection, _\r\n         ByVal strPfad<span style=\"color:blue;\"> As String<\/span>, ByVal lngParentID<span style=\"color:blue;\"> As Long<\/span>)\r\n     col.Add CStr(lngParentID) & \"|\" & strPfad\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Der Wert <b>0 <\/b>bedeutet in diesem Fall, dass es keinen &uuml;bergeordneten Ordner gibt.<\/p>\n<p>Da dieser erste Ordner eine Spezialbehandlung erfahren soll, stellen wir au&szlig;erdem die Variable <b>bolIsRoot <\/b>auf <b>True <\/b>ein.<\/p>\n<p>Schlie&szlig;lich deaktivieren wir die Bildschirmaktualisierung mit <b>DoCmd.Echo False <\/b>und aktivieren die Sanduhr mit <b>DoCmd.Hourglass True<\/b>.<\/p>\n<h2>Starten der Transaktion und der Do While-Schleife<\/h2>\n<p>Nun starten wir die Transaktion und integrieren die Fehlerbehandlung (siehe Listing 2).<\/p>\n<pre>     ...\r\n     <span style=\"color:blue;\">Do While<\/span> colTodo.Count &gt; 0\r\n         <span style=\"color:blue;\">Call<\/span> TodoPop(colTodo, strPfad, lngParentID)\r\n         <span style=\"color:blue;\">If <\/span>Right$(strPfad, 1) &lt;&gt; \"\\\"<span style=\"color:blue;\"> Then<\/span>\r\n             strPfad = strPfad & \"\\\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> bolIsRoot<span style=\"color:blue;\"> Then<\/span>\r\n             rstFolders.Add<span style=\"color:blue;\">New<\/span>\r\n             rstFolders!FolderName = GetFolderNameFromPath(strPfad)\r\n             <span style=\"color:blue;\">If <\/span>lngParentID &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n                 rstFolders!ParentID = lngParentID\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 rstFolders!ParentID = Null\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             rstFolders!UID = GetFileID(strPfad)\r\n             lngCurrentFolderID = rstFolders!FolderID\r\n             \r\n             rstFolders.Update\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             lngCurrentFolderID = 0\r\n             bolIsRoot = <span style=\"color:blue;\">False<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         strEintrag = Dir$(strPfad & \"*\", vbDirectory)\r\n         <span style=\"color:blue;\">Do While<\/span> strEintrag &lt;&gt; \"\"\r\n             <span style=\"color:blue;\">If <\/span>strEintrag &lt;&gt; \".\" And strEintrag &lt;&gt; \"..\"<span style=\"color:blue;\"> Then<\/span>\r\n                 strVollPfad = strPfad & strEintrag\r\n                 strUID = GetFileID(strVollPfad)\r\n                 <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strUID) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n                     lngAttr = GetAttr(strVollPfad)\r\n                     <span style=\"color:blue;\">If <\/span>(lngAttr And vbDirectory) = vbDirectory<span style=\"color:blue;\"> Then<\/span>\r\n                         <span style=\"color:blue;\">Call<\/span> TodoAdd(colTodo, strVollPfad, lngCurrentFolderID)\r\n                     <span style=\"color:blue;\">Else<\/span>\r\n                         rstFiles.Add<span style=\"color:blue;\">New<\/span>\r\n                         rstFiles!FileName = strEintrag\r\n                         rstFiles!ParentID = lngCurrentFolderID\r\n                         rstFiles!UID = strUID\r\n                         rstFiles!Filesize = File<span style=\"color:blue;\">Len<\/span>(strVollPfad)\r\n                         rstFiles!FileDateTime = FileDateTime(strVollPfad)\r\n                         rstFiles.Update\r\n                         lngCounter = lngCounter + 1\r\n                     <span style=\"color:blue;\">End If<\/span>\r\n                 <span style=\"color:blue;\">End If<\/span>\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             strEintrag = Dir$()\r\n         <span style=\"color:blue;\">Loop<\/span>\r\n     ...<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Die Prozedur OrdnerstrukturEinlesen (Teil 2)<\/span><\/b><\/p>\n<p>Anschlie&szlig;end starten wir eine <b>Do While<\/b>-Schleife, in der wir alle Elemente der Collection <b>colToDo <\/b>durchlaufen. Die Informationen aus der Collection holen wir uns mit der Hilfsfunktion <b>ToDoPop<\/b>:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>TodoPop(ByRef col<span style=\"color:blue;\"> As <\/span>Collection, _\r\n         ByRef strPfad<span style=\"color:blue;\"> As String<\/span>, ByRef lngParentID<span style=\"color:blue;\"> As Long<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>v<span style=\"color:blue;\"> As Variant<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>p<span style=\"color:blue;\"> As Long<\/span>\r\n     \r\n     v = col(1)\r\n     col.Remove 1\r\n     \r\n     p = <span style=\"color:blue;\">InStr<\/span>(1, v, \"|\")\r\n     lngParentID = CLng(Left$(v, p - 1))\r\n     strPfad = Mid$(v, p + 1)\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Sie schreibt den ersten Eintrag der Collection in die <b>Variant<\/b>-Variable <b>v <\/b>und entfernt dieses Element aus der Collection.<\/p>\n<p>Dann liest sie die Position des Pipe-Zeichens mit der <b>InStr<\/b>-Funktion aus und schreibt anschlie&szlig;end den Teil vor dem Pipe-Zeichen in den R&uuml;ckgabeparameter <b>lngParentID <\/b>und den Teil dahinter in den R&uuml;ckgabeparameter <b>strPfad<\/b>.<\/p>\n<p>Danach pr&uuml;fen wir, ob der Pfad einen abschlie&szlig;enden Backslash enth&auml;lt, und f&uuml;gen diesen gegebenenfalls an.<\/p>\n<h2>Ordner in tblFolders eintragen<\/h2>\n<p>Nun folgt in einer <b>If&#8230;Then<\/b>-Bedingung die Unterscheidung, ob wir gerade mit dem Root-Ordner arbeiten (<b>bolIsRoot <\/b>ist dann <b>True<\/b>) oder ob wir bereits in einer untergeordneten Ebene gelandet sind.<\/p>\n<p>Im Falle des Root-Ordners tragen wir lediglich den Wert <b>0 <\/b>in die Variable <b>lngCurrentFolderID <\/b>ein und setzen <b>bolIsRoot <\/b>auf <b>False<\/b>.<\/p>\n<p>Falls wir bereits einen untergeordneten Ordner bearbeiten, speichern wir diesen direkt in der Tabelle <b>tblFolders<\/b>. Dazu rufen wir die <b>AddNew<\/b>-Methode von <b>rstFolders <\/b>auf und tragen die Werte ein. F&uuml;r das Feld <b>FolderName <\/b>ermitteln wir den letzten Teil des Pfads mit der Funktion <b>GetFolderNameFromPath<\/b>, die wie folgt aussieht:<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>GetFolderNameFromPath( _\r\n         ByVal strPfad<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">If <\/span>Right$(strPfad, 1) = \"\\\"<span style=\"color:blue;\"> Then<\/span>\r\n         strPfad = Left$(strPfad, <span style=\"color:blue;\">Len<\/span>(strPfad) - 1)\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     GetFolderNameFromPath = _\r\n         Mid$(strPfad, <span style=\"color:blue;\">InStrRev<\/span>(strPfad, \"\\\") + 1)\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p>Die Funktion erh&auml;lt den Pfad aus <b>strPfad <\/b>als Parameter und entfernt zun&auml;chst ein eventuell vorhandenes abschlie&szlig;endes Backslash-Zeichen.<\/p>\n<p>Dann lesen wir den Teil des Pfades hinter dem letzten vorhandenen Backslash-Zeichen ein und geben diesen als Funktionsergebnis zur&uuml;ck.<\/p>\n<p>Au&szlig;erdem tragen wir die <b>FolderID <\/b>des &uuml;bergeordneten Ordners in das Feld <b>ParentID <\/b>und die eindeutige ID des Ordners aus dem NTFS-System in das Feld UID.<\/p>\n<p>Diese ermitteln wir mit der Funktion <b>GetFileID<\/b>, die wir weiter unten beschreiben. <\/p>\n<p>In der Variablen <b>lngCurrentFolderID <\/b>speichern wir schlie&szlig;lich den Prim&auml;rschl&uuml;sselwert des neuen Datensatzes. Diesen ben&ouml;tigen wir, um weitere untergeordnete Ordner- und Dateidatens&auml;tze mit dem angelegten Eintrag in <b>tblFolders <\/b>verkn&uuml;pfen zu k&ouml;nnen.<\/p>\n<h2>Dateien und Unterordner des aktuellen Ordners einlesen<\/h2>\n<p>Nun holen wir uns mit der <b>Dir<\/b>-Funktion den ersten Unterordner des Ordners aus <b>strPfad<\/b>. Damit <b>Dir <\/b>tats&auml;chlich nur Ordner liefert und keine Dateien, geben wir als zweiten Parameter den Wert <b>vbDirectory <\/b>an.<\/p>\n<p>Wenn die so bef&uuml;llte Variable <b>strEintrag <\/b>keine leere Zeichenkette enth&auml;lt, steigen wir in die folgende <b>Do While<\/b>-Schleife ein, die genau dies als Abbruchkriterium nutzt.<\/p>\n<p>Sollte der von <b>Dir <\/b>gelieferte Wert einen oder zwei Punkte enthalten, handelt es sich um Platzhalter f&uuml;r das aktuelle Verzeichnis oder f&uuml;r das Elternverzeichnis. Diese beiden ignorieren wir durch eine <b>If&#8230;Then<\/b>-Bedingung.<\/p>\n<p>Ist <b>strEintrag <\/b>aber ungleich &#8222;<b>.&#8220;<\/b> oder &#8222;<b>..&#8220;<\/b>, schreiben wir den aktuellen Pfad aus <b>strPfad <\/b>plus den gefundenen Ordner durch einen Backslash getrennt in die Variable <b>strVollPfad<\/b>. Au&szlig;erdem ermitteln wir mit <b>GetFileID <\/b>die eindeutige ID dieses Verzeichnisses und tragen diese in <b>strUID <\/b>ein. Wenn wir die ID ermitteln konnten, was zum Beispiel bei tempor&auml;ren Ordnern oder Dateien nicht gelingt, schreiben wir das Ergebnis der Funktion <b>GetAttr <\/b>in die Variable <b>lngAttr<\/b>.<\/p>\n<p>Wir pr&uuml;fen in einer weiteren <b>If&#8230;Then<\/b>-Bedingung, ob der in <b>lngAttr <\/b>gespeicherte Wert die Konstante <b>vbDirectory <\/b>enth&auml;lt. In diesem Fall rufen wir erneut die Prozedur <b>TodoAdd <\/b>auf und f&uuml;gen damit das Verzeichnis aus <b>strVollpfad <\/b>und die ID des aktuellen Ordners aus <b>lngCurrentFolderID <\/b>als neuen Eintrag zur Collection <b>colTodo<\/b> hinzu.<\/p>\n<p>Falls es sich nicht um ein Verzeichnis handelt, legen wir mit der <b>AddNew<\/b>-Methode einen neuen Datensatz in der Tabelle <b>tblFiles <\/b>an. Dabei f&uuml;llen wir die Felder <b>FileName <\/b>mit dem Wert aus <b>strEintrag<\/b>, <b>ParentID<\/b> mit dem Wert aus <b>lngCurrentFolderID <\/b>und <b>UID <\/b>mit der eindeutigen Datei-ID aus <b>strUID<\/b>.<\/p>\n<p>Au&szlig;erdem ermitteln wir mit den VBA-Funktionen <b>FileLen <\/b>und <b>FileDateTime <\/b>noch die Werte f&uuml;r die Felder <b>Filesize <\/b>und <b>FileDateTime<\/b>. Danach speichern wir den Datensatz und erh&ouml;hen den Wert der Variablen <b>lngCounter<\/b>, mit der wir die hinzugef&uuml;gten Dateien z&auml;hlen, um <b>1<\/b>.<\/p>\n<p>Schlie&szlig;lich beenden wir den Schleifendurchlauf, indem wir uns mit einem erneuten Aufruf der <b>Dir<\/b>-Funktion das n&auml;chste Element aus dem aktuellen Ordner holen &#8211; also das n&auml;chste Verzeichnis oder die n&auml;chste Datei, mit der wir dann in den n&auml;chsten Schleifendurchlauf starten.<\/p>\n<p>Zusammengefasst: Wir durchlaufen alle Elemente des aktuellen Ordners, f&uuml;gen f&uuml;r die enthaltenen Dateien jeweils einen neuen Datensatz zur Tabelle <b>tblFiles <\/b>hinzu und legen die gefundenen Ordner als neue Elemente in der Collection <b>colToDo <\/b>an, die wir anschlie&szlig;end abarbeiten.<\/p>\n<h2>Transaktion zwischendurch beenden und neu starten<\/h2>\n<p>Nach jeweils 5.000 Eintr&auml;gen beenden wir jeweils die aktuelle Transaktion mit der <b>Commit<\/b>-Methode, was die angesammelten Anf&uuml;gungen ausf&uuml;hrt, und starten mit <b>BeginTrans <\/b>eine neue Transaktion (siehe Listing 3).<\/p>\n<pre>         ...\r\n         <span style=\"color:blue;\">If <\/span>lngCounter &gt; 0 And lngCounter <span style=\"color:blue;\">Mod<\/span> 5000 = 0<span style=\"color:blue;\"> Then<\/span>\r\n             wrk.CommitTrans\r\n             wrk.BeginTrans\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     wrk.CommitTrans\r\nAufraeumen:\r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     db.Execute \"INSERT INTO tblLogs(AnzahlEintraege, Logdatum, Dauer) VALUES (\" & lngCounter & \", \" _\r\n         & ISODatum(Now) & \", \" & <span style=\"color:blue;\">Replace<\/span>(Timer - lngTimer, \",\", \".\") & \")\", dbFailOnError\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Fertig. \" & lngCounter & \" Dateien erfasst.\", vbInformation\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rstFiles Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n         rstFiles.Close\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rstFolders Is Nothing<span style=\"color:blue;\"> Then<\/span>\r\n         rstFolders.Close\r\n     <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> rstFiles = Nothing\r\n     <span style=\"color:blue;\">Set<\/span> rstFolders = Nothing\r\n     <span style=\"color:blue;\">Set<\/span> db = Nothing\r\n     <span style=\"color:blue;\">Set<\/span> colTodo = Nothing\r\n     DoCmd.Echo <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">Exit Sub<\/span>\r\nFehler:\r\n     <span style=\"color:blue;\">MsgBox<\/span> \"Fehler: \" & Err.Number & \" - \" & Err.Description, vbExclamation\r\n     wrk.Rollback\r\n     Resume Aufraeumen\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Die Prozedur OrdnerstrukturEinlesen (Teil 3)<\/span><\/b><\/p>\n<p>Wenn die Collection <b>colTodo<\/b> an dieser Stelle leer ist, ist das Einlesen erledigt, anderenfalls startet die &auml;u&szlig;ere <b>Do While<\/b>-Schleife erneut mit dem n&auml;chsten Verzeichnis, das wir uns wieder mit <b>TodoPop <\/b>aus der Collection holen.<\/p>\n<p>Sind keine Eintr&auml;ge mehr in <b>colToDo <\/b>enthalten, schlie&szlig;en wir die Transaktion mit <b>CommitTrans <\/b>ab.<\/p>\n<h2>Aufr&auml;umen, loggen und Meldung ausgeben<\/h2>\n<p>Schlie&szlig;lich landen wir unter der Sprungmarke <b>Aufraeumen<\/b> beim Abschluss der Prozedur. Hier tragen wir die Anzahl der gelesenen Dateien, den Zeitpunkt des Abschlusses und die verbrauchte Zeit in die Tabelle <b>tblLogs <\/b>ein, die im Entwurf wie in Bild 4 aussieht.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_01\/pic_1583_003.png\" alt=\"Tabelle zum Loggen der Einlesevorg&auml;nge\" width=\"549,6265\" height=\"413,3944\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Tabelle zum Loggen der Einlesevorg&auml;nge<\/span><\/b><\/p>\n<p>Dies haben wir zum Beispiel genutzt, um die Dauer verschiedener Varianten zu testen, wie zum Beispiel mit und ohne Transaktionen, mit <b>AddNew <\/b>oder <b>INSERT INTO <\/b>und so weiter.<\/p>\n<p>Danach geben wir eine Erfolgsmeldung aus, schlie&szlig;en alle ge&ouml;ffneten Objekte und leeren die Objektvariablen.<\/p>\n<p>Schlie&szlig;lich kommt noch die Sprungmarke <b>Fehler<\/b>, zu der wir im Falle eines Laufzeitfehlers gelangen. Hier geben wir eine Fehlermeldung aus und machen die letzte Transaktion mit <b>Rollback <\/b>r&uuml;ckg&auml;ngig.<\/p>\n<h2>Einlesen der Ordner und Dateien<\/h2>\n<p>Damit kommen wir zum ersten Test. Wir &uuml;bergeben der Prozedur <b>OrdnerUndDateienEinlesen <\/b>den Pfad zu dem Ordner, dessen Unterordner und Dateien wir einlesen wollen, zum Beispiel:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>strRoot<span style=\"color:blue;\"> As String<\/span>\r\nstrRoot = \"C:\\Users\\User\\Test\"\r\n<span style=\"color:blue;\">Call<\/span> OrdnerstrukturEinlesen(strRoot)<\/pre>\n<p>Danach liest die Prozedur die enthaltenen Unterordner und Dateien ein und pr&auml;sentiert dann eine Meldung mit der Anzahl der eingelesenen Dateien. Au&szlig;erdem tr&auml;gt sie einen neuen Datensatz in die Tabelle <b>tblLogs <\/b>ein (siehe Bild 5).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_01\/pic_1583_005.png\" alt=\"Geloggte Einlesevorg&auml;nge\" width=\"549,6265\" height=\"199,4785\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Geloggte Einlesevorg&auml;nge<\/span><\/b><\/p>\n<p>Wir haben uns einen kleinen Verzeichnisbaum mit einer Hilfsprozedur erstellt, die wie in Listing 4 aussieht.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>BeispieldateienUndOrdner()\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>, j<span style=\"color:blue;\"> As Integer<\/span>, f<span style=\"color:blue;\"> As Integer<\/span>, k<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strBasis<span style=\"color:blue;\"> As String<\/span>, strFile<span style=\"color:blue;\"> As String<\/span>\r\n     \r\n     strBasis = CurrentProject.Path & \"\\Test\\\"\r\n     \r\n     On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n     Kill strBasis & \"*\"\r\n     <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n     \r\n     For i = 1 To 3\r\n         MkDir strBasis & \"\\Dir\" & Format(i, \"00\")\r\n         For k = 1 To 3\r\n             f = FreeFile\r\n             strFile = strBasis & \"\\Dir\" & Format(i, \"00\") & \"\\Test\" & Format(i, \"00\") & Format(k, \"00\") & \".txt\"\r\n             Open strFile For Output<span style=\"color:blue;\"> As <\/span>#f\r\n             Print #f, \"Hallo Welt\"\r\n             Close #f\r\n         <span style=\"color:blue;\">Next<\/span> k\r\n         For j = 1 To 3\r\n             MkDir strBasis & \"\\Dir\" & Format(i, \"00\") & \"\\Dir\" & Format(i, \"00\") & Format(j, \"00\")\r\n             For k = 1 To 3\r\n                 f = FreeFile\r\n                 strFile = strBasis & \"\\Dir\" & Format(i, \"00\") & \"\\Dir\" & Format(i, \"00\") & Format(j, \"00\") & \"\\Test\" _\r\n                     & Format(i, \"00\") & Format(j, \"00\") & Format(k, \"00\") & \".txt\"\r\n                 Open strFile For Output<span style=\"color:blue;\"> As <\/span>#f\r\n                 Print #f, \"Hallo Welt\"\r\n                 Close #f\r\n             <span style=\"color:blue;\">Next<\/span> k\r\n         <span style=\"color:blue;\">Next<\/span> j\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Prozedur zum Erstellen einer Beispielhierarchie im aktuellen Datenbankordner<\/span><\/b><\/p>\n<p>Diese legt im aktuellen Datenbankverzeichnis einen Ordner namens Test an und dort zwei Ebenen von Unterordnern plus einigen Dateien. Das Ergebnis sehen wir in Bild 6.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_01\/pic_1583_006.png\" alt=\"Beispielordner mit Unterordnern und Dateien\" width=\"649,627\" height=\"412,049\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Beispielordner mit Unterordnern und Dateien<\/span><\/b><\/p>\n<p>Wenn wir den Ordner Test samt Pfad als Parameter der Prozedur <b>OrdnerUndDateienEinlesen<\/b> &uuml;bergeben, erhalten wir die entsprechenden Eintr&auml;ge in den beiden Tabellen. In der Tabelle <b>tblFolder<\/b> landen die Ordner wie in Bild 7.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_01\/pic_1583_007.png\" alt=\"Tabelle mit Ordnern\" width=\"424,6267\" height=\"344,5436\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Tabelle mit Ordnern<\/span><\/b><\/p>\n<p>Die Dateien werden schlie&szlig;lich wie in Bild 8 die Tabelle <b>tblFiles <\/b>geschrieben.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_01\/pic_1583_008.png\" alt=\"Tabelle mit Dateien\" width=\"649,627\" height=\"284,1505\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Tabelle mit Dateien<\/span><\/b><\/p>\n<h2>Einlesen der eindeutigen File-ID<\/h2>\n<p>Schlie&szlig;lich fehlt noch die Beschreibung der Funktion zum Einlesen der eindeutigen File-ID, die wir weiter oben erw&auml;hnt haben. In Listing 5 sehen wir zun&auml;chst die Deklarationen der verwendeten API-Funktionen, Konstanten und Typen.<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>Const GENERIC_READ<span style=\"color:blue;\"> As Long<\/span> = &H80000000\r\n<span style=\"color:blue;\">Private <\/span>Const FILE_SHARE_READ<span style=\"color:blue;\"> As Long<\/span> = &H1\r\n<span style=\"color:blue;\">Private <\/span>Const FILE_SHARE_WRITE<span style=\"color:blue;\"> As Long<\/span> = &H2\r\n<span style=\"color:blue;\">Private <\/span>Const FILE_SHARE_DELETE<span style=\"color:blue;\"> As Long<\/span> = &H4\r\n<span style=\"color:blue;\">Private <\/span>Const OPEN_EXISTING<span style=\"color:blue;\"> As Long<\/span> = 3\r\n<span style=\"color:blue;\">Private <\/span>Const FILE_FLAG_BACKUP_SEMANTICS<span style=\"color:blue;\"> As Long<\/span> = &H2000000\r\n<span style=\"color:blue;\">Private <\/span>Declare PtrSafe Function CreateFile Lib \"kernel32\" Alias \"CreateFileW\" (ByVal lpFileName<span style=\"color:blue;\"> As Long<\/span>Ptr, _\r\n     ByVal dwDesiredAccess<span style=\"color:blue;\"> As Long<\/span>, ByVal dwShareMode<span style=\"color:blue;\"> As Long<\/span>, ByVal lpSecurityAttributes<span style=\"color:blue;\"> As Long<\/span>Ptr, _\r\n     ByVal dwCreationDisposition<span style=\"color:blue;\"> As Long<\/span>, ByVal dwFlagsAndAttributes<span style=\"color:blue;\"> As Long<\/span>, ByVal hTemplateFile<span style=\"color:blue;\"> As Long<\/span>Ptr)<span style=\"color:blue;\"> As Long<\/span>Ptr\r\n<span style=\"color:blue;\">Private <\/span>Declare PtrSafe Function GetFileInformationByHandle Lib \"kernel32\" (ByVal hFile<span style=\"color:blue;\"> As Long<\/span>Ptr, _\r\n     lpFileInformation<span style=\"color:blue;\"> As <\/span>BY_HANDLE_FILE_INFORMATION)<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>Declare PtrSafe Function CloseHandle Lib \"kernel32\" (ByVal hObject<span style=\"color:blue;\"> As Long<\/span>Ptr)<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>Type FILETIME\r\n     dwLowDateTime <span style=\"color:blue;\"> As Long<\/span>\r\n     dwHighDateTime<span style=\"color:blue;\"> As Long<\/span>\r\nEnd Type\r\n<span style=\"color:blue;\">Private <\/span>Type BY_HANDLE_FILE_INFORMATION\r\n     dwFileAttributes<span style=\"color:blue;\"> As Long<\/span>\r\n     ftCreationTime  <span style=\"color:blue;\"> As <\/span>FILETIME\r\n     ftLastAccessTime<span style=\"color:blue;\"> As <\/span>FILETIME\r\n     ftLastWriteTime <span style=\"color:blue;\"> As <\/span>FILETIME\r\n     dwVolumeSerialNumber<span style=\"color:blue;\"> As Long<\/span>\r\n     nFileSizeHigh   <span style=\"color:blue;\"> As Long<\/span>\r\n     nFileSizeLow    <span style=\"color:blue;\"> As Long<\/span>\r\n     nNumberOfLinks  <span style=\"color:blue;\"> As Long<\/span>\r\n     nFileIndexHigh  <span style=\"color:blue;\"> As Long<\/span>\r\n     nFileIndexLow   <span style=\"color:blue;\"> As Long<\/span>\r\nEnd Type<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Deklarationen der API-Funktionen, Konstanten und Typen<\/span><\/b><\/p>\n<p>Die Funktion <b>CreateFileW <\/b>&ouml;ffnet eine Datei oder einen Ordner und gibt ein Handle zur&uuml;ck, mit dem wir sp&auml;ter weitere Informationen dazu abfragen k&ouml;nnen.<\/p>\n<p><b>GetFileInformationByHandle <\/b>liest zu diesem Handle eine Struktur mit Metadaten aus &#8211; unter anderem die <b>FileIndexHigh <\/b>und <b>FileIndexLow<\/b>, also zwei 32-Bit-Teile einer 64-Bit-Datei-ID.<\/p>\n<p><b>CloseHandle <\/b>schlie&szlig;t das Handle wieder, damit Windows die Ressource freigeben kann.<\/p>\n<p>Die Konstanten wie <b>GENERIC_READ<\/b>, <b>FILE_SHARE_READ <\/b>und so weiter geben an, wie ge&ouml;ffnet werden soll (nur lesend, ob andere parallel lesen\/schreiben d&uuml;rfen, ob es ein existierendes Objekt sein muss und so weiter).  <b>FILE_FLAG_BACKUP_SEMANTICS <\/b>ist der Trick, damit <b>CreateFile <\/b>nicht nur Dateien, sondern auch Ordner &ouml;ffnen darf.<\/p>\n<p>Die Strukturen <b>FILETIME <\/b>und <b>BY_HANDLE_FILE_INFORMATION <\/b>bilden das nach, was die Windows-API zur&uuml;ckliefert. In <b>BY_HANDLE_FILE_INFORMATION <\/b>stecken unter anderem:<\/p>\n<ul>\n<li>Zeitstempel (Erstellung, letzter Zugriff, letzte &Auml;nderung)<\/li>\n<li>die Gr&ouml;&szlig;e<\/li>\n<li>die Anzahl der Links<\/li>\n<li>die Datei-ID aus <b>nFileIndexHigh <\/b>und <b>nFileIndexLow <\/b><\/li>\n<\/ul>\n<p>In sehen wir die beiden benutzerdefinierten Funktionen <b>GetFileID <\/b>und <b>FileIDFRomHighLow<\/b>. Wir rufen von den oben beschriebenen Prozeduren aus die Funktion <b>GetFileID<\/b> auf und &uuml;bergeben dieser den Pfad zu dem zu untersuchenden Element des Dateisystems.<\/p>\n<p>Die Funktion liefert als Ergebnis die eindeutige File-ID zur&uuml;ck.<\/p>\n<p>Sie verwendet die folgenden Variablen:<\/p>\n<ul>\n<li><b>hFile<\/b>:  Windows-Handle<\/li>\n<li><b>info<\/b>: Struktur, in die <b>GetFileInformationByHandle <\/b>alle Informationen schreibt.<\/li>\n<li><b>ok<\/b>:  Nimmt den R&uuml;ckgabewert von <b>GetFileInformationByHandle <\/b>auf (<b>0<\/b>: Fehler, ungleich <b>0<\/b>: erfolgreich)<\/li>\n<\/ul>\n<p>Der Aufruf von <b>CreateFile <\/b>&ouml;ffnet das mit dem Parameter angegebene Ordner- oder Datei-Element (siehe Listing 6). <\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>GetFileID(strPath<span style=\"color:blue;\"> As String<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>hFile<span style=\"color:blue;\"> As Long<\/span>Ptr\r\n     <span style=\"color:blue;\">Dim <\/span>info<span style=\"color:blue;\"> As <\/span>BY_HANDLE_FILE_INFORMATION\r\n     <span style=\"color:blue;\">Dim <\/span>ok<span style=\"color:blue;\"> As Long<\/span>\r\n     hFile = CreateFile(StrPtr(strPath), GENERIC_READ, _\r\n                        FILE_SHARE_READ Or FILE_SHARE_WRITE Or FILE_SHARE_DELETE, _\r\n                        0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)\r\n     <span style=\"color:blue;\">If <\/span>hFile = -1<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Exit Function<\/span>\r\n     ok = GetFileInformationByHandle(hFile, info)\r\n     CloseHandle hFile\r\n     <span style=\"color:blue;\">If <\/span>ok = 0<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Exit Function<\/span>\r\n     GetFileID = FileIDFromHighLow(info.nFileIndexHigh, info.nFileIndexLow)\r\n<span style=\"color:blue;\">End Function<\/span>\r\n<span style=\"color:blue;\">Private Function <\/span>FileIDFromHighLow(Hi<span style=\"color:blue;\"> As Long<\/span>, Lo<span style=\"color:blue;\"> As Long<\/span>)<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>bigHi<span style=\"color:blue;\"> As Variant<\/span>, bigLo<span style=\"color:blue;\"> As Variant<\/span>\r\n     \r\n     <span style=\"color:blue;\">If <\/span>Hi &lt; 0<span style=\"color:blue;\"> Then<\/span> bigHi = CDec(Hi) + CDec(2 ^ 32) Else bigHi = CDec(Hi)\r\n     <span style=\"color:blue;\">If <\/span>Lo &lt; 0<span style=\"color:blue;\"> Then<\/span> bigLo = CDec(Lo) + CDec(2 ^ 32) Else bigLo = CDec(Lo)\r\n     FileIDFromHighLow = CStr(bigHi * CDec(2 ^ 32) + bigLo)\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Funktionen zum Ermitteln der FileID von Ordnern und Dateien<\/span><\/b><\/p>\n<p><b>StrPtr(strPath) <\/b>liefert dabei die Speicheradresse der Unicode-Zeichenkette, welche die API-Funktion <b>CreateFileW <\/b>erwartet. Die als Parameter &uuml;bergebenen Konstanten haben folgende Bedeutung:<\/p>\n<ul>\n<li><b>GENERIC_READ<\/b>: Wir brauchen nur Leserechte.<\/li>\n<li><b>FILE_SHARE_READ Or FILE_SHARE_WRITE Or FILE_SHARE_DELETE <\/b>erlaubt, dass andere Prozesse die Datei gleichzeitig lesen, schreiben oder l&ouml;schen d&uuml;rfen.<\/li>\n<li><b>0 <\/b>f&uuml;r den Parameter <b>lpSecurityAttributes<\/b>: Standard-Sicherheitseinstellungen.<\/li>\n<li><b>OPEN_EXISTING<\/b>: Die Datei muss bereits existieren und soll nicht neu angelegt werden  (dies k&ouml;nnte der Name der Funktion <b>CreateFile<\/b> suggerieren).<\/li>\n<li><b>FILE_FLAG_BACKUP_SEMANTICS<\/b>: sorgt daf&uuml;r, dass auch Ordner ge&ouml;ffnet werden k&ouml;nnen<\/li>\n<li><b>0 <\/b>f&uuml;r den Parameter <b>hTemplateFile<\/b>: Es wird keine Vorlage verwendet.<\/li>\n<\/ul>\n<p>Nach dem Aufruf von <b>CreateFile <\/b>und dem Zuweisen des Ergebnisses zu <b>hFile <\/b>pr&uuml;fen wir, ob <b>hFile <\/b>den Wert <b>-1 <\/b>hat &#8211; dann verlassen wir die Funktion ohne R&uuml;ckgabewert.<\/p>\n<p>Ist der Aufruf erfolgreich, k&ouml;nnen wir die Funktion <b>GetFileInformationByHandle <\/b>aufrufen, der wir das Handle auf das Datei- oder Ordner-Element &uuml;bergeben. Die Funktion f&uuml;llt den ebenfalls &uuml;bergebenen Parameter <b>info <\/b>auf Basis des Typs <b>BY_HANDLE_FILE_INFORMATION <\/b>&uuml;bergeben.<\/p>\n<p>Danach schlie&szlig;en wir mit der Funktion <b>CloseHandle <\/b>das Handle auf die Datei.<\/p>\n<p>Schlie&szlig;lich rufen wir die Funktion <b>FileIDFromHighLow <\/b>auf und &uuml;bergeben dieser die Eigenschaften <b>nFileIndexHigh <\/b>und <b>nFileIndexLow <\/b>der Struktur aus der Variablen <b>info<\/b>. Die Funktion nimmt die beiden 32-Bit-Teile der Datei-ID und erzeugt eine 64-Bit-Zahl daraus. Diese wird schlie&szlig;lich an die aufrufende Prozedur zur&uuml;ckgegeben.<\/p>\n<p>Wichtig: Diese File-ID ist innerhalb eines Volumes (also einer Partition\/eines Laufwerks) eindeutig f&uuml;r eine Datei oder einen Ordner, solange das Objekt existiert.<\/p>\n<p>Sie h&auml;ngt nicht vom Pfad ab. Wenn wir die Datei verschieben oder umbenennen, bleibt die File-ID in der Regel gleich.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Mit dieser L&ouml;sung k&ouml;nnen wir Ordner und Dateien in entsprechende Tabellen einlesen. &Uuml;ber die File-ID, die wir ebenfalls speichern, k&ouml;nnen wir in einer weiteren Tabelle benutzerdefinierte Metadaten zu den Dateien speichern und diese eindeutig den Dateien zuweisen.<\/p>\n<p>Die in Tabellen geschriebenen Ordner und Dateien k&ouml;nnen wir als Grundlage f&uuml;r die Anzeige der Struktur beispielsweise in einem <b>TreeView<\/b>-Steuerelement verwenden.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>OrdnerUndDateienInAccessEinlesen.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/25B00962-3A24-497F-A491-1BD028C3ECF3\/aiu_1583.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Es gibt verschiedene Gr&uuml;nde, warum man Ordner und Dateien aus dem Filesystem in eine entsprechende Datenstruktur einlesen sollte. Der Erste ist offensichtlich: Weil man die Laufwerke, Ordner und Dateien oder auch nur Teile davon innerhalb der Datenbank anzeigen m&ouml;chte, beispielsweise um zu sehen, welche Dateien zu einem bestimmten Projekt oder Kunden geh&ouml;ren. Der erste Schritt auf dem Weg zu einer solchen Anzeige ist das Einlesen der gew&uuml;nschten Struktur &#8211; unabh&auml;ngig davon, ob man den kompletten Inhalt einer Festplatte in seinen Tabellen abbilden m&ouml;chte oder auch nur den Inhalt eines Unterverzeichnisses. Zum Einlesen von Laufwerken, Ordnern und Dateien gibt es verschiedene M&ouml;glichkeiten auf beiden Seiten. Auf der Seite des Dateisystems k&ouml;nnen wir mit der Dir-Funktion oder alternativ mit dem FileSystemObject arbeiten, und beim Schreiben in die Tabellen der Datenbank bietet sich unter DAO das Schreiben mit AddNew\/Update oder mit der Execute-Methode an. In diesem Artikel stellen wir die schnellsten Versionen vor, damit das Einlesen umfangreicher Verzeichnis- und Dateistrukturen nicht unn&ouml;tig lange dauert. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[66012026,662026,44000026],"tags":[],"class_list":["post-55001583","post","type-post","status-publish","format-standard","hentry","category-66012026","category-662026","category-Interaktiv"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Ordner und Dateien in Access-Tabellen einlesen - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ordner und Dateien in Access-Tabellen einlesen\" \/>\n<meta property=\"og:description\" content=\"Es gibt verschiedene Gr&uuml;nde, warum man Ordner und Dateien aus dem Filesystem in eine entsprechende Datenstruktur einlesen sollte. Der Erste ist offensichtlich: Weil man die Laufwerke, Ordner und Dateien oder auch nur Teile davon innerhalb der Datenbank anzeigen m&ouml;chte, beispielsweise um zu sehen, welche Dateien zu einem bestimmten Projekt oder Kunden geh&ouml;ren. Der erste Schritt auf dem Weg zu einer solchen Anzeige ist das Einlesen der gew&uuml;nschten Struktur - unabh&auml;ngig davon, ob man den kompletten Inhalt einer Festplatte in seinen Tabellen abbilden m&ouml;chte oder auch nur den Inhalt eines Unterverzeichnisses. Zum Einlesen von Laufwerken, Ordnern und Dateien gibt es verschiedene M&ouml;glichkeiten auf beiden Seiten. Auf der Seite des Dateisystems k&ouml;nnen wir mit der Dir-Funktion oder alternativ mit dem FileSystemObject arbeiten, und beim Schreiben in die Tabellen der Datenbank bietet sich unter DAO das Schreiben mit AddNew\/Update oder mit der Execute-Methode an. In diesem Artikel stellen wir die schnellsten Versionen vor, damit das Einlesen umfangreicher Verzeichnis- und Dateistrukturen nicht unn&ouml;tig lange dauert.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-06T13:35:39+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg01.met.vgwort.de\/na\/694b7a4402934b5396dfd534d93dd302\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"22\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Ordner und Dateien in Access-Tabellen einlesen\",\"datePublished\":\"2026-02-06T13:35:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/\"},\"wordCount\":3494,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/694b7a4402934b5396dfd534d93dd302\",\"articleSection\":[\"1\\\/2026\",\"2026\",\"Interaktiv\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/\",\"name\":\"Ordner und Dateien in Access-Tabellen einlesen - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/694b7a4402934b5396dfd534d93dd302\",\"datePublished\":\"2026-02-06T13:35:39+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/694b7a4402934b5396dfd534d93dd302\",\"contentUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/694b7a4402934b5396dfd534d93dd302\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Ordner_und_Dateien_in_AccessTabellen_einlesen\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ordner und Dateien in Access-Tabellen einlesen\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Ordner und Dateien in Access-Tabellen einlesen - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/","og_locale":"de_DE","og_type":"article","og_title":"Ordner und Dateien in Access-Tabellen einlesen","og_description":"Es gibt verschiedene Gr&uuml;nde, warum man Ordner und Dateien aus dem Filesystem in eine entsprechende Datenstruktur einlesen sollte. Der Erste ist offensichtlich: Weil man die Laufwerke, Ordner und Dateien oder auch nur Teile davon innerhalb der Datenbank anzeigen m&ouml;chte, beispielsweise um zu sehen, welche Dateien zu einem bestimmten Projekt oder Kunden geh&ouml;ren. Der erste Schritt auf dem Weg zu einer solchen Anzeige ist das Einlesen der gew&uuml;nschten Struktur - unabh&auml;ngig davon, ob man den kompletten Inhalt einer Festplatte in seinen Tabellen abbilden m&ouml;chte oder auch nur den Inhalt eines Unterverzeichnisses. Zum Einlesen von Laufwerken, Ordnern und Dateien gibt es verschiedene M&ouml;glichkeiten auf beiden Seiten. Auf der Seite des Dateisystems k&ouml;nnen wir mit der Dir-Funktion oder alternativ mit dem FileSystemObject arbeiten, und beim Schreiben in die Tabellen der Datenbank bietet sich unter DAO das Schreiben mit AddNew\/Update oder mit der Execute-Methode an. In diesem Artikel stellen wir die schnellsten Versionen vor, damit das Einlesen umfangreicher Verzeichnis- und Dateistrukturen nicht unn&ouml;tig lange dauert.","og_url":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/","og_site_name":"Access im Unternehmen","article_published_time":"2026-02-06T13:35:39+00:00","og_image":[{"url":"http:\/\/vg01.met.vgwort.de\/na\/694b7a4402934b5396dfd534d93dd302","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"22\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Ordner und Dateien in Access-Tabellen einlesen","datePublished":"2026-02-06T13:35:39+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/"},"wordCount":3494,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/694b7a4402934b5396dfd534d93dd302","articleSection":["1\/2026","2026","Interaktiv"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/","url":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/","name":"Ordner und Dateien in Access-Tabellen einlesen - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/694b7a4402934b5396dfd534d93dd302","datePublished":"2026-02-06T13:35:39+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/#primaryimage","url":"http:\/\/vg01.met.vgwort.de\/na\/694b7a4402934b5396dfd534d93dd302","contentUrl":"http:\/\/vg01.met.vgwort.de\/na\/694b7a4402934b5396dfd534d93dd302"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Ordner_und_Dateien_in_AccessTabellen_einlesen\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Ordner und Dateien in Access-Tabellen einlesen"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001583","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001583"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001583\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001583"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001583"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001583"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}