Tabellen und Beziehungen kopieren

Während Sie eine Datenbank programmieren, fällt unter Umständen eine ganze Menge Datenmüll an – Datensätze, die beim Test eingegeben werden und die Sie nicht mehr benötigen. Dafür wäre ein Satz realistischer Daten nicht schlecht. Dieser Beitrag zeigt, wie Sie das komplette Datenmodell einer Datenbank in einer zweiten Datenbank vorhalten und diese per Mausklick über die Tabellen der aktuell bearbeiteten Datenbank schreiben – und zwar inklusive Beziehungen.

Wenn Sie Anwendungen programmieren und dabei zu Testzwecken immer wieder neue Beispieldaten in die Formulare eingeben oder auch Daten aus anderen Quellen wie XML-Dokumenten, Excel-Tabellen oder auch aus anderen Datenbanken in die Tabellen spülen, möchten Sie sicher gelegentlich den Urzustand wiederherstellen. Kein Problem: Sie müssen den Urzustand nur zum gewünschten Zeitpunkt in eine externe Tabelle schreiben und diesen bei Bedarf wieder herstellen. Natürlich sollten dabei keine zwischenzeitlichen änderungen am Datenmodell übersehen werden.

Dieser Beitrag beschreibt eine Lösung, mit der Sie festgelegte Tabellen einer Datenbank und deren Beziehungen in eine externe Datenbank kopieren und wiederherstellen können. Die Benutzeroberfläche dieser Lösung besteht aus dem Formular frmTabellenImportExport (s. Bild 1). Dieses Formular zeigt beim Öffnen alle Tabellen der aktuellen Datenbank an. Sie können nun durch Markieren der gewünschten Tabellen festlegen, welche Einträge in der Sicherungsdatenbank landen sollen.

pic001.png

Bild 1: Das Formular zum Festlegen der zu importierenden oder zu exportierenden Tabellen

Mit einem Klick auf die Schaltfläche Sichern öffnen Sie einen Datei öffnen-Dialog zum Auswählen der Zieldatei. Wenn Sie eine neue Sicherungsdatei erstellen möchten, markieren Sie zuvor die Option Neue Datenbank. In diesem Fall wählen Sie im Datei speichern-Dialog Pfad und Name der zu erstellenden Datenbankdatei aus. Wenn Sie die Daten einmal gesichert haben, können Sie diese über die Schaltfläche Wiederherstellen wieder in die aktuell geöffnete Datenbank importieren.

Beachten Sie bitte, dass beim Exportieren wie auch beim Importieren alle Tabellen der Zieldatenbank und deren Beziehungen gelöscht werden.

Funktion der Lösung

Das Formular frmTabellenImportExport zeigt im Listenfeld lstTabellen alle Tabellen der aktuellen Datenbank an, deren Name nicht mit USys…, MSys… oder ~… beginnt. Diese Tabellennamen werden beim ersten Öffnen des Formulars in der Tabelle tblTabellenExportImport gespeichert, und zwar in der Prozedur, die durch das Ereignis Beim Laden des Formulars ausgelöst wird (s. Listing 1).

Listing 1: Diese Prozedur wird beim Laden des Formulars frmTabellenImportExport ausgelöst.

Private Sub Form_Load()
    Dim db As DAO.Database
    Dim tdf As DAO.TableDef
    Dim rst As DAO.Recordset
    Set db = CurrentDb
    Set rst = db.OpenRecordset("tblTabellenExportImport", dbOpenDynaset)
    Do While Not rst.EOF
        Set tdf = Nothing
        On Error Resume Next
        Set tdf = db.TableDefs(rst!Tabelle)
        On Error GoTo 0
        If tdf Is Nothing Then
            db.Execute "DELETE FROM tblTabellenExportImport WHERE Tabelle = ''" _
                & rst!Tabelle & "''", dbFailOnError
        End If
        rst.MoveNext
    Loop
    rst.Close
    For Each tdf In db.TableDefs
        Select Case Left(tdf.Name, 4)
        Case "MSys", "USys", "~***"
        Case Else
        On Error Resume Next
        db.Execute "INSERT INTO tblTabellenExportImport(Tabelle) VALUES(''" & tdf.Name & "'')", dbFailOnError
        End Select
    Next tdf
    Me!lstTabellen.Requery
    Set rst = db.OpenRecordset("tblTabellenExportImport", dbOpenDynaset)
    Do While Not rst.EOF
        If rst!Export Then
            Me!lstTabellen.Selected(rst.AbsolutePosition) = True
        End If
        rst.MoveNext
    Loop
    rst.Close
    Set rst = Nothing
    Set db = Nothing
    End Sub

Diese Prozedur prüft bei jedem Aufruf des Formulars, ob die in der Tabelle tblTabellenImportExport gespeicherten Tabellennamen noch mit den tatsächlich in der Tabelle vorhandenen Tabellen übereinstimmen, und gleicht diese gegebenenfalls ab.

Dies geschieht in zwei Stufen: Als erstes durchläuft die Prozedur alle Datensätze der Tabelle tblTabellenExportImport, die wie in Bild 2 aussieht. Sie prüft für jeden Eintrag, ob es noch ein TableDef-Objekt mit dem entsprechenden Namen gibt. Falls nicht, deutet dies darauf hin, dass die Tabelle gelöscht wurde. In diesem Fall wird auch der entsprechende Eintrag aus der Tabelle tblTabellenExportImport entfernt.

pic002.png

Bild 2: Diese Tabelle speichert, welche Tabellen importiert und exportiert werden sollen.

Danach folgt der umgekehrte Weg: Die Prozedur durchläuft in einer For Each-Schleife alle TableDef-Objekte der aktuellen Datenbank und versucht, für jede Tabelle einen Eintrag in der Tabelle tblTabellenExportImport anzulegen.

Da die Tabelle einen eindeutigen Index für das Feld Tabelle enthält, schlägt dies bei bereits vorhandenen Tabellennamen fehl. Dies ist jedoch kein Problem, da die Access-eigene Fehlerbehandlung zuvor ausgeschaltet wurde.

Schließlich speichert die Tabelle im Ja/Nein-Feld Export, ob eine Tabelle beim Exportieren oder Importieren berücksichtigt werden soll. Dies soll sich auch im Listenfeld lstTabellen widerspiegeln, das für die Mehrfachauswahl vorbereitet wurde.

Dazu werden erneut alle Datensätze der Tabelle tblTabellenExportImport durchlaufen. Dabei stellt die Routine für alle Datensätze, die im Feld Export den Wert True enthalten, den Wert Selected des jeweiligen Eintrags im Listenfeld auf den Wert True ein.

Zwar erlaubt das Listenfeld keinen direkten Zugriff auf die Einträge über den Primärschlüsselwert, aber das ist nicht schlimm: Da das Listenfeld alle Datensätze der Tabelle tblTabellenExportImport anzeigt, entspricht die absolute Position des Datensatzzeigers dem Index der Einträge im Listenfeld.

Tabellen aus- und abwählen

Wenn der Benutzer auf einen der Einträge des Listenfeldes lstTabellen klickt, soll der neue Zustand direkt in der Tabelle tblTabellenExportImport gespeichert werden. Dies erledigt eine Prozedur, die durch das Ereignis Nach Aktualisierung des Listenfeldes ausgelöst wird. Leider gibt es bei der Mehrfachauswahl im Listenfeld keine Möglichkeit, direkt den zuletzt angeklickten Wert zu ermitteln. Also machen wir aus der Not eine Tugend und schreiben gleich jeweils alle Zustände in die Tabelle tblTabellenExportImport. Dies erledigt die Prozedur aus Listing 2.

Listing 2: Aktualisieren der Tabellenwerte nach dem Auswählen von Listenfeldeinträgen

Private Sub lstTabellen_AfterUpdate()
    Dim db As DAO.Database
    Dim i As Integer
    Dim intSelected As Integer
    Set db = CurrentDb
    For i = 0 To Me!lstTabellen.ListCount - 1
        intSelected = Me!lstTabellen.Selected(i)
        db.Execute "UPDATE tblTabellenExportImport SET Export = " & intSelected _
            & " WHERE TabelleID = " & Me!lstTabellen.ItemData(i)
    Next i
    End Sub

Exportieren der Tabellen

Bevor Sie Tabellen wiederherstellen können, müssen Sie diese zunächst erstmalig exportieren. Dies erledigen Sie mit einem Klick auf die Schaltfläche cmdSichern. Die dadurch ausgelöste Prozedur (s. Listing 3) prüft zunächst, ob das Kontrollkästchen chkNeueDatenbank aktiviert ist. Falls ja, öffnet sie einen Datei speichern-Dialog, mit dem der Benutzer angeben kann, wie die zu erstellende Datei heißen und wo sie gespeichert werden soll. Die Datenbankdatei wird gleich im folgenden Schritt angelegt, und zwar mit der CreateDatabase-Methode des Workspace-Objekts.

Listing 3: Starten des Sicherungsvorgangs

Private Sub cmdSichern_Click()
    Dim strPfad As String
    If Me!chkNeueDatenbank Then
        strPfad = mdlImportExport.GetSaveFile(CurrentProject.Path)
        DBEngine(0).CreateDatabase strPfad, dbLangGeneral
    Else
        strPfad = OPENFILENAME(CurrentProject.Path)
    End If
    If Len(Dir(strPfad)) > 0 Then
        MoveTablesAndRelations CurrentDb.Name, strPfad
    End If
    End Sub

Falls die Tabellen in eine bereits bestehende Datenbank übertragen werden sollen, ruft die Prozedur einfach nur einen Datei auswählen-Dialog auf. In beiden Fällen landet ein Dateipfad in der Variablen strPfad, der nun weiterverarbeitet werden kann. Dieser Pfad entspricht nämlich der Zieldatenbank des Exports.

Enthält strPfad eine vorhandene Datei, wird die Funktion MoveTablesAndRelations mit den Namen der aktuellen Datenbank und der Zieldatenbank aufgerufen. Bevor wir uns diese ansehen, werfen wir noch einen Blick auf die Prozedur, die durch einen Klick auf die Schaltfläche cmdWiederherstellen ausgelöst wird. Diese fragt direkt den Namen der Quelldatei der Sicherungsdatenbank ab und prüft diesen auf Gültigkeit.

Hat alles funktioniert, ruft auch diese Prozedur die Funktion MoveTablesAndRelations auf – mit den gleichen Parametern, nur in umgekehrter Reihenfolge. Zuerst wird also der Name der externen Quelldatenbank übergeben und dann der Name der Zieldatei, also der aktuellen Datenbank (s. Listing 4).

Listing 4: Starten der Wiederherstellung

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

Schreibe einen Kommentar