Verknüpfte Daten kopieren

Das Kopieren einfacher Datensätze ist schnell erledigt. Markieren, kopieren, einfügen – schon liegt der neue Datensatz vor. Was aber geschieht, wenn an dem zu kopierenden Datensatz noch weitere Daten hängen wie etwa solche aus verknüpften Tabellen Dann gilt es erst einmal, die Beziehung zu prüfen und dann zu entscheiden, ob die verknüpften Daten ebenfalls dupliziert werden müssen. Und schließlich benötigen Sie auch noch etwas VBA-Code, um die verknüpften Daten in einem Rutsch zu kopieren. All dies finden Sie im vorliegenden Artikel.

Beispieldatenbank

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

Daten aus verknüpften Tabellen kopieren

Bevor wir uns auf die Programmierung der VBA-Routinen stürzen, wollen wir uns erst einmal ansehen, welche Konstellationen verknüpfter Daten es gibt und wann überhaupt auch die Inhalte der verknüpften Tabellen kopiert werden müssen.

Der einfachste Fall liegt vor, wenn etwa eine Tabelle namens tblKunden über das Fremdschlüsselfeld AnredeID mit einem Datensatz der Tabelle tblAnreden verknüpft ist (siehe Bild 1).

Beziehung zwischen Kunden und Anreden

Bild 1: Beziehung zwischen Kunden und Anreden

Die Tabelle tblAnreden enthält jede benötigte Anrede einmal, was schon darauf hindeutet, dass beim Kopieren eines Datensatzes einer Kundentabelle kein neuer Datensatz in der verknüpften Tabelle tblAnreden angelegt werden muss. Und so ist es: Sie kopieren einfach den Kundendatensatz, wobei der neue Datensatz im Fremdschlüsselfeld AnredeID den gleichen Verweis auf einen Datensatz der Tabelle tblAnreden enthält wie der Originaldatensatz.

Dies gilt eigentlich für alle Beziehungen, in denen die über ein Fremdschlüsselfeld referenzierte Tabelle lediglich Lookup-Werte für ein Feld der Haupttabelle liefert – also beispielsweise auch für Tabellen wie tblKategorien, tblGeschlecht et cetera. Dies kann sich aber auch auf Tabellen beziehen, die mehr als nur einen Lookup-Wert liefern, also beispielsweise einer Tabelle wie tblLieferanten, die etwa mit einer Tabelle namens tblArtikel verknüpft ist.

Individuelle Rechnungen

Anders sieht es aus, wenn die verknüpfte Tabelle Daten enthält, die erst in Zusammenhang mit dem Datensatz der Haupttabelle angelegt werden. Wenn Sie also etwa eine Rechnung zu einem Auftrag in der Tabelle tblRechnungen anlegen und dazu einige Rechnungspositionen in der damit verknüpften Tabelle tblRechnungspositionen, ändert sich die Situation (siehe Bild 2): Wenn Sie einen Rechnung kopieren, werden Sie wohl auch die Rechnungspositionen kopieren, um diese gegebenenfalls individuell anpassen zu können.

Rechnungen und Rechnungspositionen

Bild 2: Rechnungen und Rechnungspositionen

In diesem Fall gehen wir davon aus, dass es sich um Rechnungen für individuelle Leistungen handelt – also beispielsweise das Programmieren einer Anwendung für einen Kunden. Und trotz aller Individualität: Wenn es sich um ein größeres Projekt handelt, werden Sie möglicherweise immer wieder ähnliche Positionen in Rechnung stellen, die Sie nicht jedes Mal erneut formulieren möchten. Dies ist der erste Fall, den wir uns in diesem Artikel anschauen werden.

Bestellungen und Artikel

Der zweite Fall ist die klassische Bestellung mit Bestellpositionen und Artikeln. Hier werden die Bestellungen und die Artikel über eine Tabelle etwa namens tblBestelldetails miteinander per m:n-Beziehung verknüpft.

Wenn Sie hier eine Bestellung neu auf einer bereits vorhandenen Bestellung anlegen möchten, welche die gleichen Bestellpositionen wie das Original enthält, werden Sie sich freuen, wenn Sie dies per Mausklick erledigen können statt die Bestellung manuell Bestellposition für Bestellposition anzulegen. Dies ist das zweite in diesem Artikel behandelte Beispiel (siehe Bild 3).

Bestellungen, Bestellpositionen und Artikel

Bild 3: Bestellungen, Bestellpositionen und Artikel

Daten aus 1:n-Beziehungen kopieren

Nun wollen wir uns das erste Beispiel der individuellen Rechnungen ansehen. Den relevanten Teil des Datenmodells haben Sie ja bereits weiter oben kennengelernt. Zusätzlich haben wir ein Formular erstellt, dass die Daten der Tabelle tblRechnungen anzeigt und die Daten der per 1:n-Beziehung verknüpften Tabelle tblRechnungspositionen zur aktuellen Rechnung in einem Unterformular anzeigt (siehe Bild 4). Haupt- und Unterformular sind über den Wert RechnungID in den Eigenschaften Verknüpfen von und Verknüpfen nach des Unterformular-Steuerelements miteinander verknüpft.

Formular zum Erstellen individueller Rechnungen

Bild 4: Formular zum Erstellen individueller Rechnungen

Wenn Sie nun für den gleichen Kunden eine neue Rechnung erstellen, können Sie dies natürlich manuell erledigen. Wenn sich jedoch weder der Rechnungsbetreff noch die enthaltenen Rechnungspositionen nicht wesentlich geändert haben, können Sie auch den vorhandenen Rechnungsdatensatz kopieren – und ebenso die damit verknüpften Rechnungspositionen.

Dazu haben wir oben im Formular eine Schaltfläche namens cmdRechnungKopieren angelegt. Die durch das Anklicken dieser Schaltfläche ausgelöste Ereignisprozedur soll nun zwei Aufgaben erledigen:

  • Kopieren des Datensatzes aus der Tabelle tblRechnung (also der im Hauptformular angezeigte Datensatz) und
  • Kopieren der mit dem Datensatz im Hauptformular verknüpften Datensätze der Tabelle tblRechnungspositionen (also der Datensätze im Unterformular).

Es gibt (mindestens) zwei Möglichkeiten, diese Aufgabe zu erledigen:

  • durch das Anlegen der neuen Datensätze mit den DAO-Methoden AddNew/Update oder
  • mit entsprechenden SQL-Anweisungen.

Kopieren per DAO

Die erste Variante sieht wie in Listing 1 aus und kopiert die Daten mit AddNew/Update. Dazu ist offensichtlich eine Menge Code erforderlich, aber wir wollen ja auch gleich die Daten aus zwei verknüpften Tabellen duplizieren.

Private Sub cmdRechnungKopieren_Click()
     Dim db As DAO.Database
     Dim rstRechnungen As DAO.Recordset
     Dim rstPositionenAlt As DAO.Recordset
     Dim rstPositionenNeu As DAO.Recordset
     Dim lngAlteRechnungID As Long
     Dim lngNeueRechnungID As Long
     Set db = CurrentDb
     lngAlteRechnungID = Me!RechnungID
     Set rstRechnungen = db.OpenRecordset("SELECT * FROM tblRechnungen WHERE 1=2", dbOpenDynaset)
     With rstRechnungen
         .AddNew
         !Rechnungsbetreff = Me!Rechnungsbetreff
         !Rechnungstext = Me!Rechnungstext
         !Bemerkungen = Me!Bemerkungen
         !KundeID = Me!KundeID
         !Rechnungsdatum = Me!Rechnungsdatum
         lngNeueRechnungID = !RechnungID
         .Update
     End With
     Set rstPositionenAlt = db.OpenRecordset("SELECT * FROM tblRechnungspositionen WHERE RechnungID = " & lngAlteRechnungID, dbOpenDynaset)
     Set rstPositionenNeu = db.OpenRecordset("SELECT * FROM tblRechnungspositionen WHERE 1=2", dbOpenDynaset)
     With rstPositionenAlt
         Do While Not .EOF
             rstPositionenNeu.AddNew
             rstPositionenNeu!RechnungID = lngNeueRechnungID
             rstPositionenNeu!Rechnungsposition = !Rechnungsposition
             rstPositionenNeu!Menge = !Menge
             rstPositionenNeu!Preis = !Preis
             rstPositionenNeu!Mehrwertsteuer = !Mehrwertsteuer
             rstPositionenNeu!EinheitID = !EinheitID
             rstPositionenNeu.Update
             .MoveNext
         Loop
     End With
     Me.Requery
     Me.Recordset.FindFirst "RechnungID = " & lngNeueRechnungID
End Sub

Listing 1: Kopieren von Rechnungsdaten aus dem Haupt- und dem Unterformular

Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar