Home > Artikel > Ausgabe 1/2016 > Alles plausibel

Alles plausibel?

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Fehleingaben in Datenbanken sind, nach eigener Erfahrung, ein Quell ständiger Reibereien in Unternehmen. Oft sind die Daten redundant, mangelhaft formatiert oder lückenhaft. Nachforschungen, wer nun dies oder jenes falsch gemacht habe, führen selten zu effizienterer Arbeitsatmosphäre. Dabei könnten doch Plausibilitätsprüfungen schon bei der Eingabe in Formulare einen großen Teil dieses Missstands beheben. Wir zeigen Ihnen einige Beispiele.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1602_Plausibel.accdb

Plausible Kunden

Anhand der schon in der Ausgabe 11/2015 vorgestellten Beispieldatenbank mit ihrem Kunden- und Bestellformular demonstrieren wir Ihnen die möglichen Fallstricke und zeigen Lösungsmöglichkeiten auf. Das Formular frmKunden wurde dafür mit zusätzlichem VBA-Code aufgerüstet, der die Plausibilitätsprüfung der Eingabefelder garantieren soll.

Ein immer wiederkehrender Vorgang ist die Neuanlage von Adressen, die bereits in der Datenbank vorhanden sind. Oft wird dies zu spät bemerkt, etwa dann, wenn an anderer Stelle auf die Adressen Bezug genommen und eine Verknüpfung mit anderen Daten hergestellt werden soll. Welche Adresse ist dann die richtige? Besser, Sie bauen da eine Prüfung ein, ob etwa die Kombination von Nachname und Vorname schon existiert, um dem Anwender gegebenenfalls eine Meldung zu präsentieren, wie in Bild 1. Er hat dann die Möglichkeit, die Eingabe dennoch fortzusetzen – Namen sind ja tatsächlich nicht immer eindeutig –, oder er navigiert zur bereits vorliegenden Adresse, weil er diese übersah.

Das Kundenformular der Beispieldatenbank implementiert diverse Plausibilitätsprüfungen

Bild 1: Das Kundenformular der Beispieldatenbank implementiert diverse Plausibilitätsprüfungen

Was hin und wieder ebenfalls passiert, ist die Eingabe überflüssiger Leerzeichen. So wird versehentlich ein Leerzeichen an den Anfang des Nachnamens gesetzt was zu "Aber, Jutta" und " Abel, Jutta" führt. In einer sortierten Adressliste bemerkte man die Doppelung gar nicht, weil der String mit dem Leerzeichen die Adresse ganz nach vor setzte. Bauen Sie eine Eliminierung überflüssiger Leerzeichen ein, so ist derartigem Unbill vorgesorgt.

Schlecht macht sich auch, wenn eine Auslieferung an den falschen Adressaten gerät, weil Ort und Postleitzahl nicht zueinander passen. Verknüpfen Sie beide miteinander über eine interne Postleitzahlentabelle, so können Sie auf Falschangaben reagieren und Korrekturen vorschlagen lassen.

Und schließlich sind E-Mail-Adressen heutzutage genauso wichtig, wie die örtlichen Angaben. E-Mails, die den Adressaten nicht erreichen, haben Verzögerungen im Workflow zur Folge. Fehler infolge inkorrekter E-Mail-Eingaben können Sie wenigstens minimieren, indem die Eingabe einer Validitätsprüfung unterzogen wird.

Formularnavigation

Bevor wir zum eigentlichen Thema kommen, beschreiben wir noch eine Erweiterung der Navigationsmöglichkeiten des Formulars. Da es keine Navigationsleiste anzeigt, muss zu einem Kunden über das Kombinationsfeld Gehe zu gesprungen werden. In der bisherigen Form enthält diese Combobox eine Liste aller eingegebenen Kunden. Dabei fehlt die Möglichkeit, einen Kunden zu löschen oder neu anzulegen. Zwar könnten Sie zu diesem Zweck zusätzliche Schaltflächen Löschen und Neu in das Formular einfügen, doch auch das Kombinationsfeld macht's möglich!

Die Steuerelementdaten bestanden bislang ungefähr aus dem SQL-Ausdruck

SELECT Nachname & ", " & Vorname

FROM tblKunden ORDER BY Nachname

Was wir möchten, sind die zwei zusätzlichen Einträge Neuer Kunde und Kunde löschen ganz oben in der Liste, so, wie dies Bild 2 zeigt. Da diese in der Tabelle tblKunden nicht existieren, müssen sie künstlich eingebaut werden. Dazu eignet sich in erster Linie eine Union-Abfrage. Für die Combobox sieht der SQL-Ausdruck nun so aus:

Die Combobox mit ihren zwei zusätzlichen Einträgen zum Neuanlegen und Löschen von Kunden

Bild 2: Die Combobox mit ihren zwei zusätzlichen Einträgen zum Neuanlegen und Löschen von Kunden

(SELECT -1 AS ID, "(Kunden löschen)"

          AS Vollname FROM tblKunden)

UNION

(SELECT 0 AS ID, " (Neuer Kunde)"

          AS Vollname FROM tblKunden)

UNION

(SELECT tblKunden.ID, [Nachname] & ", " & [Vorname]

          AS Vollname FROM tblKunden)

ORDER BY Vollname;

Erstaunlich, aber wahr: Nicht nur zwei, sondern auch mehrere SELECT-Abfragen können über die UNION-Klausel miteinander kombiniert werden! Die eigentliche Abfrage steht ganz unten, wobei die Kombination aus Nach- und Vorname über den Feld-Alias Vollname ausgegeben wird. Damit die Einzelabfragen zusammengefasst werden können, müssen sie die gleiche Zahl von Feldern und die gleichen Feldnamen ausgeben. Das erste SELECT-Statement setzt nun einfach den Wert -1 als ID und den Vollnamen auf (Kunden löschen). Als Tabelle im FROM-Teil wird ebenfalls tblKunden spezifiziert. Das ist aber völlig ohne Belang! Sie könnten hier genauso gut eine andere Tabelle einsetzen, weil auf deren Datensätze ja ohnehin nicht Bezug genommen wird. Nur ohne Tabelle geht es leider nicht. Von der Performance her ist es günstiger, die gleiche Tabelle zu verwenden, auf die im unteren Teil tatsächlich zugegriffen wird.

Der Inhalt der zweiten Klammer ist identisch aufgebaut. Hier steht die ID 0 für den Eintrag (Neuer Kunde). Davor steht, wohlgemerkt, ein Leerzeichen! Das führt dazu, dass dieser Eintrag infolge der abschließenden aufsteigenden Sortierung über alle Datensätze in der ORDER BY-Klausel ganz oben steht.

Die Ereignisprozedur für das Kombinationsfeld cbFind ist nun natürlich entsprechend anzupassen. Im Ereignis Nach Aktualisierung kommt es zur Ausführung der Prozedur in Listing 1. Je nach Wert (cbFind.Value) des Kombinationsfelds verzweigt der Select-Case-Block in unterschiedliche Aktionen. Wurde etwa Neuer Kunde ausgewählt, so ist der Wert von cbFind 0, was die DoCmd-Anweisung GotoRecord mit dem Parameter für einen neuen Datensatz auslöst. Ähnlich bei -1 für Kunde löschen, was den aktuellen Datensatz über die RunCommand-Anweisung löschen würde. Konjunktiv deshalb, weil davor noch eine Sicherheitsabfrage über eine Messagebox gestellt ist, die den Anwender auf den folgenden prekären Vorgang hinweist. Für alle anderen Werte von cbFind kommt es zum unteren Else-Teil des Blocks, der das Formular-Recordset auf die gewünschte ID einstellt und damit den Sprung zum entsprechenden Kunden im Formular erwirkt.

Private Sub cbFind_AfterUpdate()

     On Error Resume Next

     Select Case Me!cbFind.Value

     Case 0

         DoCmd.GoToRecord acDataForm, Me.Name, acNewRec

     Case -1

         If MsgBox("Diesen Kunden wirklich löschen?", _

             vbYesNo Or vbExclamation, "Bestätigen:") = vbYes Then

                RunCommand acCmdDeleteRecord

                Me!cbFind.Requery

         End If

     Case Else

         Me.Recordset.FindFirst "ID=" & Me!cbFind.Value

     End Select

End Sub

Listing 1: Das aktualisierte Kombinationsfeld cbFind lässt durch den Select Case-Zweig unterschiedliche Aktionen folgen

Unerwünschte Leerzeichen

Der einfachste Teil der Plausibilitätsprüfungen ist das Entfernen vor- und nachstehender Leerzeichen. Wird im Eingabefeld für den Nachnamen ein Name eingeben und ein versehentliches Leerzeichen vorangestellt, so entfernt die Ereignisprozedur Nach Aktualisierung des Felds dieses über die Trim-Funktion sogleich:

Private Sub txtNachname_AfterUpdate()

     Me!txtNachname.Value = _

            Trim(Me!txtNachname.Value)

End Sub

Dies geschieht also unmittelbar nach dem Verlassen des Textfelds. Der Anwender hat gar keine Möglichkeit, ein Leerzeichen hineinzuschummeln.

Auf gleiche Weise wird mit dem Vorname-Feld verfahren.

Stimmige E-Mail-Adresse

Wird das Eingabefeld für die E-Mail-Adresse verlassen, so löst dies seine AfterUpdate-Prozedur aus, wie in Listing 2. Hier kann die Adresse auf Validität getestet werden. Die Adresse wird zunächst der Variablen sMail zugewiesen. Die Nz-Funktion stellt dabei sicher, dass es bei geleertem Feld nicht zu einer Fehlermeldung kommt, weil dann der Feldwert nicht ein String, sondern Null wäre. In diesem Fall ist die Länge des String in sMail gleich 0, was zum Verlassen der Prozedur führt.

Private Sub txtEmail_AfterUpdate()

     Dim sMail As String

     

     sMail = Nz(Me!txtEmail.Value)

     If Len(sMail) = 0 Then Exit Sub

     If IsEmailValid(sMail) Then Exit Sub

     MsgBox "Die angegebene E-Mail-Adresse ist nicht korrekt!", _

                                                          vbExclamation

     Me!txtEmail.SetFocus

End Sub

Listing 2: Überprüfung der E-Mail-Adresse auf Gültigkeit

Erst anschließend ruft die Prozedur die Funktion IsEmailValid auf, welche im Modul mdlEmail steht, und verlässt die Routine ebenfalls, falls der Rückgabewert auf True steht. Andernfalls weist eine Meldung den Anwender darauf hin, dass die Adresse zu korrigieren wäre (Bild 3).

Meldung bei falscher E-Mail-Adresse

Bild 3: Meldung bei falscher E-Mail-Adresse

Die separate Funktion IsEmailValid finden Sie in Listing 3. Sie erzeugt über CreateObject erst ein ActiveX-Objekt des Typs VBScript.RegExp. Dieses Objekt ist Bestandteil von Windows und ermöglicht die Auswertung sogenannter Regulärer Ausdrücke. Ein Verweis auf die Bibliothek braucht auf diese Weise nicht gesetzt zu werden. Das Kernelement des Objekts ist seine Eigenschaft Pattern. Die Wirkungsweise des undurchsichtigen String-Ausdrucks zu erläutern, wäre an dieser Stelle zuviel des Guten. Erwähnt sei lediglich, dass er eine E-Mail-Adresse auf verschiedene Aspekte hin durchleuchtet.

Function IsEmailValid(sEmail As String) As Boolean

     Dim objRegExp As Object

     

     Set objRegExp = CreateObject("VBScript.RegExp")

     With objRegExp

         .IgnoreCase = True

         .Global = True

         .Pattern = "^([a-zA-Z0-9_\-\.]+)@[a-z0-9-]" & _

             "+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$"

         IsEmailValid = .Test(sEmail)

     End With

End Function

Listing 3: Ein regulärer Ausdruck dient als Hilfsmittel zur E-Mail-Prüfung in der Funktion IsValidEmail

Das @-Zeichen etwa muss vorkommen, ein Punkt für die Domain-Erweiterung ebenfalls, die Länge darf nicht zu kurz sein, nur Zahlen und Buchstaben sind erlaubt. Nach Absetzen seiner Methode Test gibt das Objekt entweder True oder False zurück, je nachdem, ob die Pattern-Bedingung erfüllt ist.

Fehlende Angaben

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!