TL;DR — A TextBox stores one kind of thing: text.
TextBox1.Valuealways hands you back aString, even when the user typed42or a date. That is the source of almost every TextBox bug — arithmetic on text, or a number compared to a string. Before you do maths, test withIsNumericand convert withCDblorCLng..Textand.Valueare nearly the same for a text box; an empty box is"", not0.
Private Sub cmdAdd_Click()
' TextBox1.Value is the STRING "10", not the number 10:
If IsNumeric(TextBox1.Value) Then
Dim n As Double
n = CDbl(TextBox1.Value) ' now it is a real number
MsgBox n + 5
Else
MsgBox "Please enter a number"
End If
End Sub
A TextBox is the plainest control on a UserForm — a box the user types into — and it causes the most confusion, for a single reason. It belongs to the control family reached through the form's Controls collection: like every control, you talk to a text box through its properties. But where a CheckBox hands back a Boolean and a ListBox hands back the selected item, a TextBox hands back something deceptively simple — a string — and treating that string as the number it resembles is the number-one TextBox mistake.
What you'll learn
- Why
TextBox1.Valueis always aString, whatever it looks like - The two different ways arithmetic on
.Valuegoes wrong - Converting safely with
IsNumeric, thenCDblorCLng - The small difference between
.Textand.Value - Why an empty box is
""and not0, and how to test it - Reacting as the user types with the
ChangeandExitevents
The mental model: a TextBox always hands back text
A text box holds characters, nothing else. When the user types 42, the box contains the two-character
string "42", not the number 42. So TextBox1.Value is a String — every time, regardless of what it
looks like. A date typed as 31/12/2026 is a string of ten characters; a currency amount 1,250.00 is a
string with a comma in it. VBA does not read intent from a text box; it hands you the characters and leaves
the meaning to you.
This one fact explains every TextBox surprise. If you remember nothing else: whatever comes out of a text box is text until you convert it.
The number trap: adding to .Value goes wrong two ways
Because .Value is a string, doing maths on it is a coin toss between two failures:
' Say the box contains 10
MsgBox TextBox1.Value + 5 ' NOT 15
If VBA treats + as concatenation you get "105"; if a later value in the box is non-numeric you get
run-time error 13, Type mismatch instead. Same code, two different wrong outcomes, depending on what the
user typed — exactly the kind of bug that passes your test and fails in the user's hands. The fix is never
to do arithmetic on .Value directly.
Converting safely: IsNumeric, then CDbl or CLng
Two steps, always in this order. First ask whether the text is a number with IsNumeric; only then
convert it:
If IsNumeric(TextBox1.Value) Then
Dim price As Double
price = CDbl(TextBox1.Value) ' string -> Double
Else
MsgBox "That is not a number"
TextBox1.SetFocus ' send them back to fix it
End If
Use CDbl for anything with decimals (prices, rates) and CLng for whole numbers (counts, ids). Skipping
the IsNumeric guard and calling CDbl on "abc" raises the same error 13 — so the guard is not
optional politeness, it is what turns a crash into a message. This is the TextBox equivalent of the type
safety you gave up the moment the value became text.
.Text versus .Value
For a text box the two are almost identical, and .Value is the one to use by habit. The distinction that
matters: .Text is always the string shown in the box, while .Value can be affected by other
properties on richer controls. For a plain TextBox they return the same string. Prefer .Value for
reading data, and reach for .Text only when you specifically need the displayed characters — for example
inside a Change event before .Value has settled.
Empty is a zero-length string, not zero
An empty text box is "" — a zero-length string — not 0 and not Null. So test it as text:
If Trim(TextBox1.Value) = "" Then
MsgBox "This field is required"
Exit Sub
End If
Trim also catches a box where the user typed only spaces. Do not test If TextBox1.Value = 0 — that
compares a string to a number and misleads you. Because empty is a string, a required-field check is a
string test, not a numeric one — a distinction that trips people coming from the
InputBox, which has its own cancel-versus-empty rules.
Reacting as the user types: the Change and Exit events
Two events cover most live validation. Change fires on every keystroke — good for a live character count
or enabling an OK button, bad for heavy work. Exit fires when the user leaves the box, and it can
cancel the exit to force a correction:
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Not IsNumeric(TextBox1.Value) Then
MsgBox "Enter a number before moving on"
Cancel = True ' keep focus in the box
End If
End Sub
Setting Cancel = True in Exit is the clean way to hold the user in a field until it is valid — far
better than letting a bad value flow into the rest of the form and failing later. Use Change for cheap,
per-keystroke feedback and Exit for the real validation.
How ExcelMaster helps
The TextBox bug is the definition of "works on my machine": the box that always held a number in testing
holds a stray letter in production, and + 5 becomes "105" or error 13. It stays quiet until the exact
input that breaks it arrives.
ExcelMaster lets you say what the field
means — "this is a price, reject anything that is not a number and put the cursor back" — and it writes the
IsNumeric guard and the CDbl conversion, with the Exit event wired up, so the string-to-number step
is never skipped. You keep the form and the code.
Frequently asked questions
Is a VBA TextBox value always a string?
Yes. A TextBox stores characters, so TextBox1.Value returns a String every time, even when the user
typed digits or a date. VBA does not convert it for you. To use it as a number you must convert it yourself
with CDbl or CLng, after checking it really is numeric with IsNumeric.
How do I get a number from a VBA TextBox?
Guard, then convert. Test IsNumeric(TextBox1.Value); if it passes, call CDbl(TextBox1.Value) for a
decimal or CLng(TextBox1.Value) for a whole number. Calling CDbl on non-numeric text raises run-time
error 13, so the IsNumeric check is what turns a crash into a friendly message.
What is the difference between .Text and .Value on a TextBox?
For a plain TextBox they return the same string, and .Value is the conventional choice for reading data.
.Text is always the characters currently displayed; .Value can differ on richer controls. Use .Value
by default and .Text only when you specifically need the displayed string, such as inside a Change
event.
How do I check if a TextBox is empty in VBA?
Test it as text: If Trim(TextBox1.Value) = "" Then. An empty box is a zero-length string, not 0 or
Null, and Trim also catches a box containing only spaces. Do not compare it to 0, which mixes a
string with a number and gives misleading results.
How do I validate a TextBox as the user types?
Use the Change event for cheap per-keystroke feedback (a character count, enabling a button) and the
Exit event for real validation. In Exit, set its Cancel argument to True to keep the cursor in the
box until the entry is valid, so a bad value never reaches the rest of the form.
Tested in
Tested in: Excel 365 (Windows 11), VBA 7.1 — last verified 2026-09-28.
Related guides: VBA Controls · VBA Frame · VBA UserForm · VBA InputBox · VBA ComboBox · VBA CheckBox · VBA On Error
