Assuming the user is providing the input, this is an X-Y problem IMO: your goal is to ensure your user can only type digit characters in that textbox, not to truncate decimals.
The problem is that a textbox' Change
event is fired too late to do that. Instead, handle KeyDown
- I'd do something like this:
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If Not KeyCodeValidator.IsValidDigitInput(KeyCode.value) Then KeyCode.value = 0
End Sub
Have a KeyCodeValidator
standard module:
Option Explicit
Option Private Module
Public Function IsValidAlphaInput(ByVal keyAscii As Long, Optional ByVal allowDeletion As Boolean = True, Optional ByVal allowNav As Boolean = True) As Boolean
IsValidAlphaInput = (keyAscii >= vbKeyA And keyAscii <= vbKeyZ) Or (allowDeletion And IsDeletion(keyAscii)) Or (allowNav And IsNavKey(keyAscii))
End Function
Public Function IsValidDigitInput(ByVal keyAscii As Long, Optional ByVal allowDeletion As Boolean = True, Optional ByVal allowNav As Boolean = True) As Boolean
IsValidDigitInput = (keyAscii >= vbKey0 And keyAscii <= vbKey9) Or (keyAscii >= vbKeyNumpad0 And keyAscii <= vbKeyNumpad9) Or (allowDeletion And IsDeletion(keyAscii)) Or (allowNav And IsNavKey(keyAscii))
End Function
Public Function IsValidAlphanumericInput(ByVal keyAscii As Long, Optional ByVal allowDeletion As Boolean = True, Optional ByVal allowNav As Boolean = True) As Boolean
IsValidAlphanumericInput = IsValidAlphaInput(keyAscii) Or IsValidDigitInput(keyAscii) Or (allowDeletion And IsDeletion(keyAscii)) Or (allowNav And IsNavKey(keyAscii))
End Function
Public Function IsValidDecimalInput(ByVal keyAscii As Long, ByVal contents As String) As Boolean
If IsValidDigitInput(keyAscii) Or keyAscii = Asc(".") Then
IsValidDecimalInput = IsNumeric(contents & Chr$(keyAscii))
End If
End Function
Private Function IsDeletion(ByVal keyAscii As Long) As Boolean
IsDeletion = keyAscii = vbKeyDelete Or keyAscii = vbKeyBack
End Function
Private Function IsNavKey(ByVal keyAscii As Long) As Boolean
IsNavKey = keyAscii = vbKeyTab Or keyAscii = vbKeyLeft Or keyAscii = vbKeyRight
End Function
If you wanted to support decimals, you'd pass the current contents of your textbox to IsValidDecimalInput
(which needs minor adjustments to support international decimal separators).
I actually have that module as a class, but a standard module fits the bill just fine too.
Point being, don't fix your user's input after it's in the textbox - prevent the user's invalid input from even being entered in the first place instead.
TextBox1 = Format(TextBox1, "0")
– braX