Access 2007: Anlagen

15.11.2006
Die neue Access-Version bietet so viele Neuheiten wie lange keine Version zuvor – dementsprechend gibt es einiges zu berichten. In diesem und jenem Blog, in Webforen und in diversen Computerzeitschriften rumort es ob des Sinns oder Unsinns der Änderungen. Inside Access stellt die Neuheiten in loser Folge vor. In dieser Ausgabe dreht sich alles die Anlagen in Tabellen, Formularen, Berichten und VBA.

Anlagen gehören zu den neuen Datentypen von Access 2007. Sie sollen Abhilfe schaffen bei Problemen, wie sie etwa beim Speichern von Bildern in Access-Datenbanken entstanden sind. Entweder man speicherte diese dort direkt in einem OLE-Feld und nahm dabei in Kauf, dass Access das Bild in ein spezielles, speicherfressendes Format umwandelte, oder man ließ die Bilddateien auf der Festplatte und verwies lediglich über die Angabe des Speicherortes darauf. Mit ein wenig VBA-Code konnte man so die Bilder direkt in einem passenden Bildsteuerelement in Formularen und Berichten anzeigen. Natürlich gab und gibt es auch alternative Verfahren, die Bilder als binären Datenstrom in einem OLE-Feld zu speichern und die Bilder ohne Umweg über die Festplatte in Bildsteuerelementen anzeigen zu lassen, aber diese Lösungen sind mit nur geringen VBA-Kenntnissen kaum zu bewältigen.

Nun kommen also die Anlagen – ein Datentyp, mit dem man in Access Dateien im nativen Format direkt in einem Tabellenfeld speichern kann. Und nicht nur das: Man kann nicht nur eine, sondern direkt mehrere Dateien je Datensatz speichern. Dabei setzt Access im Hintergrund weitere Tabellen ein, die mit der Ursprungstabelle entsprechend verknüpft sind.

Datentyp Anlage

Bild 1 zeigt, wie man den Datentyp Anlage für ein Feld einer Tabelle einstellt. Da gerade Bilder oft Probleme bereiten, werfen Sie nun einen Blick auf das Handling von Bildern – und zwar am Beispiel von Mitarbeiterfotos der Nordwind- Datenbank. Diese kann man etwa im Beispielformular Employees Details bearbeiten. Zum Hinzufügen klickt man entweder doppelt auf das Steuerelement, oder man wählt das Büroklammer-Symbol aus dem beim Anklicken erscheinenden Menü aus (Bild 2).

Bild 1: Auswahl des Datentyps Anlage in einer Tabelle der neuen Nordwind-Datenbank.
Bild 2: Beim Markieren eines Steuerelements vom Typ Anlage erscheint ein kleines Menü zum Öffnen eines weiteren Dialogs.
Bild 3: Ein gefülltes Anlage-Steuerelement und der Dialog zum Aufrufen weiterer Funktionen.
Bild 4: Die Werkzeugleiste mit dem neuen Anlage-Steuerelement.

Das Einfügen und Anzeigen etwa von Bildern ist mit dem Anlage-Datentyp und dem passenden Steuerelement in der Tat kinderleicht, wie Bild 3 zeigt. Ein an ein Tabellenfeld gebundenes Anlage-Steuerelement zieht man ganz einfach aus der Feldliste in den Formularentwurf, weitere Arbeiten sind nicht nötig. Der Benutzer muss das Steuerelement einfach nur noch einsetzen. Wenn ein Feld des Typs Anlage mehr als ein Element enthält, zeigt das Steuerelement jeweils das zuerst angelegte Element an; die übrigen kann der Benutzer mit den beim Anklicken des Steuerelements erscheinenden Steuerelementen anwählen. Ein nachträgliches Sortieren scheint aktuell jedoch nicht zu funktionieren. Zum Anlegen eines ungebundenen Anlage-Steuerelements zieht man das Büroklammer-Symbol aus der Werkzeugleiste in das Formular (Bild 4).

Anlagen in Berichten

Auch in Berichten funktioniert das Anlage-Steuerelement als Bildcontainer einwandfrei. Um dies zu testen, öffnen Sie einfach den Bericht Employee Address Book in der Entwurfsansicht. Aktivieren Sie die Feldliste, indem Sie im Bereich Entwurf unter Tools auf die Schaltfläche Vorhandene Felder hinzufügen klicken. Dann ziehen Sie den Eintrag Attachments in den Entwurf des Berichts (Bild 5) und wechseln in die Vorschauansicht.

Bild 5: Hinzufügen eines Anlage-Steuerelements zu einem Bericht.

Nun müssen Sie nur noch die Eigenschaft Bildgrößenmodus auf Zoomen und Rahmen auf Transparent einstellen.

Anlagen per VBA

Man mag fast meinen, dass VBA in Zusammenhang mit dem neuen Anlage-Datentyp und dem passenden Steuerelement der Vergangenheit angehört – ohne einzige Codezeile stellt Access Dialoge zum Bearbeiten, Öffnen, Hinzufügen und mehr zur Verfügung.

Wer allerdings schon ein wenig mit Access arbeitet, weiß, dass man vielleicht auch mal ein paar Hundert oder Tausend Elemente „handeln“ möchte – und um mal eben die 1 GByte-Speicherkarte der Digitalkamera in die Datenbank zu entladen, wäre ein wenig Automatisierung nun doch ganz hilfreich. Und dann taucht doch die Frage auf, wie man denn nun ein Feld handhabt, das einen oder mehrere Werte enthalten kann. Mit Access 2007 führt Microsoft eine neue DAO-Bibliothek ein: die Microsoft Office 2007 Access Database Engine Object Library. Sie ist standardmäßig als Verweis eingestellt, die vorherigen DAO- und ADO-Bibliotheken nicht mehr (Bild 6).

Bild 6: Die neue DAO-Bibliothek im Verweise-Fenster.

Genau genommen handelt es sich nur um eine Erweiterung der bisherigen DAO-Objektbibliothek. Neu ist beispielsweise das Objekt Recordset2, das Sie gleich für den Zugriff auf die im Anlage-Feld gespeicherten Dateien einsetzen werden.

Oberflächlich betrachtet speichert Access die Anhänge in einem einzigen Feld, das aber intern mit einer versteckten Tabelle verknüpft ist. Diese enthält je Anlage einen Datensatz. Wie greift man aber nun per VBA auf diese verknüpfte Tabelle zu? Ganz einfach: Man erstellt eine neue Datensatzgruppe auf Basis der Value-Eigenschaft des Anlage-Feldes.

Listing 1 zeigt, wie es geht: Es öffnet zunächst eine Datensatzgruppe auf Basis der Tabelle Employees und dann eine zweite, die auf dem Feld mit dem Datentyp Anlage basiert.

Public Sub AnlagenfelderAuflisten()
Dim db As DAO.Database
Dim rst As DAO.Recordset2
Dim rstAttachments As DAO.Recordset2
Dim fld As Field2
Set db = CurrentDb
Set rst = db.OpenRecordset("Employees", dbOpenDynaset)
Set rstAttachments = rst.Fields("Attachments").Value
For Each fld In rstAttachments.Fields
Debug.Print fld.Name
Next fld
rstAttachments.Close
rst.Close
Set rstAttachments = Nothing
Set rst = Nothing
Set db = Nothing
End Sub

Auflisten der Datensatzgruppen-Felder

Wie bei einer herkömmlichen Datensatzgruppe lassen sich die Felder der Datensatzgruppe auflisten. Auf diese Weise erhalten Sie einen Einblick in die Struktur der eigentlich nicht sichtbaren Tabelle zum Speichern der Anlagen. Diese enthält die folgenden Felder:

Nun sollen Sie auch noch auf die Inhalte der versteckten Tabelle zugreifen. Dies ermöglicht die Prozedur aus Listing 2. Die Routine durchläuft in der äußeren Schleife alle Mitarbeiter und gibt deren Namen aus, in der inneren Schleife zeigt es alle Anlagen samt detaillierten Informationen an.

Public Sub AnlagenAuflisten()
Dim db As DAO.Database
Dim rst As DAO.Recordset2
Dim rstAttachments As DAO.Recordset2
Dim fld As Field2
Set db = CurrentDb
Set rst = db.OpenRecordset("Employees", dbOpenDynaset)
Do While Not rst.EOF
Debug.Print rst![First Name] & " " & rst![Last Name]
Set rstAttachments = rst.Fields("Attachments").Value
Do While Not rstAttachments.EOF
Debug.Print rstAttachments!FileName, rstAttachments!FileType, rstAttachments!
FileFlags, rstAttachments!FileURL
rstAttachments.MoveNext
Loop
rstAttachments.Close
rst.MoveNext
Loop
rst.Close
Set rstAttachments = Nothing
Set rst = Nothing
Set db = Nothing
End Sub

Bild 7: Ausgabe der Routine aus Listing 2.

Bild 7 zeigt die Ausgabe dieser Routine für die Beispieldatenbank im Direktfenster.

Anlagen per VBA hinzufügen

Das Hinzufügen per VBA erfolgt mit der Routine aus Listing 3. Die Routine erzeugt zunächst eine Datensatzgruppe mit einem einzigen Datensatz, der den Mitarbeiter im Parameter lngMitarbeiterID enthält. Um die Anlagen dieses Mitarbeiters zu bearbeiten, müssen Sie zunächst das Anlagenfeld in der Mitarbeitertabelle mit der Edit- Methode zur Bearbeitung vorbereiten, bevor Sie selbiges mit dem ersten Feld der Tabelle mit den Anhängen tun.

Public Sub AnlageHinzufuegen(lngMitarbeiterID As Long, strBild As String)
Dim db As DAO.Database
Dim rstMitarbeiter As DAO.Recordset2
Dim rstAnlagen As DAO.Recordset2
Set db = CurrentDb
Set rstMitarbeiter = db.OpenRecordset("SELECT * FROM Employees WHERE ID = " &
lngMitarbeiterID, dbOpenDynaset)
rstMitarbeiter.Edit
Set rstAnlagen = rstMitarbeiter.Fields("Attachments").Value
rstAnlagen.AddNew
rstAnlagen.Fields("FileData").LoadFromFile strBild
rstAnlagen.Update
rstAnlagen.Close
Set rstAnlagen = Nothing
rstMitarbeiter.Update
rstMitarbeiter.Close
Set rstMitarbeiter = Nothing
End Sub

Das Hinzufügen eines Anhangs erfolgt über die Methode LoadFromFile des Feldes FileData der Tabelle mit den Anhängen. LoadFromFile erwartet den Namen der hinzuzufügenden Datei als Parameter.

Keine Anlagen-Duplikate

Offensichtlich prüft Access beim Hinzufügen einer Datei als Anlage, ob diese bereits vorhanden ist. Wenn Sie die Routine aus Listing 3 zweimal intereinander mit den gleichen Parametern ausführen, erhalten Sie die (zweifellos neue) Fehlermeldung aus Bild 8.

Bild 8: Fehlermeldung beim Hinzufügen doppelter Dateien als Anlage des gleichen Anlage-Feldes.

Ersetzen und Löschen von Anlagen per VBA

Das Ersetzen einer Anlage erfolgt mit einer Routine ähnlich der aus Listing 3, allerdings verwendet man statt der AddNew-Methode die Edit-Methode.

Das Löschen ist noch einfacher: Hier reicht die Delete-Methode – ebenfalls im gleichen Kontext wie in Listing 3.

Viele Anlagen speichern

Wenn Sie einmal eine ganze Tabelle etwa mit den in einem Verzeichnis gespeicherten Bildern füllen möchten, können Sie das ebenfalls per VBA erledigen. Die passende Routine finden Sie in Listing 4. Sie erwartet die Angabe des Verzeichnisses mit den einzulesenden Bildern und durchforstet dieses dann nach Dateien mit der Endung .bmp.

Public Sub BildtabelleFuellen(strVerzeichnis As String)
Dim db As DAO.Database
Dim rstBilder As DAO.Recordset2
Dim rstAnlagen As DAO.Recordset2
Dim strBild As String
Set db = CurrentDb
Set rstBilder = db.OpenRecordset("tblBilder", dbOpenDynaset)
strBild = Dir(strVerzeichnis & "\*.*")
Do While Not strBild = ""
If Right(strBild, 3) = "bmp" Then
rstBilder.AddNew
rstBilder!Dateiname = strBild
Set rstAnlagen = rstBilder.Fields("Bild").Value
rstAnlagen.AddNew
rstAnlagen.Fields("FileData").LoadFromFile strVerzeichnis & "\" & str-
Bild
rstAnlagen.Update
rstAnlagen.Close
Set rstAnlagen = Nothing
rstBilder.Update
End If
strBild = Dir
Loop
rstBilder.Close
Set rstBilder = Nothing
End Sub

Für jede passende Datei legt die Routine dann zunächst einen Datensatz in der Tabelle tblBilder und dann einen Datensatz in der dazugehörenden Anlagen-Tabelle an.