Another method would be to not allow text to be entered in the first place. In the example below I've added the case-sensitive word 'Numerical' to the controls Tag property for text boxes that must be numeric.
Rather than not allowing the user to move on if an incorrect entry is added I've always found it easier to check the whole form when a Save button is pressed.
I've added code at the bottom for changing the back colour of the control.
Create a Class and name it clsTxtBxEvent.
Option Explicit
Public WithEvents txtBox As MSForms.TextBox
Private Sub txtBox_Change()
Static LastText As String
Static SecondTime As Boolean
Const MaxDecimal As Integer = 2
With txtBox
'Allow only numbers with <=2 decimal places
If Not SecondTime Then
If .Text Like "[!0-9.-]*" Or Val(.Text) < -1 Or _
.Text Like "*.*.*" Or .Text Like "*." & String$(1 + MaxDecimal, "#") Or _
.Text Like "?*[!0-9.]*" Then
SecondTime = True
.Text = LastText
Else
LastText = .Text
End If
End If
SecondTime = False
' 'Allow only whole numbers.
' If .Text Like "[!0-9]" Or Val(.Text) < -1 Or .Text Like "?*[!0-9]*" Then
' .Text = LastText
' Else
' LastText = .Text
' End If
End With
End Sub
Add this to your form:
Option Explicit
Private TextBoxCollection As Collection
Private Sub UserForm_Initialize()
Dim TxtBxEvent As clsTxtBxEvent
Dim ctrl As Control
Set TextBoxCollection = New Collection
For Each ctrl In Me.Controls
Select Case TypeName(ctrl)
Case "TextBox"
If ctrl.Tag = "Numeric" Then '<Remove check if all textboxes.
Set TxtBxEvent = New clsTxtBxEvent
Set TxtBxEvent.txtBox = ctrl
TextBoxCollection.Add TxtBxEvent
End If '<Remember to remove this as well
End Select
Next ctrl
End Sub
This code added to the form will change the back colour of the control.
Private Sub ColourBackground(ctrl As Control, Optional ColourOn As Boolean = True)
If ColourOn Then
ctrl.BackColor = &HFFC0C0
Else
ctrl.BackColor = &H80000005
End If
End Sub
'Colour controls on Enter / Exit '
'Enter / Exit isn't exposed to class objects, so needs coding separately. '
Private Sub TextBox1_Enter()
ColourBackground Me.TextBox1
End Sub
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
ColourBackground Me.TextBox1, False
End Sub
Private Sub TextBox2_Enter()
ColourBackground Me.TextBox2
End Sub
Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
ColourBackground Me.TextBox2, False
End Sub
I haven't tried, but you could move the ColourBackground procedure to the class module and check against the controls Tag value for max/min allowed values in specific controls and colour accordingly on update.
Bit of a disclaimer - I had a similar question years ago and was answered on MrExcel.
Cancel = Trueprevents it, simple take that line out.txt_1x2_1_fromwhen you move to another textbox. Are you talking about the background color of the textbox?