Home > Artikel > Ausgabe 1/2014 > Datensätze per VBA kopieren

Datensätze per VBA kopieren

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).

Im Artikel Datensätze kopieren haben Sie bereits erfahren, wie Sie Datensätze ohne eine einzige selbstgeschriebene Zeile VBA-Code kopieren können. Der vorliegende Artikel zeigt, wie Sie dies mit VBA erledigen und damit einige Flexibilität gewinnen. Wir stürzen uns dabei zunächst auf die Datensätze, die in einem Unterformular angezeigt werden und schauen uns danach die übrigen Methoden von VBA zum Kopieren von Datensätzen an.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1401_DatensaetzeKopierenVBA.mdb.

Datensätze im Unterformular kopieren

Im Artikel Datensätze kopieren haben wir zuletzt per Schaltflächen-Assistent eine Schaltfläche mit einer Prozedur erstellt, die fünf DoCmd.RunCommand-Befehle mit verschiedenen Parametern aufruft, um den im aktuellen Formular angezeigten Datensatz zu kopieren und als neuen Datensatz in die Tabelle einzufügen.

Eigentlich, so nimmt man naiverweise an, sollte dies doch genau in dieser Form auch funktionieren, wenn wir den Datensatz in einem Unterformular, das seine Daten in der Datenblattansicht anzeigt, kopieren wollen. Wenn wir also ein Hauptformular erstellen und in dieses ein Unterformular einfügen, dass die Tabelle tblArtikel als Datenherkunft verwendet, alle Felder dieser Tabelle anzeigt und den Wert Datenblatt als Standardansicht nutzt, brauchen wir nur noch eine Schaltfläche im Hauptformular, die den Kopiervorgang durchführt (siehe Bild 1).

Haupt- und Unterformular mit der Schaltfläche zum Kopieren im Hauptformular und den Daten im Unterformular

Bild 1: Haupt- und Unterformular mit der Schaltfläche zum Kopieren im Hauptformular und den Daten im Unterformular

Diese nennen wir cmdDatensatzKopierenUF und legen dafür, wieder mit dem Schaltflächen-Assistent, die Prozedur zum Duplizieren des aktuellen Datensatzes an. Die Prozedur erleichtern wir noch um die Fehlerbehandlung, um direkt zu erkennen, welche Zeile einen eventuellen Fehler auslöst (siehe Listing 1).

Private Sub cmdDatensatzKopierenUF_Click()

     'Fehlerbehandlung entfernt

     DoCmd.RunCommand acCmdSelectRecord

     DoCmd.RunCommand acCmdCopy

     DoCmd.RunCommand acCmdRecordsGoToNew

     DoCmd.RunCommand acCmdSelectRecord

     DoCmd.RunCommand acCmdPaste

End Sub

Listing 1: Kopieren des Datensatzes im Unterformular

Anschließend starten Sie die Prozedur mit einem Mausklick auf die Schaltfläche cmd­Daten­satz­ko­pieren­UF und erhalten die Fehlermeldung aus Bild 2. Anscheinend findet Access also nichts, was es aktuell kopieren könnte – was bei genauerer Betrachtung auch logisch ist: Immerhin sollte das zu kopierende Objekt auch den Fokus besitzen oder in einer anderen Form markiert sein. Aber selbst wenn Sie noch vor dem Mausklick auf die Schaltfläche cmdDatensatzKopieren­UF den zu kopierenden Datensatz im Unterformular markiert haben, so verliert das Unterformular doch zum Zeitpunkt des Mausklicks auf die Schaltfläche den Fokus. Das ist jedoch kein großes Problem: Es gibt nämlich ebenfalls Befehle, um den Fokus auf die meisten Elemente der benutzerdefinierten Formulare zu verschieben – in diesem Fall auf das Unterformular-Steuerelement. Damit die Prozedur ihren Dienst tut, müssen Sie einfach nur die folgende Anweisung als erste Zeile der Prozedur einfügen:

Fehler, der beim Versuch, den Datensatz im Unterformular zu kopieren, ausgelöst wird.

Bild 2: Fehler, der beim Versuch, den Datensatz im Unterformular zu kopieren, ausgelöst wird.

Me!sfmDatensatzKopieren.SetFocus

Nun erhält das Unterformular nach dem Anklicken der Schaltfläche den Fokus und die folgenden fünf DoCmd.RunCommand-Befehle können ihren Dienst verrichten. Der kopierte Datensatz landet dann am Ende des Datenblatts und wird gleich markiert (siehe Bild 3).

Kopieren und Einfügen eines Datensatzes im Unterformular per Schaltfläche

Bild 3: Kopieren und Einfügen eines Datensatzes im Unterformular per Schaltfläche

Datensatz per DAO kopieren

Im nächsten Beispiel wollen wir eine Variante vorstellen, die per direktem Zugriff auf die zu kopierenden Daten in der Tabelle erfolgt. Das Datenblatt im Unterformular dient nur noch der Auswahl des zu kopierenden Datensatzes und der Anzeige des Duplikats.

Das Beispiel finden Sie im Formular frmDatensatzKopierenDAO. Die Prozedur, die durch die Schaltfläche cmdDatensatzKopierenDAO ausgelöst wird, finden Sie in Listing 2. Die Prozedur verwendet die Recordset-Methoden der DAO-Bibliothek zum Kopieren des aktuell markierten Datensatzes der Tabelle tblArtikel im Unterformular sfmDatensatzKopieren.

Private Sub cmdDatensatzKopierenDAO_Click()

     Dim db As DAO.Database

     Dim rstOriginal As DAO.Recordset

     Dim rstDuplikat As DAO.Recordset

     Dim lngOriginalID As Long

     Dim lngDuplikatID As Long

     lngOriginalID = Me!sfmDatensatzKopieren.Form!ArtikelID

     Set db = CurrentDb

     Set rstOriginal = db.OpenRecordset("SELECT * FROM tblArtikel WHERE ArtikelID = " & lngOriginalID, dbOpenDynaset)

     Set rstDuplikat = db.OpenRecordset("SELECT * FROM tblArtikel WHERE 1 = 2", dbOpenDynaset)

     rstDuplikat.AddNew

     rstDuplikat!Artikelname = rstOriginal!Artikelname

     rstDuplikat!LieferantID = rstOriginal!LieferantID

     rstDuplikat!KategorieID = rstOriginal!KategorieID

     rstDuplikat!Liefereinheit = rstOriginal!Liefereinheit

     rstDuplikat!Einzelpreis = rstOriginal!Einzelpreis

     rstDuplikat!Lagerbestand = rstOriginal!Lagerbestand

     rstDuplikat!BestellteEinheiten = rstOriginal!BestellteEinheiten

     rstDuplikat!Mindestbestand = rstOriginal!Mindestbestand

     rstDuplikat!Auslaufartikel = rstOriginal!Auslaufartikel

     rstDuplikat!AusgelaufenAm = rstOriginal!AusgelaufenAm

     lngDuplikatID = rstDuplikat!ArtikelID

     rstDuplikat.Update

     Me!sfmDatensatzKopieren.Form.Recordset.Requery

     Me!sfmDatensatzKopieren.Form.Recordset.FindFirst "ArtikelID = " & lngDuplikatID

End Sub

Listing 2: Kopieren eines Datensatzes per DAO

Die Prozedur deklariert ein Database-Objekt namens db und zwei Recordset-Objekte. Das erste heißt rst­Original und soll den zu kopierenden Datensatz referenzieren. Das zweite heißt rstDuplikat und nimmt den neu zu erstellenden Datensatz auf.

Als Erstes wollen wir jedoch den Primärschlüsselwert des zu duplizierenden Datensatzes ermitteln, also des Datensatzes, der aktuell im Unterformular markiert ist. Diesen Wert erhalten wir relativ einfach, indem wir das Feld ArtikelID im Unterformular referenzieren. Der Weg dorthin ist jedoch etwas komplizierter: Dazu referenzieren wir zunächst das Hauptformular (vom Klassenmodul des Formulars aus mit Me). Darin greifen wir auf das Unterformular-Steuerelement zu, und zwar über dessen Namen (sfmDatensatzKopieren). Dies entspricht jedoch noch nicht dem darin enthaltenen Formular, welches wir mit der Form-Eigenschaft ansprechen können. Erst über das im Unterformular-Steuerelement enthaltene Formular können wir schließlich auf den Wert von ArtikelID zugreifen und den enthaltenen Wert in der Long-Variablen lngOriginalID speichern.

Danach füllen wir die Recordset-Variable rstOriginal mit einem Verweis auf den zu kopierenden Datensatz, was durch die Formulierung einer entsprechenden SELECT-Abfrage als erstes Argument der OpenRecordset-Methode gelingt.

Dann öffnen wir ein weiteres Recordset-Objekt, dass diesmal aber kein Datensatz referenzieren soll, sondern lediglich als Ziel zum Anlegen des zu kopierenden Datensatzes dienen soll. Es kann natürlich einen oder alle Datensätze der zugrunde liegenden Tabelle tblArtikel enthalten, aber dies wäre unnötig. Also öffnen wir das Recordset auf Basis einer SELECT-Abfrage, die durch die nicht zu erfüllende Bedingung 1=2 eine leere Datensatzgruppe zurückliefert.

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!