I need to find numbers from a string
. How does one find numbers from a string
in VBA Excel?

- 22,092
- 39
- 79
- 102

- 277
- 1
- 3
- 10
10 Answers
Assuming you mean you want the non-numbers stripped out, you should be able to use something like:
Function onlyDigits(s As String) As String
' Variables needed (remember to use "option explicit"). '
Dim retval As String ' This is the return string. '
Dim i As Integer ' Counter for character position. '
' Initialise return string to empty '
retval = ""
' For every character in input string, copy digits to '
' return string. '
For i = 1 To Len(s)
If Mid(s, i, 1) >= "0" And Mid(s, i, 1) <= "9" Then
retval = retval + Mid(s, i, 1)
End If
Next
' Then return the return string. '
onlyDigits = retval
End Function
Calling this with:
Dim myStr as String
myStr = onlyDigits ("3d1fgd4g1dg5d9gdg")
MsgBox (myStr)
will give you a dialog box containing:
314159
and those first two lines show how you can store it into an arbitrary string variable, to do with as you wish.

- 854,327
- 234
- 1,573
- 1,953
-
Thanks it works. Sorry i am asking very basic question i want to use this 'onlydigits' value for input to another method. – user905527 Aug 30 '11 at 07:13
-
No problems, @user905527, I've updated the sample code at the end to show how you put it into a variable and pass it to another function. – paxdiablo Aug 30 '11 at 07:41
-
2You can reduce the number of comparisons with the IsNumeric function. if IsNumeric(Mid(s,i,1)) then – Spevy Feb 02 '14 at 11:08
-
I digits of Pi a co incidence? – Arulx Z Oct 22 '15 at 09:52
-
1@ArulxZ, coincidence, no. I tend to use `pi`, `e`, `xyzzy`, `plugh`, `42` and other "magical" items quite a bit :-) – paxdiablo Oct 22 '15 at 11:30
-
First Try Failed, my assumption is due to my string having `155(Str)` – FreeSoftwareServers Feb 02 '21 at 20:11
Regular expressions are built to parse. While the syntax can take a while to pick up on this approach is very efficient, and is very flexible for handling more complex string extractions/replacements
Sub Tester()
MsgBox CleanString("3d1fgd4g1dg5d9gdg")
End Sub
Function CleanString(strIn As String) As String
Dim objRegex
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
.Global = True
.Pattern = "[^\d]+"
CleanString = .Replace(strIn, vbNullString)
End With
End Function

- 54,857
- 16
- 114
- 177
-
7`+1` for using `regex`, I am really glad we can use it in VBA, it adds some ***coolness*** to VBA's *`dim` `dim` lighting culture* =) – bonCodigo Jan 19 '13 at 17:26
-
2While regex is the most elegant, does regex cause a performance hit on a large scale? – Daryl Bennett Nov 16 '16 at 22:23
-
3@DarylBennett Great question. Instantiating the object can cause a hit equivalent or worse than a loop. But if the object is instantiated once (say in an array loop) and run repeatedly it is extremely efficient. – brettdj Nov 17 '16 at 02:24
-
Perhaps add [this link](https://stackoverflow.com/q/22542834/111794) to your answer? Admittedly, the question is phrased in terms of Excel-hosted VBA, but most of the information applies equally well to any VBA host. – Zev Spitz Jul 22 '18 at 14:19
Expanding on brettdj's answer, in order to parse disjoint embedded digits into separate numbers:
Sub TestNumList()
Dim NumList As Variant 'Array
NumList = GetNums("34d1fgd43g1 dg5d999gdg2076")
Dim i As Integer
For i = LBound(NumList) To UBound(NumList)
MsgBox i + 1 & ": " & NumList(i)
Next i
End Sub
Function GetNums(ByVal strIn As String) As Variant 'Array of numeric strings
Dim RegExpObj As Object
Dim NumStr As String
Set RegExpObj = CreateObject("vbscript.regexp")
With RegExpObj
.Global = True
.Pattern = "[^\d]+"
NumStr = .Replace(strIn, " ")
End With
GetNums = Split(Trim(NumStr), " ")
End Function

- 1,080
- 14
- 9
-
1Fantastic, I always missed RegEx in VBA! See also: [VBScript’s Regular Expression Support](http://www.regular-expressions.info/vbscript.html). – Olivier Jacot-Descombes May 21 '15 at 15:21
Use the built-in VBA function Val, if the numbers are at the front end of the string:
Dim str as String
Dim lng as Long
str = "1 149 xyz"
lng = Val(str)
lng = 1149

- 31
- 3
-
1`Val` does some very strange things: `Val("3d1fgd4g1dg5d9gdg")` returns `30`, while `Va("3d11gd4g1dg5d9gdg")` returns `300000000000`. – Zev Spitz Jul 22 '18 at 14:28
-
@zev-spitz Noted: very odd behaviour. I see that the anomalous results in your examples above are triggered, respectively, but the first three or four characters; hence `Val("3d1")` and `Val("3d11")` respectively return 30 and 300000000000. – Rohan Moore Jul 25 '18 at 11:41
-
Interprets as floating point values (I don't know why): 3d1=3*10^1; 3d11=3*10^11. Do not use Val()! – Álvaro Gustavo López Sep 26 '18 at 14:51
I was looking for the answer of the same question but for a while I found my own solution and I wanted to share it for other people who will need those codes in the future. Here is another solution without function.
Dim control As Boolean
Dim controlval As String
Dim resultval As String
Dim i as Integer
controlval = "A1B2C3D4"
For i = 1 To Len(controlval)
control = IsNumeric(Mid(controlval, i, 1))
If control = True Then resultval = resultval & Mid(controlval, i, 1)
Next i
resultval = 1234

- 43
- 1
- 7
This a variant of brettdj's & pstraton post.
This will return a true Value and not give you the #NUM!
error. And \D
is shorthand for anything but digits. The rest is much like the others only with this minor fix.
Function StripChar(Txt As String) As Variant
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "\D"
StripChar = Val(.Replace(Txt, " "))
End With
End Function

- 1,729
- 1
- 17
- 27
This is based on another answer, but is just reformated:
Assuming you mean you want the non-numbers stripped out, you should be able to use something like:
'
' Skips all characters in the input string except digits
'
Function GetDigits(ByVal s As String) As String
Dim char As String
Dim i As Integer
GetDigits = ""
For i = 1 To Len(s)
char = Mid(s, i, 1)
If char >= "0" And char <= "9" Then
GetDigits = GetDigits + char
End If
Next i
End Function
Calling this with:
Dim myStr as String
myStr = GetDigits("3d1fgd4g1dg5d9gdg")
Call MsgBox(myStr)
will give you a dialog box containing:
314159
and those first two lines show how you can store it into an arbitrary string variable, to do with as you wish.

- 7,611
- 5
- 39
- 71
Alternative via Byte
Array
If you assign a string to a Byte
array you typically get the number equivalents of each character in pairs of the array elements. Use a loop for numeric check via the Like
operator and return the joined array as string:
Function Nums(s$)
Dim by() As Byte, i&, ii&
by = s: ReDim tmp(UBound(by)) ' assign string to byte array; prepare temp array
For i = 0 To UBound(by) - 1 Step 2 ' check num value in byte array (0, 2, 4 ... n-1)
If Chr(by(i)) Like "#" Then tmp(ii) = Chr(by(i)): ii = ii + 1
Next i
Nums = Trim(Join(tmp, vbNullString)) ' return string with numbers only
End Function
Example call
Sub testByteApproach()
Dim s$: s = "a12bx99y /\:3,14159" ' [1] define original string
Debug.Print s & " => " & Nums(s) ' [2] display original string and result
End Sub
would display the original string and the result string in the immediate window:
a12bx99y /\:3,14159 => 1299314159

- 9,436
- 3
- 33
- 57
Based on @brettdj's answer using a VBScript regex ojbect with two modifications:
- The function handles variants and returns a variant. That is, to take care of a null case; and
- Uses explicit object creation, with a reference to the "Microsoft VBScript Regular Expressions 5.5" library
Function GetDigitsInVariant(inputVariant As Variant) As Variant
' Returns:
' Only the digits found in a varaint.
' Examples:
' GetDigitsInVariant(Null) => Null
' GetDigitsInVariant("") => ""
' GetDigitsInVariant(2021-/05-May/-18, Tue) => 20210518
' GetDigitsInVariant(2021-05-18) => 20210518
' Notes:
' If the inputVariant is null, null will be returned.
' If the inputVariant is "", "" will be returned.
' Usage:
' VBA IDE Menu > Tools > References ...
' > "Microsoft VBScript Regular Expressions 5.5" > [OK]
' With an explicit object reference to RegExp we can get intellisense
' and review the object heirarchy with the object browser
' (VBA IDE Menu > View > Object Browser).
Dim regex As VBScript_RegExp_55.RegExp
Set regex = New VBScript_RegExp_55.RegExp
Dim result As Variant
result = Null
If IsNull(inputVariant) Then
result = Null
Else
With regex
.Global = True
.Pattern = "[^\d]+"
result = .Replace(inputVariant, vbNullString)
End With
End If
GetDigitsInVariant = result
End Function
Testing:
Private Sub TestGetDigitsInVariant()
Dim dateVariants As Variant
dateVariants = Array(Null, "", "2021-/05-May/-18, Tue", _
"2021-05-18", "18/05/2021", "3434 ..,sdf,sfd 444")
Dim dateVariant As Variant
For Each dateVariant In dateVariants
Debug.Print dateVariant & ": ", , GetDigitsInVariant(dateVariant)
Next dateVariant
Debug.Print
End Sub

- 1,676
- 1
- 16
- 18
Public Function ExtractChars(strRef$) As String
'Extract characters from a string according to a range of charactors e.g'+.-1234567890'
Dim strA$, e%, strExt$, strCnd$: strExt = "": strCnd = "+.-1234567890"
For e = 1 To Len(strRef): strA = Mid(strRef, e, 1)
If InStr(1, strCnd, strA) > 0 Then strExt = strExt & strA
Next e: ExtractChars = strExt
End Function
In the immediate debug dialog:
? ExtractChars("a-5d31.78K")
-531.78

- 23
- 6
-
1As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 06 '21 at 16:38
-
The function returns any characters in the strings, example '+.-1234567890' – Zhou Lei Nov 07 '21 at 17:17