Search code examples
ms-access

Find the position of the first occurrence of any number in string (if present) in MS Access


In MS Access I have a table with a Short Text field named txtPMTaskDesc in which some records contains numbers, and if they do, at different positions in the string. I would like to recover these numbers from the text string if possible for sorting purposes. There are over 26000 records in the table, so I would rather handle it in a query over using VBA loops etc.

Sample Data

While the end goal is to recover the whole number, I was going to start with just identifying the position of the first numerical value in the string. I have tried a few things to no avail like:

InStr(1,[txtPMTaskDesc],"*[0-9]*")

Once I get that, I was going to use it as a part of a Mid() function to pull out it and the character next to it like below. (its a bit dodgy, but there is never more than a two-digit number in the text string)

IIf(InStr(1,[txtPMTaskDesc],"*[0-9]*")>0,Mid([txtPMTaskDesc],InStr(1,[txtPMTaskDesc],"*[0-9]*"),2)*1,0)

Any assistance appreciated.


Solution

  • If data is truly representative and number always preceded by "- No ", then expression in query can be like:

    Val(Mid(txtPMTaskDesc, InStr(txtPMTaskDesc, "- No ") + 5))

    If there is no match, a 0 will return, however, if field is null, the expression will error.

    If string does not have consistent pattern (numbers always in same position or preceded by some distinct character combination that can be used to locate position), don't think can get what you want without VBA. Either loop through string or explore Regular Expressions aka RegEx. Set reference to Microsoft VBScript Regular Expressions x.x library.

    Function GetNum(strS AS String)
    Dim re As RegExp, Match As Object
    Set re = New RegExp
    re.Pattern = "[\d+]+"
    Set Match = re.Execute(strS)
    GetNum = Null
    If Match.Count > 0 Then GetNum = Match(0)
    End Function
    

    Input of string "Fuel Injector - No 1 - R&I" returns 1.

    Place function in a general module and call it from query.
    SELECT table.*, GetNum(Nz(txtPMTaskDesc,"")) AS Num FROM table;

    Function returns Null if there is no number match.