Textfeld nur mit bestimmten Zeichen füllen

Manche Felder in Tabellen dürfen nur bestimmte Zeichen aufnehmen. So soll beispielsweise eine Postleitzahl nur aus Zahlen bestehen, Namen sollen keine Zahlen enthalten, Telefonnummern nur Zahlen und bestimmte Zeichen wie Plus, Minus und Klammern. Um dies durchzusetzen, gibt es verschiedene Möglichkeiten. Die einfachste ist, nach der Eingabe zu prüfen, ob das Feld nur die zulässigen Zeichen enthält und den Benutzer darauf hinzuweisen. Man könnte aber auch direkt bei der Eingabe nur die zulässigen Zeichen akzeptieren. Dabei gibt es jedoch einige Fallstricke. In diesem Beitrag schauen wir uns die verschiedenen Möglichkeiten an.

Prüfung nach der Eingabe

Die einfachste Variante ist wohl die, direkt nach der Eingabe zu prüfen, ob der Text nicht erlaubte Zeichen enthält. Dazu müssen wir zunächst einmal definieren, welche Zeichen erlaubt sind und welche nicht. Ein einfaches Beispiel ist die Postleitzahl. Sie darf nur Zahlen enthalten, was leicht zu erreichen wäre, wenn man das Feld, an das man das Textfeld zur Eingabe bindet, direkt als Zahlenfeld definieren würde.

Postleitzahlen enthalten aber auch mal führende Nullen, und die werden eben nur bei Verwendung eines Felddatentyps wie Kurzer Text gespeichert. Es geht zwar auch mit einem Zahlenfeld und bestimmten Formatierungen, aber spätestens beim Export in eine Textdatei, etwa zum Übergeben von Adressen, werden standardmäßig nur die tatsächlich gespeicherten Werte übergeben.

Wir haben eine kleine Tabelle namens tblBeispielfelder erstellt, die drei Felder namens PLZ, Telefon und EMail für uns als Spielmaterial enthält. Diese binden wir über die Eigenschaft Datensatzquelle an ein neues Formular.

Wir definieren als Erstes eine Konstante, die alle zulässigen Zeichen enthält:

Const cStrZahlen As String = "0123456789"

Dann hinterlegen wir für das Ereignis Vor Aktualisierung des Textfeldes txtPLZ, das an das Feld PLZ gebunden ist, die Ereignisprozedur aus Listing 1. Diese liest den Inhalt des Textfeldes txtPLZ in die Variable strPLZ ein und ersetzt einen eventuellen Nullwert durch eine leere Zeichenkette. Dann untersucht sie in einer For…Next-Schleife alle Buchstaben der Zeichenkette strPLZ. Dabei ermittelt sie den aktuellen Buchstaben mit Mid(strPLZ, i, 1) und prüft dann mit der InStr-Funktion, ob dieser in der Zeichenkette aus cStrZahlen enthalten ist. Ist das nicht der Fall, liefert InStr die Position, die gleich 0 ist. Dann erscheint eine entsprechende Meldung und die Eingabe wird mit Cancel = True abgebrochen – der Benutzer kann das Feld erst verlassen, wenn die Prüfung erfolgreich ist (siehe Bild 1). Dazu kann das Feld auch vollständig geleert werden.

Meldung nach dem Vor Aktualisierung-Ereignis

Bild 1: Meldung nach dem Vor Aktualisierung-Ereignis

Private Sub txtPLZ_BeforeUpdate(Cancel As Integer)
     Dim i As Integer
     Dim strPLZ As String
     strPLZ = Nz(Me!PLZ, "")
     For i = 1 To Len(strPLZ)
         If InStr(1, cStrZahlen, Mid(strPLZ, i, 1)) = 0 Then
             MsgBox "Die PLZ darf nur aus Zahlen bestehen.", vbOKOnly + vbExclamation, "Ungültige PLZ"
             Cancel = True
         End If
     Next i
End Sub

Listing 1: Prüfen der PLZ nach der Eingabe

Prüfung während der Eingabe

Die alternative Variante ist, die Zeichen direkt bei der Eingabe zu prüfen. Dazu benötigen wir eine andere Ereignisprozedur, nämlich Bei Taste ab. Vorab ein Hinweis: Damit decken wir nicht alle Fälle ab. Dazu jedoch später mehr.

Da wir auch erst einmal die Eingabe der Postleitzahl beschreiben wollen, kopieren wir das Feld txtPLZ in ein neues Textfeld namens txtPLZ2. Für dieses hinterlegen wir dann die Ereignisprozedur txtPLZ2_KeyDown. Was können wir mit dem Ereignis Bei Taste ab erledigen?

Die dadurch ausgelöste Prozedur txtPLZ2_KeyDown ist so aufgebaut:

Private Sub txtPLZ2_KeyDown(KeyCode As Integer,  Shift As Integer)
End Sub

Hier sehen wir zwei Parameter:

  • KeyCode: Liefert einen Zahlenwert, der die betätigte Taste repräsentiert.
  • Shift: Gibt an, ob eine der Tasten Umschalt, Alt oder Strg gedrückt ist.

KeyCode liefert aber nicht nur einen Zahlenwert für die aktuell angeklickte Taste. Sie können durch Einstellen von KeyCode auf den Wert 0 auch dafür sorgen, dass der Tastenanschlag nicht an das aktuelle Steuerelement weitergeleitet wird. Und Sie können sogar festlegen, dass statt des gedrückten Zeichens ein anderes Zeichen weitergegeben wird. Für uns ist allerdings nur interessant, die Eingabe eines nicht gewünschten Zeichens zu unterbinden, indem wir KeyCode auf 0 einstellen.

Wie finden wir heraus, welcher KeyCode welchem Zeichen entspricht, um entsprechend darauf reagieren zu können? Ganz einfach: Wir geben den KeyCode einfach im Direktbereich aus.

Private Sub txtPLZ2_KeyDown(KeyCode As Integer,  Shift As Integer)
     Debug.Print KeyCode
End Sub

Damit erfahren wir durch Eingeben von Zeichen in das Feld txtPLZ2 schnell, dass die Zahlen von 0 bis 9 den Werten 48 bis 57 für KeyCode entsprechen. Wir können nun in einem ersten Ansatz dafür sorgen, dass der Benutzer nur noch diese Zeichen in das Textfeld eingeben kann. Dazu prüfen wir, ob KeyCode einen Wert von 48 bis 57 enthält und falls nicht, geben wir mit dem Parameter KeyCode den Wert 0 zurück:

Private Sub txtPLZ2_KeyDown(KeyCode As Integer,  Shift As Integer)
     Select Case KeyCode
         Case 48 To 57
         Case Else
             KeyCode = 0
     End Select
End Sub

Das funktioniert genau wie angenommen: Nur die Tasten 0 bis 9 werden weitergeleitet und im Textfeld ausgegeben.

Wir haben allerdings ein kleines Problem: Auch die Tasten zum Bewegen der Einfügemarke, die Eingabetaste, die Tabulatortaste et cetera werden innerhalb des Textfeldes blockiert. Also geben wir auch solche Tasten wieder frei.

Wie Sie herausfinden, welche KeyCodes hinter den Tasten stecken, haben wir ja bereits beschrieben. Der Übersicht halber tragen wir die zusätzlichen Elemente in eine weitere Case-Bedingung ein:

  • 8: Back
  • 9: Tabulator
  • 13: Eingabetaste
  • 27: Escape
  • 37: Cursor nach links
  • 39: Cursor nach rechts
  • 46: Entfernen
  • 113: F2 (zum Aufheben von Markierungen)

Nummernblock berücksichtigen

Gegebenenfalls verwenden Benutzer auch den Nummernblock der Tastatur, um Zahlen einzugeben. Das müssen wir berücksichtigen, denn die KeyCode-Werte entsprechen nicht denen der normalen Zahlentasten, sondern den Zahlen von 96 bis 105. Wir fügen diese dem Case-Zweig für die normalen Zahlen hinzu:

        Case 48 To 57, 96 To 105

Die Eingabetaste im Nummernblock hat allerdings auch den KeyCode-Wert 13, sodass hier keine Erweiterung notwendig ist.

Die vollständige Prozedur sieht nun wie folgt aus:

Private Sub txtPLZ2_KeyDown(KeyCode As Integer,  Shift As Integer)
     Select Case KeyCode
         Case 48 To 57, 96 To 105
         Case 8, 9, 13, 27, 37, 39, 46, 113
         Case Else
             KeyCode = 0
     End Select
End Sub

Für bessere Lesbarkeit können wir auch die Konstanten der Enumeration KeyCodeConstants nutzen.

Bei der Gelegenheit fällt uns noch eine Ergänzung ein: Aktuell lassen wir alle Betätigungen der Tasten von 0 bis 9 zu – und wir prüfen noch nicht, ob der Benutzer dabei eine der Tasten Umschalt, Strg oder Alt drückt. Das heißt, dass der Benutzer die Zahlen auch bei gedrückter Umschalttaste eingeben kann, was die Eingabe von Ausrufezeichen, Anführungszeichen und so weiter erlaubt. Wir müssen also im Case-Zweig für die Zahlen noch prüfen, ob der Parameter Shift den Wert 0 enthält und falls nicht, das eingegebene Zeichen abfangen.

Dann sieht die Prozedur wie in Listing 2 aus.

Private Sub txtPLZ2_KeyDown(KeyCode As Integer, Shift As Integer)
     Select Case KeyCode
         Case vbKey0 To vbKey9, vbKeyNumpad0 To vbKeyNumpad9
             If Not Shift = 0 Then
                 KeyCode = 0
             End If
         Case vbKeyBack, vbKeyTab, vbKeyReturn, vbKeyEscape, vbKeyLeft, vbKeyRight, vbKeyDelete, vbKeyF2
         Case Else
             KeyCode = 0
     End Select
End Sub

Listing 2: Prüfen der PLZ nach der Eingabe mit KeyCode-Konstanten

Einfügen über die Zwischenablage

Der Fall, den wir mit dieser Methode nicht verarbeiten können, ist das Einfügen von Texten über die Zwischenablage. Das heißt, der Benutzer hat beispielsweise den Text D-12345 in die Zwischenablage kopiert, markiert dann das Textfeld txtPLZ2 und betätigt entweder die Tastenkombination Strg + V oder den Kontextmenübefehl Einfügen.

Sie haben das Ende des frei verfügbaren Textes erreicht. Möchten Sie ...

TestzugangOder bist Du bereits Abonnent? Dann logge Dich gleich hier ein. Die Zugangsdaten findest Du entweder in der aktuellen Print-Ausgabe auf Seite U2 oder beim Online-Abo in der E-Mail, die Du als Abonnent regelmäßig erhältst:

Schreibe einen Kommentar