Formularinhalte speichern und wieder abrufen

Webbrowser kennen diese Funktion dank Add-Ons schon länger: Wenn Sie dort Daten in ein Formular eintragen, können Sie diese speichern und bei der nächsten Verwendung des Formulars per Mausklick erneut einfügen. Warum gibt es das unter Access eigentlich noch nicht Wie auch immer: Dieser Beitrag zeigt, wie Sie die Inhalte eines Access-Formulars zwischenspeichern und bei Bedarf wieder abrufen. Das hilft sowohl dem Entwickler als auch dem Benutzer, denn sowohl bei der Entwicklung als auch bei der Anwendung der Datenbank kann dieses Feature sehr nützlich sein – wenn auch mit leicht unterschiedlichem Ansatz.

Wir wollen die Technik zum Speichern und Wiederherstellen eines Formularinhalts von zwei Seiten betrachten: Aus Entwicklersicht und aus Benutzersicht. Der Entwickler benötigt das Feature hauptsächlich, um beim Testen eines Formulars nicht die gleichen Daten immer wieder neu einzugeben, sondern diese gegebenenfalls per Mausklick zu speichern und wiederherzustellen. Für den Entwickler soll diese Funktion eher flexibel und für alle Formulare anwendbar sein – am besten also in Form eines Add-Ins, das die Inhalte mehrerer Formulare verwalten kann.

Für den Benutzer ist eine eingebaute Funktion sinnvoll, welche zum einen eine Schaltfläche zum Speichern der aktuellen Eingabe bietet, zum anderen eine Auswahlmöglichkeit für die bisher gespeicherten Daten.

Formularinhalte speichern für Benutzer

In diesem Beitrag schauen wir uns die Variante für Benutzer an. Dazu erstellen wir zunächst ein einfaches Formular, das die Daten der Tabelle tblArtikel in der Formularansicht anzeigt. Diesem fügen wir ein Kombinationsfeld namens cboVorlageAuswaehlen hinzu sowie eine Schaltlfäche mit der Beschriftung Speichern und dem Namen cboVorlageSpeichern. Im Entwurf sieht das Formular nun wie in Bild 1 aus.

Das Beispielformular in der Entwurfsansicht

Bild 1: Das Beispielformular in der Entwurfsansicht

Bevor wir uns nun an die Programmierung machen können, müssen wir uns ein paar Gedanken um die Speicherung selbst machen. Die erste Frage dabei lautet: Welche Inhalte sollen überhaupt gespeichert werden Und die zweite: Wohin und wie speichern wir diese Inhalte

Die erste Frage ist eigentlich einfach zu beantworten: Natürlich alle Daten, die der Benutzer in das Formular eingegeben hat! Nur müssen wir noch herausfinden, in welchen Steuerelementen sich diese Daten befinden. Aber wie erkennen wir, welche Steuerelemente die Daten enthalten, die in der zugrunde liegenden Datenherkunft gespeichert werden

Und: Gibt es überhaupt immer eine Datenherkunft Kann es nicht sein, dass ein Formular zur Eingabe von Daten dient, die noch nicht einmal in der Datenbank gespeichert werden Dies könnte ja geschehen, wenn Sie etwa die Daten für eine Banküberweisung in ein Formular eingeben und die überweisung anstoßen. Die Daten müssen nicht zwangsläufig gespeichert werden, denn wir können diese später nach erfolgter überweisung vom Bankserver einlesen.

Allein die Bindung eines Steuerelements ein Feld der Datenherkunft liefert also kein Indiz dafür, dass der Inhalt des Steuerelements gespeichert und wiederhergestellt werden soll.

Also gestalten wir die Funktion so flexibel, dass wir sowohl einfach den Inhalt aller gebundenen Steuerelemente speichern können als auch speziell zum Speichern markierte Steuerelemente.

Tabelle zum Speichern der Daten

Die Tabelle zum Speichern der Inhalte der Steuerelemente soll ebenso flexibel sein. Wir möchten diese also nicht auf eine einzige Datenherkunft auslegen und somit nicht etwa die Artikeltabelle abbilden, sondern beliebig viele Felder für unterschiedliche Vorlagen in der Tabelle speichern.

Damit wir verschiedene Vorlagen für das gleiche Formular speichern können, benötigen wir ein Feld, das den Namen der Vorlage aufnimmt. Wenn wir die Vorlagen-Funktion für mehrere Formulare in der gleichen Datenbank verwenden möchten, müssen wir außerdem noch ein Feld vorsehen, das angibt, zu welchem Formular die Vorlage gehört.

Schließlich benötigen wir ein Feld für den Steuerelementnamen und eines für den Inhalt des Steuerelements. Welchen Datentyp soll das Feld zum Speichern der Inhalte haben Da wir einfach nur die in den Steuerelementen enthaltenen Werte speichern wollen, die ja in verschiedenen Datentypen auftreten können, verwenden wir den Datentyp Text. Diesem können wir sowohl Texte also auch Zahlen, Datumsangaben oder Boolean-Werte zuweisen (0/-1).

Die Tabelle tblVorlagen sieht im Entwurf schließlich wie in Bild 2 aus. Dort erkennen Sie auch, dass es einen aus den drei Feldern Formularname, Vorlage und Steuerelementname zusammengesetzten, eindeutigen Index gibt.

Entwurf der Tabelle tblVorlagen

Bild 2: Entwurf der Tabelle tblVorlagen

Speichern des Formularinhalts

Nun benötigen wir eine Prozedur, die durch das Ereignis Beim Klicken der Schaltfläche cmdVorlageSpeichern ausgelöst wird. Zuvor müssen wir noch festlegen, welche Felder gespeichert werden sollen. Wir wollen zwei Arten ermöglichen:

  • Speichern aller Felder, die an ein Feld der Datenherkunft gebunden sind
  • Speichern aller Felder, deren Tag-Eigenschaft einen bestimmten Wert enthält, zum Beispiel AlsVorlage-Speichern.

Die erste Variante ist für gebundene Formulare interessant, die zweite für gebundene und ungebundene Formulare. Welche Methode zum Einsatz kommt, legen wir durch eine Boolean-Variable fest, die beim Laden des Formulars auf den entsprechenden Wert eingestellt wird.

Werfen wir nun einen Blick auf die Schaltfläche cmdVorlageSpeichern. Diese löst beim Anklicken die Prozedur aus Listing 1 (Teil I) aus. Die Prozedur liest zunächst den Namen des aktuellen Formulars aus der Eigenschaft Name in die Variable strFormular ein. Dann prüft sie, ob aktuell im Kombinationsfeld cboVorlageAuswaehlen ein Eintrag ausgewählt ist. Falls ja, geht sie davon aus, dass die aktuellen Inhalte des Formulars unter dem Namen der ausgewählten Vorlage gespeichert werden sollen. Das bedeutet natürlich, dass die vorhandenen Daten überschrieben werden. Der Name der aktuell ausgewählten Vorlage landet dann zunächst in der Variablen strVorlage. Ist das Kombinationsfeld leer, trägt die Prozedur den Platzhalter [Neue Vorlage] in die Variable strVorlage ein.

Private Sub cmdVorlageSpeichern_Click()
     Dim db As DAO.Database
     Dim rst As DAO.Recordset
     Dim ctl As Control
     Dim strName As String
     Dim varWert As Variant
     Dim strVorlage As String
     Dim strFormular As String
     Dim bolFeldSpeichern As Boolean
     Dim strTest As String
     strFormular = Me.Name
     If Not IsNull(Me!cboVorlageAuswaehlen) Then
         strVorlage = Me!cboVorlageAuswaehlen
     Else
         strVorlage = "[Neue Vorlage]"
     End If
     strVorlage = InputBox("Geben Sie eine Bezeichnung für die Vorlage ein.", _
         "Vorlage speichern", strVorlage)
     Set db = CurrentDb
     db.Execute "DELETE FROM tblVorlagen WHERE Vorlage = ''" & strVorlage _
         & "'' AND Formularname = ''" & strFormular & "''", dbFailOnError
     Set rst = db.OpenRecordset("SELECT * FROM tblVorlagen", dbOpenDynaset)
     For Each ctl In Me.Controls
         bolFeldSpeichern = False
         Select Case bolGebundeneFelder
             Case True
                 On Error Resume Next
                 strTest = ctl.ControlSource
                 If Err.Number = 0 Then
                     bolFeldSpeichern = True
                 End If
                 On Error GoTo 0
             Case False
                 If ctl.Tag = "AlsVorlageSpeichern" Then
                     bolFeldSpeichern = True
                 End If
         End Select
         ...

Listing 1: Speichern des aktuellen Formularinhalts als Vorlage, Teil I

Dieser Wert wird nun in einer InputBox angezeigt, die neben dem Text Geben Sie eine Bezeichnung für die Vorlage ein. den in strVorlage gespeicherten Wert als Standardwert verwendet (s. Bild 3). Anschließend löscht die Prozedur mit einer per Execute-Methode ausgeführten DELETE-Anweisung alle Datensätze aus der Tabelle tblVorlagen, deren Feld Vorlage den Wert aus strVorlage und deren Feld Formularname den Wert aus strFormular enthält.

Abfrage des Namens für die neue Vorlage

Bild 3: Abfrage des Namens für die neue Vorlage

Danach öffnet die Prozedur ein Recordset auf Basis der Tabelle tblVorlagen und speichert den Verweis darauf in der Variablen rst. In einer For Each-Schleife durchläuft die Prozedur dann alle Steu-erelemente des Formulars (Me.Controls) und speichert das aktuelle Steuerelement in der Variablen ctl.

Die folgenden Anweisungen ermitteln, ob der Inhalt des Steuerelements aus ctl gespeichert werden kann und soll. Zunächst geht die Prozedur vom Gegenteil aus und stellt die Variable bolFeldSpeichern, die letztlich darüber entscheidet, auf den Wert False ein.

Dann prüft die Prozedur den Wert der Variablen bolGebundeneFelder. Diese wird im Kopf des Klassenmoduls deklariert:

Dim bolGebundeneFelder As Boolean

Den Wert dieser Variablen legen wir in der Ereignisprozedur Beim öffnen des Formulars fest – dazu später mehr. Hat die Variable den Wert True, sollen die Werte aller gebundenen Felder des Formulars in der Tabelle tblVorlagen gespeichert werden, sonst nur diejenigen Felder, deren Tag-Eigenschaft (im Eigenschaftsfenster unter Marke zu finden) den Wert AlsVorlageSpeichern enthält. Die Prozedur ermittelt den Wert der Variablen bolGebundeneFelder in einer Select Case-Bedingung und schlägt dort den entsprechenden Weg ein.

Im Fall der gebundenen Felder deaktiviert die Prozedur zunächst die Fehlerbehandlung und versucht dann, den Wert der Eigenschaft ControlSource des Steuerelements in die Variable strTest einzulesen. Dies führt zu einem Fehler, wenn das Steuerelement nicht über die Eigenschaft Steuerelementinhalt (ControlSource) verfügt, der aber zu einer Fehlermeldung führt. Stattdessen prüft die Prozedur im nächsten Schritt, ob Err.Number den Wert 0 enthält, was dafür spricht, dass bei der Zuweisung kein Fehler aufgetreten ist und die Eigenschaft Steuerelementinhalt somit gefüllt ist.

Es handelt sich also um ein gebundenes Feld, dessen Inhalt in der Vorlage gespeichert werden soll, also stellt die Prozedur die Variable bolFeldSpeichern auf den Wert True ein.

Sollte bolGebundeneFelder den Wert False enthalten, sollen nur speziell gekennzeichnete Felder in der Vorlage gespeichert werden.

Die Prozedur prüft also für das aktuelle Steuerelement, ob die Tag-Eigenschaft den Wert AlsVorlageSpeichern aufweist. In diesem Fall erhält bolFeldSpeichern wiederum den Wert True (anderenfalls bleibt er False).

Da wir nun durch den Wert der Variablen bolFeldSpeichern wissen, ob der Inhalt des Steuerelements gespeichert werden soll, können wir die benötigen Werte ermitteln (s. Listing 2). Der Name des Steuerelements landet in strName, der Wert in strWert.

         ...
         If bolFeldSpeichern = True Then
             strName = ctl.Name
             varWert = ctl.Value
             Select Case strName
                 Case "cboVorlageAuswaehlen", "cmdVorlageSpeichern"
                 Case Else
                     rst.AddNew
                     rst!Vorlage = strVorlage
                     rst!Formularname = strFormular
                     rst!Steuerelementname = strName
                     rst!Steuerelementinhalt = varWert
                     rst.Update
             End Select
         End If
     Next ctl
     Me!cboVorlageAuswaehlen.Requery
     Me!cboVorlageAuswaehlen = strVorlage
End Sub

Listing 2: Speichern des aktuellen Formularinhalts als Vorlage, Teil II

Wir prüfen das Steuerelement noch dahingehend, ob es sich dabei um das Kombinationsfeld zur Auswahl der Vorlagen oder um die Schaltfläche cmdVorlageSpeichern handelt. Falls nicht, erfolgt der eigentliche Speichervorgang für dieses Steuerelement.

Hier legen wir mit der AddNew-Methode einen neuen Datensatz in der Tabelle an und füllen die Felder Vorlage, Formularname, Steuerelementname und Steuerelementinhalt mit den Werten der Variablen strVorlage, strFormularname, strName und strWert. Schließlich speichert die Update-Methode den Datensatz.

Auf die gleiche Weise durchläuft die Prozedur alle Steuerelemente des Formulars und speichert die Inhalte der infrage kommenden Steuerelemente. Schließlich aktualisiert sie die Datensatzherkunft des Kombinationsfeldes cboVorlageAuswaehlen und stelle dieses auf die soeben gespeicherte Vorlage ein.

Der Inhalt der Tabelle tblVorlagen sieht für eine Vorlage des Beispielformulars frmArtikel nun wie in Bild 4 aus.

Die Tabelle tblVorlagen mit einer Beispielvorlage

Bild 4: Die Tabelle tblVorlagen mit einer Beispielvorlage

Kombinationsfeld zur Auswahl einer Vorlage

Schauen wir uns nun das Kombinationsfeld cboVorlageAuswaehlen an. Es erhält seine Datensatzherkunft beim öffnen des Formulars durch die Ereignisprozedur, die durch das Ereignis Beim öffnen ausgelöst wird (s. Listing 3). Dabei dient der Formularname als Filter für die anzuzeigenden Elemente. Damit jeder Vorlagenname nur einmal angezeigt wird, verwendet die Abfrage hinter SELECT das Schlüsselwort DISTINCT.

Private Sub Form_Open(Cancel As Integer)
     bolGebundeneFelder = True
     Me!cboVorlageAuswaehlen.RowSource = _
         "SELECT DISTINCT Vorlage FROM tblVorlagen WHERE Formularname = ''" _
         & Me.Name & "'' ORDER BY Vorlage;"
End Sub

Listing 3: Diese Prozedur wird bei öffnen des Formulars ausgelöst.

Auswahl einer Vorlage

Wenn der Benutzer einen der im Kombinationsfeld enthaltenen Einträge auswählt, löst er damit die Prozedur aus Listing 4 aus.

Private Sub cboVorlageAuswaehlen_AfterUpdate()
     Dim db As DAO.Database
     Dim rst As DAO.Recordset
     Set db = CurrentDb
     Set rst = db.OpenRecordset("SELECT * FROM tblVorlagen WHERE Vorlage = ''" _
         & Me!cboVorlageAuswaehlen _
         & "'' AND Formularname = ''" & Me.Name & "''", dbOpenDynaset)
     Do While Not rst.EOF
         If Not IsNull(rst!Steuerelementinhalt) Then
             On Error Resume Next
             Me.Controls(rst!Steuerelementname) = rst!Steuerelementinhalt
             On Error GoTo 0
         End If
         rst.MoveNext
     Loop
End Sub

Listing 4: Prozedur, die nach dem Aktualisieren des Kombinationsfeldes ausgelöst wird

Diese öffnet ein Recordset auf Basis der Tabelle tblVorlagen, wobei als Filter der Name der Vorlage aus dem Kombinationsfeld sowie der Formularname verwendet werden. Anschließend durchläuft die Prozedur alle Datensätze der Tabelle und prüft dabei zunächst, ob das Feld Steuerelementinhalt nicht den Wert Null enthält.

Ist der Feldinhalt ungleich Null, trägt die Prozedur den Wert des Feldes Steu-er-elementinhalt als Wert des mit dem Feld Steuerelementname angegebenen Steuerelements ein.

Vor dem Zuweisen dieses Wertes deaktiviert die Prozedur die Fehlerbehandlung. Warum das Es gibt einige wenige Fälle, bei denen die Zuweisung der Werte nicht gelingt. Der einzige, der beim Testen dieser Funktion aufgefallen ist, war der Fall eines Primärschlüsselwertes mit Autowert. Ein Steuerelement mit einem Autowertfeld als Steuerelementinhalt kann natürlich nicht einfach durch Zuweisen eines Wertes gefüllt werden. Den dadurch ausgelösten Fehler übergeht die Prozedur jedoch durch die Deaktivierung der Fehlerbehandlung.

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