Dynamische Standardwerte

In vielen Fällen können Sie dem Benutzer bei der Nutzung Ihrer Anwendung durch die Vorgabe von Standardwerten Arbeit abnehmen. Oft kristallisiert sich aber erst später heraus, welche die gewünschten Standardwerte sind oder diese unterscheiden sich je nach Benutzer. Dann wäre es praktisch, wenn die Benutzer selbst die Standardwerte für das Anlegen neuer Datensätze vorgeben könnten. Vielleicht möchten Sie sogar, dass der nächste neue Datensatz die Werte des vorherigen Datensatzes als Standardwerte übernimmt Wie dies gelingt, zeigt der vorliegende Beitrag.

Als Beispielformular nutzen wir ein einfaches Detailformular namens frmArtikel, welches die Daten der Tabelle tblArtikel der Beispieldatenbank anzeigt.

Angenommen, die Datenbank enthält überwiegend Artikel einer bestimmten Kategorie, beispielsweise der Kategorie Getränke mit dem Primärschlüsselwert 1, dann könnte es dem Benutzer einige Arbeit sparen, wenn dieser Wert beim Anlegen eines neuen Datensatzes bereits voreingestellt wird. Dies erledigen Sie über die Eigenschaft Standardwert des Kombinationsfeldes zur Anzeige der Kategorie im Entwurf des Formulars (s. Bild 1).

Formular mit der Standardwert-Eigenschaft im Entwurf

Bild 1: Formular mit der Standardwert-Eigenschaft im Entwurf

Wenn Sie dann in die Formularansicht wechseln und einen neuen Datensatz anzeigen, erscheint im Kombinationsfeld Kategorie bereits der voreingestellte Eintrag (s. Bild 2). Dies ändert sich allerdings auch nicht beim Anlegen weiterer Datensätze.

Kategorie Getränke als Standardwert

Bild 2: Kategorie Getränke als Standardwert

Vorarbeit: Steuerelementname ändern

Da wir die Felder direkt aus der Feldliste in das Formular gezogen haben, hat Access die Namen der Felder als Steuerelementnamen übernommen. Das kann in manchen Situationen zu Problemen führen, wenn Sie per VBA auf das Steuerelement zugreifen wollen – etwa, um die Eigenschaft DefaultValue einzustellen. Diese ist nämlich nur für Steuerelemente verfügbar, nicht aber für die Felder der Datenherkunft des Formulars, die aber – wenn Steuerelement und Feld den gleichen Namen tragen – auf die gleiche Weise referenziert werden. Um Missverständnissen vorzubeugen, sollten Sie also das Steuerelement mit einem Präfix versehen, also etwa txt für Textfelder oder cbo für Kombinationsfelder. Sie können ganz einfach testen, dass DefaultValue für Felder nicht zur Verfügung steht, indem Sie das Kombinationsfeld in cboKategorieID umbenennen und dann versuchen, dem Feld KategorieID die Eigenschaft DefaultValue zuzuweisen. Diese steht dort nicht zur Verfügung, wie Bild 3 zeigt.

DefaultValue steht nur für Steuerelemente zur Verfügung

Bild 3: DefaultValue steht nur für Steuerelemente zur Verfügung

Wert des vorherigen Datensatzes übernehmen

Eine Variante lautet nun, den Wert des zuvor eingegebenen Datensatzes als Standardwert für den folgenden Datensatz zu übernehmen. Dazu ist nicht viel Aufwand nötig: Wir fügen dem Klassenmodul des Formulars lediglich eine Ereignisprozedur hinzu, die durch das Ereignis Nach Aktualisierung des betroffenen Steuerelements ausgelöst wird. Diese Prozedur sieht wie folgt aus:

Private Sub cboKategorieID_AfterUpdate()
     Me!cboKategorieID.DefaultValue = Me!cboKategorieID
End Sub

Wenn Sie nun den Wert des Feldes KategorieID über das Kombinationsfeld ändern und dann einen neuen Datensatz anzeigen, erscheint der zuletzt gewählte Wert bereits als Standardwert dieses Feldes.

Wenn Sie diese Methode nutzen, benötigen Sie für andere Datentypen leicht abgewandelte Varianten der obigen Methode. Für Felder mit dem Datentyp Text etwa müssen Sie den Wert, den Sie der Eigenschaft DefaultValue zuweisen wollen, noch in Anführungszeichen einfassen. Für das Textfeld txtArtikelname sieht dies wie folgt aus:

Private Sub txtArtikelname_AfterUpdate()
     Me!txtArtikelname.DefaultValue = Chr(34) _
         & Me!txtArtikelname & Chr(34)
End Sub

Chr(34) entspricht dem Anführungszeichen (). Sie können stattdessen auch zwei in zwei weitere Anführungszeichen eingefasste Anführungszeichen angeben:

Me!txtArtikelname.DefaultValue = """" _
     & Me!txtArtikelname & """"

Die Variante mit Chr(34) ist jedoch besser lesbar.

Für andere Felddatentypen wie Datum– oder Ja/Nein-Felder verwenden Sie auch die zuerst genannte Variante mit der direkten Zuweisung des aktuellen Wertes.

Damit findet der Benutzer nun schon einmal jeweils den zuletzt eingegebenen Wert für verschiedene Steuerelemente als Standardwert für neue Datensätze vor.

Nach dem Schließen und öffnen

Die Lösung hat allerdings einen kleinen Nachteil: Wenn der Benutzer die Datenbank schließt und wieder öffnet, sind die zusammengestellten Standardwerte wieder weg (genau genommen geschieht dies bereits, wenn das Formular geschlossen wird). Das ist klar, denn wenn wir dynamisch per VBA Eigenschaften zuweisen, werden diese ja nicht gespeichert. Dies wäre nur der Fall, wenn Sie die Eigenschaft Standardwert in der Entwurfsansicht festlegen und das Formular dann speichern.

Was tun Abhilfe schafft eine Tabelle, in welcher wir die Standardwerte für verschiedene Formulare und Steuerelemente speichern können. Die Tabelle heißt tblStandardwerte und sieht im Entwurf wie in Bild 4 aus. Damit die Tabelle nicht nur für ein, sondern gleich für mehrere Formulare Standardwerte speichern kann, legen wir zwei Felder namens Formularename und Steuerelementname an, welche die entsprechenden Daten zum betroffenen Steuerelement speichern. Das Feld Standardwert nimmt dann den zu speichernden Standardwert auf. Damit der Benutzer für keine Kombination aus Formularname und Steuerelementname zwei Standardwerte speichern kann, fügen wir gleich noch einen eindeutigen Index namens UniqueIndex für die beiden Felder Formularname und Steuerelementname hinzu.

Tabelle zum Speichern von Standardwerten

Bild 4: Tabelle zum Speichern von Standardwerten

Um unser Formular mit Funktionen zum Lesen und Schreiben der Standardwerte auszustatten, kopieren wir es zunächst und fügen es unter dem Namen frmArtikel_Standardwerttabelle wieder ein. Werfen Sie dann die bereits angelegten Ereignisprozeduren aus der neuen Version des Formulars heraus.

Standardwerte speichern

Das Speichern eines Wertes als Standardwert soll beim Speichern des jeweiligen Datensatzes erfolgen. Dazu bauen wir uns eine Prozedur, die den Namen des Formulars, den Namen des Steuerelements und den neuen Standardwert als Parameter entgegennimmt und nennen diese StandardwertSpeichern. Die Prozedur sieht wie in Listing 1 aus. Die Prozedur prüft zunächst, ob der Parameter varStandardwert überhaupt einen Wert enthält. Falls das Feld, für das der Standardwert gespeichert werden soll, nämlich den Wert Null hat, ist varStandardwert leer. Ist varStandardwert leer, geschieht Folgendes:

Public Sub StandardwertSpeichern(strFormularname As String, strSteuerelementname As String, varStandardwert As Variant)
     Dim db As DAO.Database
     Set db = CurrentDb
     On Error Resume Next
     If Not IsEmpty(varStandardwert) Then
         db.Execute "INSERT INTO tblStandardwerte(Formularname, Steuerelementname, Standardwert) VALUES(''''" _
             & strFormularname & "'''', ''''" & strSteuerelementname & "'''', ''''" & varStandardwert & "'''')", dbFailOnError
         If Err.Number = 3022 Then
             db.Execute "UPDATE tblStandardwerte SET Standardwert = ''''" & varStandardwert & "'''' WHERE Formularname = ''''" _
                 & strFormularname & "'''' AND Steuerelementname = ''''" & strSteuerelementname & "''''", dbFailOnError
         End If
     Else
         db.Execute "INSERT INTO tblStandardwerte(Formularname, Steuerelementname, Standardwert) VALUES(''''" _
             & strFormularname & "'''', ''''" & strSteuerelementname & "'''', NULL)", dbFailOnError
         If Err.Number = 3022 Then
             db.Execute "UPDATE tblStandardwerte SET Standardwert = NULL WHERE Formularname = ''''" & strFormularname _
                 & "'''' AND Steuerelementname = ''''" & strSteuerelementname & "''''", dbFailOnError
         End If
     End If
End Sub

Listing 1: Prozedur zum Speichern von Standardwerten

Die Prozedur versucht, einen neuen Datensatz in der Tabelle tblStandardwerte anzulegen. Dabei sollen die mit den drei Parametern strFormularname, strSteuerelementname und varStandardwert übergebenen Werte in die drei Felder Formularname, Steuerelementname und Standardwert der Tabelle tblStandardwerte eingetragen werden. Für den dritten Parameter haben wir den Datentyp Variant gewählt, damit hier auch der Wert Null verarbeitet werden kann.

Da es beim Speichern geschehen kann, dass die Prozedur versucht, einen Datensatz mit einer bereits vorhandenen Kombination aus Formularname und Steuerelementname zu speichern, haben wir zuvor die eingebaute Fehlerbehandlung deaktiviert.

So meldet Access keinen Fehler, wenn das Anlegen des Datensatzes aus dem genannten Grund fehlschlägt. Stattdessen prüft die Prozedur anschließend, ob der Fehler mit der Nummer 3022 aufgetreten ist, was diesem Fehler entspricht. In diesem Fall soll die Prozedur dann den Wert des Feldes Standardwert in dem bereits vorhandenen Datensatz überschreiben.

Sollte varStandardwert leer sein, dann legt die Prozedur auch einen Datensatz in der Tabelle tblStandardwerte an beziehungsweise ändert den Standardwert für einen eventuell vorhandenen Datensatz für diese Konstellation aus Formularname und Steuerelementname. Allerdings trägt die Prozedur dann den Wert NULL für das Feld Standardwert ein.

In der Nach Aktualisierung-Ereignisprozedur des Formulars tragen wir dann etwa die folgende Zeile ein, um den aktuellen Wert des Feldes cboKategorieID in der Tabelle tblStandardwerte zu speichern:

Private Sub Form_AfterUpdate()
     StandardwertSpeichern Me.Name, "cboKategorieID", _
         Me!cboKategorieID
End Sub

Nachdem Sie nun einen Datensatz im Formular frmArtikel_Standardwerttabelle bearbeitet haben, speichert diese Prozedur den dabei verwendeten Wert für das Steuerelement cboKategorien wie in Bild 5 in der Tabelle tblStandardwerte.

Tabelle zum Speichern von Standardwerten, Datenblattansicht

Bild 5: Tabelle zum Speichern von Standardwerten, Datenblattansicht

Standardwerte wiederherstellen

Nun benötigen wir noch einen Algorithmus, der die Standardwerte wiederherstellt. Hier wollen wir nicht so kleinschrittig vorgehen und eine Prozedur bereitstellen, die für jeden vorzugebenden Wert erneut aufgerufen wird. Stattdessen wollen wir der zu erstellenden Prozedur nur noch den Namen des Formulars übergeben, dessen Standardwerte eingestellt werden sollen, den Rest soll die Prozedur anhand der für dieses Formular gespeicherten Werte erledigen.

Die dazu verwendete Prozedur finden Sie in Listing 2. Die Prozedur erwartet diesmal nicht den Namen des zu behandelnden Formulars, sondern gleich einen Verweis auf das Formular-Objekt selbst. Das hat den Hintergrund, dass wir in der Prozedur sowieso noch auf Elemente des Formulars zugreifen wollen – also können wir auch direkt den Objektverweis darauf übergeben. Die Prozedur öffnet ein Recordset auf Basis der Tabelle tblStandardwerte, wobei nur diejenigen Datensätze berücksichtigt werden, deren Formularname dem Namen des mit frm übergebenen Formulars entsprechen.

Public Sub StandardwerteSetzen(frm As Form)
     Dim db As DAO.Database
     Dim rst As DAO.Recordset
     Set db = CurrentDb
     Set rst = db.OpenRecordset("SELECT * FROM tblStandardwerte WHERE Formularname = ''''" & frm.Name & "''''", dbOpenDynaset)
     On Error Resume Next
     Do While Not rst.EOF
         frm.Controls(rst!Steuerelementname).DefaultValue = rst!Standardwert
         rst.MoveNext
     Loop
     On Error GoTo 0
End Sub

Listing 2: Prozedur zum Setzen von Standardwerten

Dies durchläuft die Prozedur in einer Schleife und trägt dabei für alle gefundenen Datensätze den im Feld Standardwert angegebenen Wert in das im Feld Steuerelementname gefundene Steuerelement ein. Diese Methode rufen wir nur dann auf, wenn der Benutzer einen neuen Datensatz anlegt. Dies fangen wir in der Ereignisprozedur ab, die durch das Ereignis Beim Anzeigen ausgelöst wird und die wie folgt aussieht:

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