Validieren mit Klasse

Das Validieren von Daten in Formularen ist normalerweise eine langweilige Arbeit, die man gewöhnlich an das Ende der Formularentwicklung packt. Die Anzahl der möglichen Fälle, die durch eine Validierung abgefangen werden sollen, ist überschaubar und die nötigen Codezeilen sehen sich meist sehr ähnlich: Prüfen, Fokus auf das Feld setzen, Aktualisierung abbrechen, Meldung ausgeben. Mit ein paar einfachen Klassen lässt sich diese Arbeit ein wenig spannender gestalten und am Ende sparen Sie sogar noch Code und somit Zeit.

Welche Fälle treten bei der Validierung der Steuerelemente von Formularen auf Der einfachste ist wohl der, bei dem ein Feld unabhängig von allen anderen nur bestimmte Werte annehmen kann.

Teilweise werden die dazu notwendigen Regeln möglicherweise schon im Tabellenentwurf festgelegt, teilweise müssen Sie sich selbst darum kümmern.

Gleiches gilt für Felder, deren Wertebereich durch ein oder mehrere weitere Felder eingeschränkt wird – zum Beispiel sollte ein Feld namens Startdatum keinen Wert aufnehmen, der im Kalender hinter dem Wert des Feldes Enddatum liegt.

Hier fällt die Prüfung schon ein wenig umfangreicher aus: Es reicht ja nicht, einfach nur den Inhalt der beiden Felder zu vergleichen; gleichzeitig ist auch noch zu prüfen, ob das jeweils andere Feld überhaupt einen Wert aufweist.

Überhaupt stellt sich die Frage, wann der richtige Zeitpunkt für die Validierung ist: Direkt nach der Eingabe eines Wertes in ein Feld oder doch erst beim Klicken auf die OK– oder Speichern-Schaltfläche

Ersteres würde die Prüfung in das Vor Aktualisierung-Ereignis des Steuerelements verlegen, Letzteres betrifft die Ereignisprozedur gleichen Namens des Formulars selbst.

Ein Beispiel für die Validierung eines Textfelds, das nicht Null sein darf, sieht etwa wie folgt aus:

Private Sub txt_BeforeUpdate(Cancel As Integer)
    If IsNull(Me!txt) Then
        MsgBox "Bitte geben Sie einen Wert ein."
        Cancel = True
    End If
    End Sub

Dieses Ereignis wird gleich beim Verlassen des geänderten Feldes ausgelöst. Die Alternative zum Validieren des Feldes vor dem Speichern des kompletten Datensatzes sieht fast genau so aus – mit dem feinen Unterschied, dass das Ereignis nicht zu einem Steuerelement gehört, sondern durch das Formular selbst ausgelöst wird:

Private Sub Form_BeforeUpdate(Cancel As Integer)
    If IsNull(Me!txt) Then
        MsgBox "Bitte geben Sie einen Wert ein."
        Me!txt.SetFocus
        Cancel = True
    End If
    End Sub

Deshalb ist hier auch noch eine zusätzliche Zeile nötig, die den Fokus beim Fehlschlagen der Validierung auf das Feld mit den ungültigen Daten setzt.

Validierungsregeln auf Tabellenebene

Neben den manuell hinzugefügten Validierungsmechanismen wie aus dem obigen Beispiel gibt es einige Validierungen, die Access automatisch durchführt.

Diese hängen meist vom Datentyp ab: So können Sie für ein Datumsfeld nur gültige Datumsangaben speichern und ein Zahlenfeld kann nur Zahlen, aber keine Buchstaben aufnehmen. Diese und ähnliche Verfehlungen würden einen Fehler auf Formularebene auslösen.

Beim Einfügen einer Zeichenkette in ein Zahlenfeld würde beispielsweise die Fehlermeldung Sie haben einen Wert eingegeben, der für dieses Feld nicht gültig ist auftreten.

Mit der BeforeUpdate-Ereignisprozedur kommen Sie dieser Meldung nicht bei: Das Ereignis feuert erst nach dem Erscheinen der Fehlermeldung. Die einzige Möglichkeit, diese Meldung zu verhindern, ist das Formularereignis Bei Fehler, für das Sie beispielsweise die folgende Routine anlegen können:

Private Sub Form_Error(DataErr As Integer, _
    Response As Integer)
    MsgBox "Formularfehler " & DataErr
    Response = acDataErrContinue
    End Sub

DataErr liefert die gleiche Fehlernummer, wie Err.Number bei einer herkömmlichen Fehlerbehandlung. Der Rückgabewert acDataErrContinue für den Parameter Response sorgt dafür, dass Access seine Meldung nicht mehr anzeigt.

Prinzipiell entspricht die Wirkung unserer weiter oben vorgestellten Routine, die durch das Ereignis Vor Aktualisierung ausgelöst wird: Es erscheint eine Meldung, der Inhalt bleibt stehen und das Feld kann nicht verlassen werden.

Welche Steuerelemente werden validiert

Die wichtigsten Kandidaten für eine Validierung sind Textfelder. Hier finden Sie sicher Kandidaten, für die Sie eine Validierung festlegen müssen, allein weil ihr Datentyp wie Datum/Zeit oder Zahl eine Validierung nötig macht.

Daneben gibt es natürlich noch einige Validierungen, die für die Einhaltung der Geschäftsregeln nötig sind: Ist Datum A kleiner als Datum B Hat Zeichenkette XYZ die richtige Anzahl Zeichen Hier dreht es sich meist um Daten, die über Textfelder eingegeben werden. Daneben sind noch Kombinationsfelder, Listenfelder, Kontrollkästchen, Optionsgruppen und Umschaltflächen interessant – andere Steuerelemente bleiben im Kontext dieses Beitrags außen vor.

Validierung ganz einfach

Die Lösung dieses Beitrags liefert ein paar Objekte, die Sie einfach in eine Datenbank einlesen müssen, die Sie mit einer Validierungsfunktion versehen möchten. Das geht ganz schnell:

  • Öffnen Sie die Zieldatenbank.
  • Betätigen Sie den Menübefehl Datei|Externe Daten|Importieren und wählen Sie im folgenden Dialog die Beispieldatenbank dieses Beitrags aus.
  • Es erscheint der Dialog Objekte importieren, über den Sie die benötigten Objekte markieren und den Import mit einem Klick auf OK starten.

Sie brauchen die folgenden Objekte:

  • Standardmodule mdlGlobal und mdlValidation
  • Klassenmodule clsControlValidation, clsFormValidation und clsValidation

Legen Sie dann ein Beispielformular an, weisen Sie diesem eine Tabelle mit Feldern unterschiedlicher Datentypen zu (zum Beispiel die Tabelle tblPersonal aus der Südwind-Datenbank, einer modifizierten Version der Nordwind-Datenbank) und ziehen Sie die Felder in die Entwurfsansicht eines neuen Formulars, das in diesem Beispiel den Namen frmBeispielValidierung trägt.

Erstellen Sie dann ein Klassenmodul für dieses Formular, indem Sie die Formulareigenschaft Enthält Modul auf Ja einstellen. Wechseln Sie dann mit der Tastenkombination Alt + F11 zum VBA-Editor und klicken Sie dort im Projektexplorer (falls nicht sichtbar, mit Strg + R einblenden) doppelt auf den neuen Eintrag Form_frmBeispielValidierung.

Es erscheint ein neues, leeres Codefenster. Fügen Sie dort die folgende Deklaration ein (siehe (auch Bild 1)):

pic001.png

Bild 2: Das Beispielformular in der Entwurfsansicht

Dim objValidation As clsValidation

Schauen wir uns das Formular an, das nach dem Anlegen einer OK-Schaltfläche wie in Bild 2 aussieht. Wir verwenden das Feld Nachname für ein erstes Experiment. Damit die Validierung funktioniert, muss das oben deklarierte Objekt objValidation des Typs clsValidation instanziert werden. Der richtige Zeitpunkt hierfür ist das Laden des Formulars und somit das Ereignis Beim Laden. Dieses legen Sie direkt im VBA-Editor an, indem Sie aus dem linken Kombinationsfeld des Codefensters für das Klassenformular Form_frmValidierungBeispiel den Eintrag Form auswählen. Es erscheint automatisch eine Ereignisprozedur namens Form_Load (siehe Bild 3).

pic002.png

Bild 1: Der VBA-Editor mit der Deklaration der Validierungsklasse im Klassenmodul des Zielformulars

pic003.png

Bild 3: Die automatisch angelegte Ereignisprozedur Form_Load

Diese ergänzen Sie zunächst um folgende Anweisung, um das Objekt objValidation zu instanzieren:

Set objValidation = New clsValidation

Die Klasse objValidation bietet vor allem zwei Methoden, aber auch noch einige Eigenschaften, auf die Sie leicht über IntelliSense zugreifen können (siehe Bild 4). Die erste heißt AddControlValidation und erlaubt das Anlegen von Validierungen, die direkt nach dem ändern des Steuerelementinhalts ausgelöst werden.

pic005.png

Bild 4: Hinzufügen einer Methode zum Anlegen einer Validierung per IntelliSense

Die zweite heißt AddFormValidation und bezieht sich ebenfalls auf ein Steuerelement, wird aber erst kurz vor dem Speichern des Datensatzes ausgelöst. Beide Methoden haben die gleiche Syntax und erwarten die folgenden Parameter (siehe (auch Bild 5)):

pic004.png

Bild 5: Die Parameter der Anweisung zum Anlegen einer Validierung

  • ctl: Verweis auf das Steuerelement, das die Validierung auslöst
  • eType: Typ der Validierung, festgelegt in der Enumeration eValidationType. Mögliche Werte siehe weiter unten.
  • strTitle: Zeichenkette, die beim Fehlschlagen der Validierung als Titel des Meldungsfensters angezeigt werden soll.
  • strMessage: Zeichenkette, die beim Fehlschlagen der Validierung als Text des Meldungsfensters angezeigt werden soll.
  • strExpression: Optionale Zeichenkette, die einen auswertbaren Ausdruck enthält. Liefert dieser Ausdruck den Wert False, ist die Validierung fehlgeschlagen.

Für den mit dem Parameter eType übergebenen Validierungstyp stehen diese Werte parat:

  • eIsNumeric: Prüft, ob der neue Wert ein numerischer Wert ist.
  • eIsNull: Prüft, ob der neue Wert Null ist.
  • eIsDate: Prüft, ob der neue Wert ein gültiges Datum enthält.
  • eIsNullstring: Prüft, ob der neue Wert eine leere Zeichenkette ist.
  • eIsTrue: Prüft, ob der neue Wert wahr ist.
  • eIsFalse: Prüft, ob der neue Wert falsch ist.
  • eExpression: Legt fest, dass der im Parameter strExpression angegebene Ausdruck das Ergebnis der Validierung liefert.

Nehmen wir an, das Feld PLZ darf nur numerische Wert enthalten.

Dann brauchen Sie die folgende Anweisung in der Ereignisprozedur Form_Load, um eine entsprechende Validierung hinzuzufügen:

objValidation.AddControlValidation Me!PLZ,
eIsNumeric, "Ungültige PLZ", "Bitte geben
Sie eine aus vier oder fünf Ziffern
bestehende PLZ ein."

Öffnen Sie das Formular in der Entwurfsansicht und probieren Sie es aus: Geben Sie beispielsweise einige Buchstaben oder eine Postleitzahl in der Form D-47137 in das Feld PLZ ein. Bild 6 zeigt, wie das Ergebnis ausfallen wird.

pic006.png

Bild 6: Eine erste Beispielvalidierung – erstellt mit nur einer Codezeile!

Klicken Sie auf OK, verbleibt die Einfügemarke im soeben bearbeiteten Feld und wird sich nicht in ein anderes Feld bewegen lassen, bis der Benutzer einen gültigen Wert eingegeben oder die änderung mit der Escape-Taste rückgängig gemacht hat. Letzteres ist wichtig für das Handling: Die Validierung auf Steuerelementbasis (erstellt mit AddControlValidation) arbeitet nur mit gebundenen Feldern und auch nur dann, wenn der Benutzer das jeweilige Feld seit dem Öffnen des Datensatzes geändert hat. In allen anderen Fällen bleibt die Validierung aus.

Validierung auf Formularebene

Bevor wir uns den übrigen Varianten zuwenden, schauen wir uns die Validierung auf Formularebene an – und zwar am gleichen Beispiel, damit Sie die Unterschiede erkennen können. Wir verwenden also nun die folgende Anweisung, um die gewünschte Validierung zu implementieren:

objValidation.AddFormValidation Me!PLZ,
eIsNumeric, "Ungültige PLZ", "Bitte geben Sie eine aus vier oder fünf Ziffern bestehende PLZ ein."

Vorab der Hinweis für schreibfaule Programmierer: Wenn Sie ein Steuerelement auf Steuerelement- und auf Formularebene validieren möchten, brauchen Sie einfach nur eine der beiden Methoden AddControlValidation oder AddFormValidation auszuformulieren, diese zu kopieren und den Methodennamen auszutauschen.

Wie wirkt diese Validierung nun Es gilt das Gleiche wie bei der Validierung auf Feldebene: Ohne eine änderung der Daten tut sich gar nichts. Hier braucht der Benutzer jedoch nur irgendeinen Feldinhalt zu ändern, damit sich die Validierung vor dem Speichern des Datensatzes einschaltet.

Wer beide Validierungen definiert hat und nun das Verhalten der Variante auf Formularebene testen möchte, wird feststellen, dass dies nicht funktioniert: Die änderung der PLZ, die wir auf Formularebene validieren lassen möchten, kann gar nicht erfolgen, weil die Validierung auf Feldebene vorher zuschlägt und Werte wie D-47137 erfolgreich unterbindet. Also kommentieren wir die AddControlValidation-Zeile einfach aus und testen dann erneut die Validierung auf Formularebene.

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