2
votes

Take this example:

Column A

  1. 392898 818 AA 8812 1918281 000 EUR 100A
  2. 31898 818 AA 88172 1281 000 GBP 1A
  3. 12100098 618 AA 612 7281 000 USD 11100A

All 3 rows are different. Different length, different number of substrings, etc.

How can I extract only the currency code from that string?

I want Column B to have:

  1. EUR
  2. GBP
  3. USD

Can this be done without using too many different functions in a single formula? I was thinking to use SEARCH to look for one string in a list.. i.e. "GBP","USD","EUR", etc - but this doesn't work. It only ever works for the first string, so SEARCH can't be used to check through multiple possible values.

3
Do you have a list of currencies that you want to pull out? Is it just EUR, GBP, and USD?BruceWayne
Kind of.. I can give you the list of currencies I can see: EUR, GBP, JPY, HUF, USD and also 3 blank spaces if there is no currency (5 blank spaces if you include the one before and the one after...).user2127447
Is the currency code always the next to last substring?Ron Rosenfeld

3 Answers

1
votes

Try this:

=TRIM(RIGHT(SUBSTITUTE(LEFT(A1,LEN(A1)-LEN(TRIM(RIGHT(SUBSTITUTE(A1, " ", REPT(" ", 100)), 100)))-1), " ", REPT(" ", 100)), 100))

A1 is cell with value

1
votes

You could also use a regex in a user defined function, which means you could execute in a loop over column A writing out to column B, or use in the sheet in column B. You can pass a list of the currencies of interest as the second argument to the function. If more than one currency, from your list, is present you get a comma separated list back.

Option Explicit
Public Sub Testing()
    Dim tests(), i As Long, currencies()
    currencies = Array("EUR", "GBP", "USD")
    tests = Array("392898 818 AA 8812 1918281 000 EUR 100A", _
                  "31898 818 AA 88172 1281 000 GBP 1A", _
                  "12100098 618 AA 612 7281 000 USD 11100A")

    For i = LBound(tests) To UBound(tests)
        Debug.Print GetCurrency(tests(i), currencies)
    Next
End Sub
Public Function GetCurrency(ByVal inputString As String, ByVal currencies As Variant) As String
    Dim matches As Object, total As Long, arr(), i As Long
    With CreateObject("VBScript.RegExp")
        .Global = True
        .MultiLine = True
        .Pattern = "\b" & Join(currencies, Chr$(124)) & "\b"
        If .TEST(inputString) Then
            Set matches = .Execute(inputString): total = matches.Count - 1
            ReDim arr(0 To total)
            For i = 0 To total
                arr(i) = matches(i)
            Next
            GetCurrency = Join(arr, Chr$(44))
        Else
            GetCurrency = vbNullString
        End If
    End With
End Function

Regex:

Try the regex here.

It basically uses the currencies in an OR fashion for matching. Match this currency or that currency etc. They are matched on being individual words and not part of a longer string.

/ \bEUR|GBP|USD\b / gm

1st Alternative \bEUR

\b assert position at a word boundary (^\w|\w$|\W\w|\w\W)

EUR matches the characters EUR literally (case sensitive)

2nd Alternative GBP

GBP matches the characters GBP literally (case sensitive)

3rd Alternative USD\b

USD matches the characters USD literally (case sensitive)

\b assert position at a word boundary (^\w|\w$|\W\w|\w\W)


In sheet:

Sheet

You could store the array of currencies in a single cell and refer to that cell as the second function argument.

0
votes

SEARCH and/or FIND (note that FIND is case-sensitive, and SEARCH is not) can certainly be used to return multiple search results. It returns an array, so you have to take that into account.

For example, if you have list of the possible currencies in a range (which I have name'd currList), the following formula will return the name of the matched currency:

=INDEX(currList,LOOKUP(2,1/(ISNUMBER(FIND(currList,A1))),ROW(INDIRECT("1:"&ROWS(currList)))))

enter image description here

IF the currency code will always be the next to last in the string, as you show in your examples, then you could just return that value.

Here is one way:

=TRIM(MID(SUBSTITUTE(TRIM(A1)," ",REPT(" ",99)),(LEN(TRIM(A1))-LEN(SUBSTITUTE(TRIM(A1)," ",""))-1)*99,99))