E-Mail-Adressen validieren per VBA

Immer mehr Vorgänge werden per E-Mail verarbeitet. Dazu gehören auch Bestellungen, Rechnungen et cetera. Früher wurden beispielsweise Rechnungen an die Postadresse geschickt, was einigermaßen fehlertolerant war. Spätestens der Briefträger hat die falsche Hausnummer erkannt und die Sendung dank regelmäßigem Zustellungsgebiet beim richtigen Adressaten abgeliefert. Bei E-Mails verhält sich dies völlig anders: Hier führt jede Ungenauigkeit zur Unzustellbarkeit, toleriert werden allenfalls noch Abweichungen bei der Groß-/Kleinschreibung. Daher lohnt es sich, die E-Mail-Adressen von Kunden und anderen Adressaten zumindest oberflächlich zu prüfen.

Aufbau einer E-Mail-Adresse

Als Erstes unterteilen wir eine E-Mail-Adresse grob in den Teil vor dem @-Zeichen und dahinter. Davor finden wir den sogenannten Lokalteil, dahinter die Domain des E-Mail-Providers.

Schauen wir uns zuerst die Domain an. Diese besteht wiederum aus drei Teilen: dem Hostnamen, einem Punkt und der Top-Level-Domain. Da es immer mehr Top-Level-Domains gibt, wird es schwierig, diese konkret auf Gültigkeit zu prüfen. Auch die Anzahl der Zeichen wurde im Laufe der Zeit immer mehr ausgeweitet. Früher gab es nur Top-Level-Domains mit zwei oder drei Buchstaben (wie de oder com), mittlerweile finden wir auch solche mit mehr Buchstaben.

Der Teil vor dem @-Zeichen heißt Lokalteil und kann je Domain nur einmal vergeben werden. Er kann die folgenden Zeichen verwenden:

A-Za-z0-9.!#$%&''*+-/=?^_''{|}~

Allerdings finden wir in der Regel nur Buchstaben, Zahlen und den Punkt vor. Dennoch können wir die möglichen Zeichen in die Prüfung mit einbeziehen.

Möglichkeiten für die Prüfung

Wir können verschiedene Techniken für die Prüfung von E-Mail-Adressen einsetzen. Wenn wir nur eine grundlegende Prüfung vornehmen wollen, kommen wir mit den Zeichenkettenfunktionen von VBA aus. Für eine weitergehende Prüfung ist auch die Nutzung von regulären Ausdrücken möglich. Dazu benötigen wir jedoch bereits eine zusätzliche Bibliothek. Diese beiden Methoden erlauben jedoch nur die Prüfung der Syntax der E-Mail-Adresse.

Wenn Sie sicherstellen wollen, dass die E-Mail auch beim Empfänger ankommt, können Sie einen der zahlreichen Onlinedienste beanspruchen. Diese sind jedoch meist kostenpflichtig oder bieten keinen Webservice an, mit dem wir diese nutzen können.

Grundlegende Prüfung

Die grundlegendste Prüfung kontrolliert schlicht, ob die E-Mail-Adresse bestimmte Elemente und keine unerlaubten Sonderzeichen enthält.

Diese wollen wir nun per VBA programmieren. Die dazu notwendige Funktion soll CheckEMailSyntax heißen und die zu prüfende E-Mail-Adresse als Parameter entgegennehmen. Das Ergebnis soll ein Boolean-Wert sein, der im Falle einer gültigen E-Mail-Adresse den Wert True enthält. Diese definieren wir zunächst wie folgt:

Public Function CheckEMailSyntax(strEMail As String) As Boolean
End Function

Nun wollen wir ein paar Testfälle mit vorgegebenen Ergebnissen definieren, mit denen wir die Funktion direkt während der Entwicklung testen können. Dazu verwenden wir zwei verschiedene Prozeduren.

Die erste ruft die eigentliche Testprozedur auf und übergibt dieser jeweils die zu untersuchende E-Mail-Adresse und die Angabe, ob diese gültig ist oder nicht. Hier sind die Aufrufe mit einigen Test-Adressen:

Public Sub Test()
     Test_CheckEMailSyntax "andre@minhorst.com", True
     Test_CheckEMailSyntax "andre@minhorst,com", False
     Test_CheckEMailSyntax "andreQminhorst.com", False
     Test_CheckEMailSyntax "andre@minhorst.de", True
     Test_CheckEMailSyntax "@minhorst.de", False
     Test_CheckEMailSyntax "andre@.de", False
     Test_CheckEMailSyntax "andre@minhorst.", False
     Test_CheckEMailSyntax "andre@minhorst@de", False
End Sub

Die zweite Prozedur führt den Testaufruf aus und gleicht das Ergebnis mit dem erwarteten Ergebnis ab. Liefert der Test das erwartete Ergebnis, erscheint eine Zeile im Direktbereich, die auf den erfolgreichen Test verweist.

Anderenfalls wird der fehlgeschlagene Test gemeldet (siehe Listing 1).

Public Sub Test_CheckEMailSyntax(strEMail As String, bolResult As Boolean)
     If CheckEMailSyntax(strEMail) = bolResult Then
         Debug.Print "Test mit ''" & strEMail & "'' erfolgreich"
     Else
         Debug.Print "Test mit ''" & strEMail & "'' fehlgeschlagen"
     End If
End Sub

Listing 1: Eigentliche Testprozedur

Mit den obigen Tests sieht das Ergebnis wie folgt aus:

Test mit ''andre@minhorst.com'' erfolgreich
Test mit ''andre@minhorst,com'' erfolgreich
Test mit ''andreQminhorst.com'' erfolgreich
Test mit ''andre@minhorst.de'' erfolgreich
Test mit ''@minhorst.de'' fehlgeschlagen
Test mit ''andre@.de'' fehlgeschlagen
Test mit ''andre@minhorst.'' fehlgeschlagen
Test mit ''andre@minhorst@de'' erfolgreich

Zufälligerweise liefert die Funktion mit dem Wert False in einigen Fällen das richtige Ergebnis, was sich aber gleich relativieren wird.

Als Erstes wollen wir prüfen, ob ein @-Zeichen in der E-Mail enthalten ist. Dazu erweitern wir die Funktion wie folgt:

Public Function CheckEMailSyntax(strEMail As String)  As Boolean
     If InStr(1, strEMail, "@") = 0 Then
         CheckEMailSyntax = False
         Exit Function
     End If
     ''...
     ''weitere Prüfungen
     ''...
     CheckEMailSyntax = True
End Function

Hier prüfen wir mit der InStr-Funktion, ob in strEMail überhaupt ein @-Zeichen enthalten ist. Rufen wir die Test-Prozedur erneut auf, liefern nun andere Tests ein positives Ergebnis. Wenn die Bedingung falsch ist, also die Funktion nicht über Exit Function verlassen wird, gibt die Funktion den Wert True zurück.

Aber die Prüfung ist nicht ganz korrekt, denn es soll nicht nur überhaupt ein @-Zeichen enthalten sein, sondern genau eines. Wie können wir prüfen, ob genau ein @-Zeichen vorhanden ist? Wir ersetzen dieses durch eine leere Zeichenkette und vergleichen dann die Länge mit der Länge des Originals. Der durch die folgende Bedingung ermittelte Unterschied muss 1 sein:

If Not Len(strEMail) - Len(Replace(strEMail, "@", ""))  = 1 Then
     CheckEMailSyntax = False
     Exit Function
End If

Als Nächstes fügen wir eine Bedingung hinzu, die auf das Vorhandensein des Punkts prüft. Im Gegensatz zum @-Zeichen kann die E-Mail-Adresse auch mehrere Punkte enthalten, wie zum Beispiel in andre.minhorst@t-online.de. Allerdings darf nur ein Punkt hinter dem @-Zeichen auftauchen. Wir schauen uns also nur den Teil hinter dem @-Zeichen an.

Dazu deklarieren wir eine Variable namens strDomain und fügen den Teil hinter dem @-Zeichen in diese Variable ein:

Dim strDomain As String
...
strDomain = Mid(strEMail, InStr(1, strEMail, "@") + 1)

Danach führen wir für strDomain und den Punkt die gleiche Prüfung wie oben für strEMail und das @-Zeichen durch und prüfen so, ob genau ein Punkt in strDomain enthalten ist:

If Not Len(strDomain) - Len(Replace(strDomain, ".", ""))  = 1 Then
     CheckEMailSyntax = False
     Exit Function
End If

Damit gelingen schon einmal die ersten vier Tests, also schauen wir uns an, was wir noch nicht berücksichtigt haben, dass der fünfte Test fehlschlägt. Hier testen wir auf @minhorst.com, was das Ergebnis False liefern sollte, aber die Prozedur liefert das Ergebnis True.

Wir müssen also vor dem @-Zeichen noch mindestens ein weiteres Zeichen vorfinden. Dazu lesen wir den Teil vor dem @-Zeichen in die Variable strLocal ein:

Dim strLocal As String
...
strLocal = Left(strEMail, InStr(1, strEMail, "@") - 1)

Danach können wir zunächst einmal prüfen, ob strLocal mindestens die Länge 1 aufweist:

If Len(strLocal) = 0 Then
     CheckEMailSyntax = False
     Exit Function
End If

Damit kommen wir zum nächsten Test, der fehlschlägt: andre@.de liefert einen Fehler. Logisch: Hier fehlt der Hostname, also der Teil vor dem Punkt. Also nutzen wir zwei weitere Variablen, in denen wir den Hostnamen und die Top Level Domain speichern:

Dim strHostname As String
Dim strTLD As String

Diese ermitteln wir aus strDomain – für den Hostnamen bis zum ersten Punkt von hinten, für die Top Level Domain vom ersten Punkt von hinten an:

strHostname = Left(strDomain, InStrRev(strDomain, ".") - 1)
strTLD = Mid(strDomain, InStrRev(strDomain, ".") + 1)

Die Prüfung, ob ein Hostname enthalten ist, sieht so aus:

If Len(strHostname) = 0 Then
     CheckEMailSyntax = False
     Exit Function
End If

Und auf die Gültigkeit der Top Level Domain, also dem hinteren Teil, testen wir so:

If Len(strTLD) = 0 Then
     CheckEMailSyntax = False
     Exit Function
End If

Damit sind nun alle Tests erfolgreich. Also können wir ein paar weitere Hürden in Form neuer Tests einbauen.

Lokalteil auf ungültige Zeichen prüfen

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