I have a column containing cells of text string which includes text and numbers. I found a great formula that finds the first number in the string and extracts it to the corresponding cell e.g.
Text String: "Initial commission of £9,999.99, then renewal commission of £9.9 from month 99"
Entering this formula =LOOKUP(99^99,--("0"&MID(F8,MIN(SEARCH({0,1,2,3,4,5,6,7,8,9},F8&"0123456789")),ROW($1:$10000))))
adjacent to the cell will extract the first number of 9,999.99.
This is not my formula but one that I found and love but would like to be able to indicate that I would also like to extract the 2nd occurring number and also the 3rd occurring number. Basically all the numbers in the string, into separate cells.
Are any of you clever people able to suggest an edit on the formula to allow this?
Thanks in advance.
Well I managed to sort it out in the end with a crazy long formula.
Its not the prettiest of formulas but it does the job.
Thank you for your suggestiongs to which did lead me down the trail of thought to get the answer. Here are my formulas.
The string of text is in a table column called 'Event Label' formula reference [@[Event Label]].
So for the first number I use this formula:
=SUBSTITUTE(LEFT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])+1)),LEFT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])+1)),LOOKUP(99^99,--("0"&MID(LEFT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])+1)),MIN(SEARCH({0,1,2,3,4,5,6,7,8,9},LEFT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])+1))&"0123456789")),ROW($1:$10000)))))
For the second number I use this formula:
=SUBSTITUTE(RIGHT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]]))),RIGHT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]]))),LOOKUP(99^99,--("0"&MID(RIGHT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]]))),MIN(SEARCH({0,1,2,3,4,5,6,7,8,9},RIGHT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])))&"0123456789")),ROW($1:$10000)))))
And for the final 3rd number I use this formula:
=SUBSTITUTE(RIGHT([@[Event Label]],LEN([@[Event Label]])-FIND("month",[@[Event Label]])+1),RIGHT([@[Event Label]],LEN([@[Event Label]])-FIND("month",[@[Event Label]])+1),LOOKUP(99^99,--("0"&MID(RIGHT([@[Event Label]],LEN([@[Event Label]])-FIND("month",[@[Event Label]])+1),MIN(SEARCH({0,1,2,3,4,5,6,7,8,9},RIGHT([@[Event Label]],LEN([@[Event Label]])-FIND("month",[@[Event Label]])+1)&"0123456789")),ROW($1:$10000)))))
This works for me as I have defined text strings that will always be in the same position in the text string.
I'm sure there is probably a better way but it will do for now.
So this is the proposed function - it uses a simple 2-state approach. The problem with a general solution is with using a comma both as a thousands separator and part of the text as in the question. So 999,999 could be a single number or two separate numbers. Also, 99,99,99 although not a valid number returns TRUE from ISNUMERIC and 99 from VAL. You could try and find the longest possible number but if faced with a string such as 99,999,99 you would have to backtrack and a simple 2-state model wouldn't work.
So I think the only practical solution at this kind of simple level is for the function to be called with a parameter which tells it either (a) to treat a comma as a thousands separator (and basically ignore it) or (b) to treat it as a delimiter and therefore to stop adding characters to a number whenever a comma is encountered.
It should be easy enough to be able to process an initial minus sign if required, but that isn't in the present version yet.
Function GetNthNumber(s As String, n As Integer, Optional CommaAsThousands As Boolean = True) As Variant
Dim c, testNumber, number As String
' Ignore commas if treated as thousands separator
If CommaAsThousands Then s = Replace(s, ",", "")
s = s & "x"
Dim i, j, count As Integer
Dim inNumber As Boolean
inNumber = False
' Loop through each character of string
For i = 1 To Len(s)
c = Mid(s, i, 1)
' Part of a number - append new character or finish number
If inNumber Then
If IsNumeric(number & c) And (CommaAsThousands Or c <> ",") Then
number = number & c
Else
inNumber = False
If count = n Then Exit For
End If
Else
' Not part of a number - start new number or do nothing
If IsNumeric(c) Then
inNumber = True
number = c
count = count + 1
End If
End If
Next i
'Return nth number or #Value error
If count = n Then
GetNthNumber = Val(number)
Else
GetNthNumber = CVErr(xlErrValue)
End If
End Function
Here are the results when called in the two different ways (first row with comma as thousands separator and second row with comma as delimiter):-