Zum Kopieren von Datensätzen aus einer Tabelle in die nächste gibt es verschiedene Varianten. Zunächst einmal gibt es die grobe Aufteilung von Methoden, die rein mit den Befehlen der DAO-Bibliothek auskommen – also solche, die ein Recordset referenzieren oder anlegen und dann die einzelnen Felder füllen. Dann stehen noch die Aktionsabfragen von SQL zur Verfügung, die wiederum über eine Methode der DAO-Bibliothek aufgerufen werden, aber ganz andere Möglichkeiten bieten als AddNew, Edit und Update. Und dann kommen mit Access 2007 noch die Anlagefelder hinzu, die eine eigene hintergelagerte Tabelle zum Speichern ihrer Daten verwenden. Der vorliegende Artikel stellt die verschiedenen Möglichkeiten zum Kopieren von Datensätzen mit Anlagefeldern vor.
Grundsätzlich gilt beim Kopieren von Datensätzen wie bei allen anderen Operationen, die das ändern von Daten zum Ziel haben: Das direkt Absetzen von SQL-Anweisungen wie INSERT INTO, UPDATE, SELECT INTO oder DELETE sind den DAO-Methoden AddNew, Edit, Update und Delete vorzuziehen.
Dies gilt insbesondere, wenn es sich um mehrere änderungen gleichzeitig handelt – die SQL-Anweisungen liefern dort schlicht eine viel bessere Performance. Allerdings bergen hier die mit Access 2007 eingeführten neuen Datentypen wie das mehrwertige Feld oder das Anlagefeld spezielle Anforderungen in sich.
Interessant wird dies, wenn Anlagefelder hinzukommen: Diese lassen sich nämlich nicht so einfach samt Inhalt kopieren. Aber sehen Sie selbst …
Beispieltabellen
Als Beispielmaterial für diesen Beitrag haben wir zwei Tabellen erstellt – eine namens tblBeispielanlagen und eine namens tblBeispielanlagenZiel. Beide sind genau gleich aufgebaut. Den Entwurf der Tabelle tblBeispielanlagen finden Sie in Bild 1.
Bild 1: Beispieltabelle mit Anlagefeld
Der erste Datensatz dieser Tabelle sieht wie in Bild 2 aus. Er enthält lediglich eine Anlage namens pic001.png.
Bild 2: Anlagefeld mit einer gespeicherten Datei
Wir fügen noch einen zweiten Datensatz mit zwei Anlagen namens pic002.png und pic003.png hinzu sowie einen Datensatz, dessen Anlagefeld keine Anlage enthält. Die Tabelle sieht dann in der Datenblattansicht wie in Bild 3 aus.
Bild 3: Tabelle mit allen Beispieldatensätzen
Diese drei Datensätze wollen wir nun auf verschiedene Arten in die Tabelle tblBeispielanlagenZiel kopieren.
Anlagefeld per DAO kopieren
Starten wir mit einem etwas naiven Versuch, bei dem wir die Prozedur aus Listing 1 ausprobieren. Hier definieren wir zwei Recordset-Objekte, die wir jeweils mit einem Verweis auf alle Datensätze der Tabellen tblBeispielanlagen und tblBeispielanlagenZiel versehen. In einer Do While-Schleife über alle Datensätze der Tabelle tblBeispielanlegen versuchen wir, jeweils einen neuen Datensatz in der Tabelle tblBeispielanlagenZiel zu erstellen und die beiden Felder Beispieltext und Beispielanlage der Quelltabelle zu füllen.
Public Sub AnlagePerDAO() Dim db As DAO.Database Dim rst As DAO.Recordset Dim rstZiel As DAO.Recordset Set db = CurrentDb Set rst = db.OpenRecordset("SELECT * FROM tblBeispielanlagen", dbOpenDynaset) Set rstZiel = db.OpenRecordset("SELECT * FROM tblBeispielanlagenZiel", dbOpenDynaset) Do While Not rst.EOF With rstZiel .AddNew !Beispieltext = rst!Beispieltext !Beispielanlage = rst!Beispielanlage .Update End With rst.MoveNext Loop Set db = Nothing End Sub
Listing 1: Naiver Versuch, ein Recordset samt Anlagefeld zu kopieren
Dies resultiert allerdings gleich bei der Zuweisung von rst!Beispielanlage zum entsprechenden Zielfeld in dem Fehler aus Bild 4: Die Methode “Collect“ für das Objekt “Recordset2“ ist fehlgeschlagen. Wenn Sie weder das Objekt Recordset2 noch die Methode Collect kennen, sind Sie vermutlich nicht allein. Das Objekt Recordset2 ist der Nachfolger des Recordset-Objekts. Es wird stillschweigend statt des Recordset-Objekts verwendet, wenn die Bibliothek Microsoft Office x.0 Access Database Object Library verwendet wird. Dies können Sie leicht ermitteln, indem Sie einen Haltepunkt in der Prozedur AnlagePerDAO hinter den Set rst…-Anweisungen setzen und dann im Direktfenster folgende Anweisung absetzen:
Bild 4: Fehlermeldung beim ersten Kopierversuch
Typename(rst) Recordset2
Nun scheint das schlichte Kopieren des Inhalts des Anlagefeldes nicht zu gelingen. Warum aber funktioniert dies nicht Der Grund wird etwas offensichtlicher, wenn Sie eine neue Abfrage erstellen und eine Tabelle mit einem Anlagefeld in die Abfrage ziehen. Das Anlagefeld liefert noch einige weitere, scheinbar untergeordnete Felder, was im Abfrageentwurf wie in Bild 5 aussieht.
Bild 5: Anlagefeld im Entwurf einer Abfrage
In einem zweiten Anlauf entwerfen wir die Prozedur AnlagePerDAO_II, um die Datensätze der Tabelle tblBeispielanlagen samt dem Inhalt des Anlagefeldes in die Tabelle tblBeispielanlagenZiel zu kopieren (s. Listing 2).
Public Sub AnlagePerDAO_II() Dim db As DAO.Database Dim rst As DAO.Recordset Dim rstZiel As DAO.Recordset Dim rstAnlagen As DAO.Recordset2 Dim rstAnlagenZiel As DAO.Recordset2 Set db = CurrentDb Set rst = db.OpenRecordset("SELECT * FROM tblBeispielanlagen", dbOpenDynaset) Set rstZiel = db.OpenRecordset("SELECT * FROM tblBeispielanlagenZiel", dbOpenDynaset) Do While Not rst.EOF With rstZiel .AddNew !Beispieltext = rst!Beispieltext Set rstAnlagen = rst.Fields("Beispielanlage").Value Set rstAnlagenZiel = rstZiel.Fields("Beispielanlage").Value Do While Not rstAnlagen.EOF rstAnlagenZiel.AddNew rstAnlagenZiel!FileData = rstAnlagen!FileData rstAnlagenZiel!FileName = rstAnlagen!FileName rstAnlagenZiel.Update rstAnlagen.MoveNext Loop .Update End With rst.MoveNext Loop End Sub
Listing 2: Dieser Versuch, Datensätze samt Anlagen zu kopieren, ist erfolgreich.
Diese Prozedur definiert zwei weitere Recordset-Objekte, diesmal explizit vom Typ Recordset2 – nämlich rstAnlagen und rstAnlagenZiel. Sie erstellt wie zuvor zwei Recordsets auf Basis der Quelltabelle tblBeispielanlagen und der Zieltabelle tblBeispielanlagenZiel. Dann beginnt sie, wie auch die vorherige Version, mit dem Durchlaufen aller Datensätze dieses Recordsets. Sie legt mit der AddNew-Methode einen neuen Datensatz in der Tabelle tblBeispielanlagenZiel an und füllt das Feld Beispieltext mit dem Inhalt des gleichnamigen Felds der Quelltabelle. Dann wird es interessant: Die Prozedur öffnet ein weiteres Recordset und füllt es mit einem Verweis auf die Value-Eigenschaft des Anlagefeldes der Tabelle tblBeispielanlagen beziehungsweise des Recordsets rstAnlagen. Dieses Recordset können Sie genauso durchlaufen wie ein herkömmliches Recordset – und dabei auf die folgenden Felder zugreifen:
- FileData
- FileFlags
- FileName
- FileTimeStamp
- FileType
- FileURL
Wir benötigen in diesem Fall allerdings nur die beiden Felder FileData und FileName. Die übrigen sind anderen Anwendungsfällen wie etwa dem Einsatz in Webdatenbanken vorbehalten und sind hier mit dem Wert Null gefüllt.
Die Prozedur legt also für jeden Datensatz des in der Value-Eigenschaft des Anlagefeldes enthaltenen Recordsets einen neuen Datensatz im Recordset der Value-Eigenschaft des Anlagefeldes der Zieldatenbank an. Dabei trägt sie die Werte der beiden Felder FileData und FileName ein und speichert dann den entsprechenden Datensatz mit der Update-Methode.
Nachdem die Prozedur alle Anlagen kopiert hat, speichert sie den eigentlichen Datensatz ebenfalls mit der Update-Methode und wendet sich dem nächsten Datensatz der Tabelle tblBeispielanlagen zu.
Das hat funktioniert: Alle Datensätze der Tabelle tblBeispielanlagen sind in der Tabelle tblBeispielanlagenZiel gelandet (s. Bild 6).
Bild 6: Anlagefelder – erfolgreich kopiert
Anlagefelder kopieren per SQL
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