🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA TextBox in Excel — Why .Value Is Always Text (and How to Convert It)

|

VBA TextBox in Excel — Why .Value Is Always Text (and How to Convert It)

TL;DR — A TextBox stores one kind of thing: text. TextBox1.Value always hands you back a String, even when the user typed 42 or 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 with IsNumeric and convert with CDbl or CLng. .Text and .Value are nearly the same for a text box; an empty box is "", not 0.

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.Value is always a String, whatever it looks like
  • The two different ways arithmetic on .Value goes wrong
  • Converting safely with IsNumeric, then CDbl or CLng
  • The small difference between .Text and .Value
  • Why an empty box is "" and not 0, and how to test it
  • Reacting as the user types with the Change and Exit events

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