Home > Artikel > Ausgabe 9/2013 > Anlage-Felder und VBA

Anlage-Felder und VBA

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Anlage-Felder bieten bereits ohne den Einsatz von VBA echten Nutzen. Wenn es jedoch darum geht, größere Operationen durchzuführen, um etwa eine Reihe von Bildern aus verschiedenen Verzeichnissen in ein oder mehrere Anlage-Felder zu kopieren, werden Sie dies kaum von Hand erledigen wollen. Stattdessen erstellen Sie eine VBA-Abfrage, die das Einfügen, Löschen oder Entfernen der Dateien in und aus dem Anlage-Feld erledigen soll.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1309_Anlagefelder.accdb.

Hinweise

Anlage-Felder wurden mit Access 2007 eingeführt. Voraussetzung ist außerdem ein Verweis auf die Bibliothek Microsoft Office x.0 Access Database Engine Object Library, der normalerweise bei Datenbanken des Typs .accdb bereits voreingestellt sein sollte.

Sollte die Datenbank aus irgendwelchen Gründen den Verweis auf die Bibliothek Microsoft DAO 3.6 Object Library enthalten, entfernen Sie diesen Sie über den Verweise-Dialog (VBA-Editor, Menü Extras|Verweise) und fügen den Verweis auf die oben genannte Bibliothek hinzu (siehe Bild 1).

Verweis auf die neue DAO-Bibliothek

Bild 1: Verweis auf die neue DAO-Bibliothek

Struktur von Anlage-Feldern

Bevor wir uns mit VBA an das Lesen und Bearbeiten eines Anlage-Feldes heranwagen, schauen wir uns die zugrunde liegende Struktur an. Am besten gelingt dies, wenn Sie eine neue Abfrage erstellen und eine Tabelle als Datenherkunft hinzufügen, die ein Anlage-Feld enthält. Dies sieht etwa wie in Bild 2 aus.

Das Anlage-Feld im Abfrageentwurf

Bild 2: Das Anlage-Feld im Abfrageentwurf

Wechseln Sie zur Datenblattansicht dieser Abfrage, erkennen Sie, dass jeder Datensatz für jede enthaltene Anlage je einmal erscheint (siehe Bild 3). Der Datensatz mit dem Wert 3 im Feld DateiID enthält beispielsweise fünf Dateien im Anlagefeld. Dementsprechend erscheint der Datensatz fünf Mal, jeweils mit einer anderen Anlage.

Abfrage, die jeden Datensatz entsprechend der Anzahl der enthaltenen Anlagen anzeigt.

Bild 3: Abfrage, die jeden Datensatz entsprechend der Anzahl der enthaltenen Anlagen anzeigt.

Dies weist darauf hin, dass die in Anlage-Feldern gespeicherten Daten möglicherweise in einer weiteren, für Benutzeraugen nicht sichtbaren, Tabelle gespeichert werden. In der Tat findet sich in einer Datenbank, nachdem Sie eine Tabelle mit einem Anlage-Feld hinzugefügt haben, eine zusätzliche Tabelle mit einem kryptischen Namen wie f_AE1ADE703D174BDAADDFFEBC068B79C8_Test (diese lässt sich allerdings nicht öffnen).

Und wenn die Daten des Anlage-Feldes schon in einer verknüpften Tabelle landen, finden wir sicher auch unter DAO einen alternativen Weg für den Zugriff auf diese Daten.

Nur lesen

Wenn Sie die Daten nur lesen möchten, aber nicht bearbeiten, können Sie direkt mit einem Recordset auf Basis der oben beschriebenen Abfrage arbeiten. Für die VBA-Prozeduren legen Sie im VBA-Editor mit Einfügen|Modul ein neues Modul namens mdlAnlagen an.

Fügen Sie dann die Prozedur mit dem Code aus Listing 1 hinzu. Die Prozedur deklariert und erstellt zunächst die benötigten Objekte, also ein Database-Objekt namens db und ein Recordset-Objekt namens rst und durchläuft dann alle Datensätze der Abfrage qryAnlagen in einer Do While-Schleife.

Public Sub LesenderZugriff()

     Dim db As DAO.Database

     Dim rst As DAO.Recordset

     Set db = CurrentDb

     Set rst = db.OpenRecordset("qryAnlagen", dbOpenDynaset)

     Do While Not rst.EOF

         Debug.Print rst!DateiID, rst("tblDateien.Datei.FileName"), rst("tblDateien.Datei.FileType"), _

             Left(rst("tblDateien.Datei.FileData"), 100)

         rst.MoveNext

     Loop

End Sub

Listing 1: Einfacher lesender Zugriff über eine Abfrage mit allen Feldern der Tabelle mit dem Anlage-Feld

Dabei gibt eine Debug.Print-Anweisung die Inhalte aller Felder im Direktbereich aus. Da der Inhalt des Anlagefeldes selbst, also die Datei, als Zeichenfolge ausgegeben wird, haben wir die Anzahl der Zeichen auf die ersten 100 begrenzt (Left(...)). Das Ergebnis finden Sie in Bild 4.

Inhalt eines Anlagefeldes

Bild 4: Inhalt eines Anlagefeldes

Die Namen der Felder können Sie dabei einfach der Datenblattansicht der Abfrage qryAnlagen entnehmen – oder Sie fragen diese etwa mit folgenden Ausdrücken im Direktfenster ab:

  CurrentDb.QueryDefs("qryAnlagen").Fields(1).Name

tblDateien.Datei.FileData

Nun stellt sich allerdings die Frage, ob wir auch auf die Datei zugreifen und diese etwa speichern können. Aber mit welcher Methode? Zunächst einmal nutzen wir eines der aktualisierten Objekte der neuen DAO-Bibliothek, und zwar Field2.

Deklarieren Sie in der Prozedur von oben eine entsprechende Variable dieses Typs namens fld. Dann weisen Sie dieser Variablen innerhalb der Schleife den Inhalt des Feldes tblDateien.Datei.Filedata zu, also des für das Speichern der Datei zuständigen Feldes innerhalb der verborgenen, verknüpften Tabelle.

Das Objekt des Typs Field2 liefert gegenüber der älteren Variante Field zum Beispiel die neue Methode SaveToFile, die wir in diesem Fall einsetzen um den Inhalt des Feldes in einer als Parameter angegebenen Datei zu speichern. Den angepassten Code der Prozedur finden Sie in gekürzter Form in Listing 2.

Public Sub LesenderZugriff()

     Dim fld As DAO.Field2

     ...

     Do While Not rst.EOF

         Set fld = rst.Fields("tblDateien.Datei.Filedata")

         fld.SaveToFile CurrentProject.Path & "\test_" & rst("tblDateien.Datei.Filename")

         rst.MoveNext

     Loop

End Sub

Listing 2: Diese Prozedur durchläuft alle Anlagen und speichert diese auf der Festplatte.

Anlagen in eigenem Recordset

Nun haben wir ja bereits ermittelt, dass die Anlagen in einer eigenen Tabelle gespeichert werden. Können wir auf die Elemente dieser Tabelle auch mit einem eigenen Recordset zugreifen? Ja, das ist möglich.

Dazu deklarieren Sie zunächst eine weitere Recordset-Variable, die aber dem Typ Recordset2 entsprechen muss. Dieser weisen Sie dann wiederum den Value-Wert des Anlage-Feldes des ersten Recordsets zu. Wir wollen und den Aufbau des Recordsets einmal ansehen und lesen dazu zunächst alle Feldnamen und Felddatentypen dieses Recordsets aus, nach dem wir es referenziert haben.

Die passende Prozedur finden Sie in Listing 3. Die Prozedur referenziert die aktuelle Datenbank und erstellt eine Datensatzgruppe auf Basis der Tabelle tblDateien.

Public Sub FelderDerAnlagenTabelle()

     Dim db As DAO.Database

     Dim rst As DAO.Recordset

     Dim fld As DAO.Field2

     Dim rstAnlagen As DAO.Recordset2

     Set db = CurrentDb

     Set rst = db.OpenRecordset("tblDateien", dbOpenDynaset)

     If Not rst.EOF Then

         Set rstAnlagen = rst.Fields("Datei").Value

         For Each fld In rstAnlagen.Fields

             Debug.Print fld.Name, fld.Type

         Next fld

     End If

End Sub

Listing 3: Auslesen aller Felder eines Recordsets auf Basis eines Anlage-Feldes

Mit der Variablen rstAnlagen referenziert sie dann die Value-Eigenschaft des Anlage-Feldes dieser Tabelle, also des Feldes Datei, und erzeugt so ein Recordset auf Basis der verknüpften Tabelle mit den Daten des Anlage-Feldes.

Da es sich hierbei tatsächlich um eine Tabelle handelt, können wir nun in einer For Each-Schleife alle Felder des Recordsets durchlaufen und dabei alle Feldnamen plus die Kennzahlen für die Felddatentypen im Direktbereich ausgeben.

Nachfolgend finden Sie das Ergebnis, ergänzt um die Datentypen im Klartext:

  • FileData: 11 (Byte-Array)
  • FileFlags: 4 (Long)
  • FileName: 10 (Text)
  • FileTimeStamp: 8 (Date/Time)
  • FileType: 10 (Text)
  • FileURL: 12 (Memo)

Anlagen auslesen

Nun wollen wir die im Anlage-Feld der Tabelle befindlichen Dateien direkt über das untergeordnete Recordset2-Objekt auslesen.

Diesmal benötigen wir keine Field2-Variable, sondern nur eine Recordset- und eine Recordset2-Variable.

In einer äußeren Do While-Schleife durchläuft die Prozedur die Datensätze der Tabelle tblDateien, in einer inneren die Datensätze der verknüpften, verborgenen Tabelle mit den Daten des Anlagefeldes, die zuvor über die Value-Eigenschaft des Anlage-Feldes des Recordsets der äußeren Schleife der Variablen rstAnlagen zugewiesen wurde. In der inneren Do While-Schleife gibt die Prozedur die in den einzelnen Feldern des Anlage-Feldes enthaltenen Informationen im Direktfenster aus (siehe Listing 4).

Public Sub AnlagenAuslesen()

     Dim db As DAO.Database

     Dim rst As DAO.Recordset

     Dim rstAnlagen As DAO.Recordset2

     Set db = CurrentDb

     Set rst = db.OpenRecordset("tblDateien", dbOpenDynaset)

     Do While Not rst.EOF

         Set rstAnlagen = rst.Fields("Datei").Value

         With rstAnlagen

         Do While Not .EOF

             Debug.Print !FileFlags, !FileName, !FileTimeStamp, !FileType, !FileURL

             .MoveNext

         Loop

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!