VBA. How to find position of first digit in string
Asked Answered
D

7

15

I have string "ololo123". I need get position of first digit - 1. How to set mask of search ?

Dilly answered 23/8, 2010 at 13:0 Comment(1)
@Remou thanks, I deleted the remark.Drawing
M
13

Here is a lightweight and fast method that avoids regex/reference additions, thus helping with overhead and transportability should that be an advantage.

Public Function GetNumLoc(xValue As String) As Integer

For GetNumLoc = 1 To Len(xValue)
    If Mid(xValue, GetNumLoc, 1) Like "#" Then Exit Function
Next

GetNumLoc = 0

End Function
Musset answered 6/8, 2015 at 19:9 Comment(0)
J
9

Something like this should do the trick for you:

Public Function GetPositionOfFirstNumericCharacter(ByVal s As String) As Integer
    For i = 1 To Len(s)
        Dim currentCharacter As String
        currentCharacter = Mid(s, i, 1)
        If IsNumeric(currentCharacter) = True Then
            GetPositionOfFirstNumericCharacter = i
            Exit Function
        End If
    Next i
End Function

You can then call it like this:

Dim iPosition as Integer
iPosition = GetPositionOfFirstNumericCharacter("ololo123")
Jeroboam answered 23/8, 2010 at 13:10 Comment(2)
You can simplify the function. You don't really need currentCharacter; your test could be If IsNumeric(Mid(s, i, 1)) Then...Siphonostele
@Siphonostele - very true. Breaking it down makes it more readable and that's what I am for when answering a question of this level of complexity as I work on the basis that the OP may need simpler/clearer code to aid understanding =)Jeroboam
L
2

Not sure on your environment, but this worked in Excel 2010

'Added reference for Microsoft VBScript Regular Expressions 5.5

Const myString As String = "ololo123"
Dim regex As New RegExp
Dim regmatch As MatchCollection

regex.Pattern = "\d"
Set regmatch = regex.Execute(myString)
MsgBox (regmatch.Item(0).FirstIndex)   ' Outputs 5
Londonderry answered 23/8, 2010 at 14:1 Comment(0)
S
2

I actually have that function:

Public Function GetNumericPosition(ByVal s As String) As Integer
    Dim result As Integer
    Dim i As Integer
    Dim ii As Integer

    result = -1
    ii = Len(s)
    For i = 1 To ii
        If IsNumeric(Mid$(s, i, 1)) Then
            result = i
            Exit For
        End If
    Next
    GetNumericPosition = result
End Function
Strawworm answered 23/8, 2010 at 14:19 Comment(0)
D
1

You could try regex, and then you'd have two problems. My VBAfu is not up to snuff, but I'll give it a go:

Function FirstDigit(strData As String) As Integer
    Dim RE As Object REMatches As Object

    Set RE = CreateObject("vbscript.regexp")
    With RE
        .Pattern = "[0-9]"
    End With

    Set REMatches = RE.Execute(strData)
    FirstDigit = REMatches(0).FirstIndex
End Function

Then you just call it with FirstDigit("ololo123").

Dibrin answered 23/8, 2010 at 13:27 Comment(0)
M
0

If speed is an issue, this will run a bit faster than Robs (noi Rob):

Public Sub Example()
    Const myString As String = "ololo123"
    Dim position As Long
    position = GetFirstNumeric(myString)
    If position > 0 Then
        MsgBox "Found numeric at postion " & position & "."
    Else
        MsgBox "Numeric not found."
    End If
End Sub

Public Function GetFirstNumeric(ByVal value As String) As Long
    Dim i As Long
    Dim bytValue() As Byte
    Dim lngRtnVal As Long
    bytValue = value
    For i = 0 To UBound(bytValue) Step 2
        Select Case bytValue(i)
            Case vbKey0 To vbKey9
                If bytValue(i + 1) = 0 Then
                    lngRtnVal = (i \ 2) + 1
                    Exit For
                End If
        End Select
    Next
    GetFirstNumeric = lngRtnVal
End Function
Maihem answered 23/8, 2010 at 13:14 Comment(1)
so you turn the string to byte and check it by two-byte chunks if the first byte is 0-9 and the second is 0. but how does that make it faster?Nonobedience
S
0

An improved version of spere's answer (can't edit his answer), which works for any pattern

Private Function GetNumLoc(textValue As String, pattern As String) As Integer
    For GetNumLoc = 1 To (Len(textValue) - Len(pattern) + 1)
        If Mid(textValue, GetNumLoc, Len(pattern)) Like pattern Then Exit Function
    Next

    GetNumLoc = 0
End Function

To get the pattern value you can use this:

Private Function GetTextByPattern(textValue As String, pattern As String) As String
    Dim NumLoc As Integer
    For NumLoc = 1 To (Len(textValue) - Len(pattern) + 1)
        If Mid(textValue, NumLoc, Len(pattern)) Like pattern Then
            GetTextByPattern = Mid(textValue, NumLoc, Len(pattern))
            Exit Function
        End If
    Next    

    GetTextByPattern = ""
End Function

Example use:

dim bill as String
bill = "BILLNUMBER 2202/1132/1 PT2200136"

Debug.Print GetNumLoc(bill , "PT#######")
'Printed result:
'24

Debug.Print GetTextByPattern(bill , "PT#######")
'Printed result:
'PT2200136
Spodumene answered 7/5, 2022 at 11:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.