|
Eine TextBox dazu zu bringen, nur Ziffern, Dezimalzeichen (falls
gewünscht) und Rückschritttaste zu akzeptieren, scheint auf den
ersten Blick nicht allzu schwierig zu sein. Sie brauchen nur dafür
zu sorgen, dass im KeyPress-Ereignis
der TextBox nur die diesen Zeichen bzw. Tasten entsprechenden
Ascii-Codes durchgelassen und alle übrigen herausgefiltert werden:
Private Sub TextBox_KeyPress(KeyAscii As Integer)
Select Case KeyAscii
Case vbKey0 To vbKey9, vbKeyBack, 44
Case Else
KeyAscii = 0
End Select
End Sub
 |
Im KeyPress-Ereignis filtern Sie alle
Zeichen außer Ziffern, Dezimalzeichen und Rückschritt heraus

|
Das KeyDown-Ereignis brauchen Sie nicht separat zu behandeln. Im
KeyPress-Ereignis kommen nämlich die Codes aller darstellbaren
Zeichen an.
Durch die Filterung im KeyPress-Ereignis wird allerdings nicht
verhindert, dass der Anwender unerwünschte Zeichen über die
Zwischenablage einfügen kann. Die Tastendrücke für das Einfügen
(Strg+Einfg oder Strg+V) abzufangen, wäre wenig sinnvoll, da auch
über das Kontextmenü der Textbox aus der Zwischenablage eingefügt
werden kann. Es ist jedoch ziemlich aufwändig, dieses wiederum
abzufangen und darin den Menüpunkt zum Einfügen zu sperren, falls
sich unerwünschter (also nicht-numerischer) Text in der
Zwischenablage befinden sollte (was jeweils auch erst noch zu
prüfen wäre).
Der richtige Ort zum Abfangen unerwünschter Einfügungen ist
dagegen das Change-Ereignis
der TextBox. Hier können Sie jeglichen Inhalt - allerdings immer
nur hinterher, nach der Eingabe - auf Korrektheit und, in diesem
Fall, auf Erwünschtheit prüfen. Hier prüfen Sie, ob die
Textlänge gleich 0 ist, oder ob der Inhalt numerisch ist. Da die
VB-Funktion IsNumeric
Strings akzeptiert, die neben Ziffern auch Punkte
(Tausender-Trennzeichen) enthalten können, sollten diese zuvor
mittels der VB-Funktion Replace
(seit VB 6 verfügbar) aus dem Inhalt entfernt werden. Falls der
Anwender versehentlich eine einen String mit falscher oder
unsinniger Stellung von Tausenderpunkten oder eine Dezimalzahl mit
dem Punkt als angelsächsischem Dezimalzeichen eingefügt hat, hat
er Pech gehabt. Die Plausibilität in dieser Hinsicht zu prüfen,
ist recht aufwändig und daher eher ein Feature einer speziellen
TextBox für maskierte Eingaben (MaskedEdit usw.).
Ergibt die Prüfung einen zulässigen Inhalt in der
Text-Eigenschaft der TextBox, wird dieser in der statischen
Variablen sLastText festgehalten. Dieser Wert wird benötigt, falls
die nächste Prüfung einen ungültigen Inhalt ergeben sollte. Dann
wird der ungültige Inhalt durch den zuletzt in dieser Variablen
gesicherten Inhalt ersetzt - die falsche Eingabe wird also umgehend
rückgängig gemacht. Das geht in der Regel so schnell, dass der
Anwender gar nichts davon mitbekommt.
Da diese erneute Änderung innerhalb der Ereignisbearbeitung das
Change-Ereignis erneut auslöst, sollten Sie verhindern, dass die
Prozedur dabei erneut vollständig durchlaufen wird. Wie Sie das mit
Hilfe der statischen Variablen sInProc bewerkstelligen, finden Sie
im Artikel "Aller
guten Dinge ist eins".
Da es bei einer TextBox für numerische Eingaben sinnvoll ist,
auch keinen leeren Inhalt zuzulassen, sollte statt dessen eine
"0" eingefügt werden. Damit der Anwender diese jedoch
gleich wieder bequem überschreiben kann, setzen Sie den Beginn der
Markierung auf den Anfang (= 0) und die Länge der Markierung auf
volle Länge (= 1).
Eigentlich wird bei dieser Prüfung auch das erneut geprüft, was
im KeyPress-Ereignis bereits als zulässig durchgelassen worden ist.
Sie könnten auf die Filterung dort verzichten, würden sich aber
damit einen weitaus höheren, zusätzlichen Aufwand im
Change-Ereignis einhandeln. Damit der Anwender nicht zu sehr von der
aus einer eventuellen Rücksetzung resultierenden
Unberechenbarkeit der Cursor-Position und der Markierung verwirrt
würde, müssten Sie deren Verwaltung im Change-Ereignis komplett
selbst vornehmen.
Private Sub TextBox_Change()
Static sLastText As String
Static sInProc As Boolean
If sInProc Then
Exit Sub
Else
sInProc = True
End If
With TextBox
.Text = Replace(.Text, ".", "")
If CBool(Len(.Text) = 0) Or IsNumeric(.Text) Then
sLastText = .Text
Else
Beep
.Text = sLastText
End If
If Len(.Text) = 0 Then
.Text = "0"
End If
If .Text = "0" Then
.SelStart = 0
.SelLength = 1
End If
End With
sInProc = False
End Sub
 |
So verhindern Sie, dass unerwünschte,
nicht-numerische Inhalte aus der Zwischenablage eingefügt
werden können

|

|