I am trying to extract all numbers from a string with a function in Excel. In the second time, I would like to extract the maximum value contains in the string.
Your decimal separator may be different from the US decimal separator.
Public Function MyCode(ByVal txt As String) As String
Dim maxi As Double, db As Double
maxi = -9 ^ 9
arr = Split(txt, ",")
For Each a In arr
If InStr(a, "=") Then
a = Mid(a, InStr(a, "=") + 1)
ar = Replace(a, ".", Format(0, "."))
If IsNumeric(ar) Then
db = ar
If db > maxi Then maxi = db: ok = True
End If
End If
Next a
If ok = True Then
MyCode = CStr(maxi)
End If
End Function
Here is some VBA (not vbscript) that you can adapt to you needs:
Public Function MyCode(ByVal txt As String) As String
Dim maxi As Double, db As Double
maxi = -9999
arr = Split(Replace(txt, "=", ","), ",")
For Each a In arr
If IsNumeric(a) Then
db = CDbl(a)
If db > maxi Then maxi = db
End If
Next a
MyCode = CStr(maxi)
End Function
NOTE:
This gives a String
and not a Number
.
EDIT#1:
In Excel-VBA, the code must be placed in a standard module.
User Defined Functions (UDFs) are very easy to install and use:
If you save the workbook, the UDF will be saved with it. If you are using a version of Excel later then 2003, you must save the file as .xlsm rather than .xlsx
To remove the UDF:
To use the UDF from Excel:
=MyCode(A1)
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
and for specifics on UDFs, see:
http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx
Macros must be enabled for this to work!
Collect all of the mixed numbers as doubles in an array and return the maximum value.
Option Explicit
Option Base 0 '<~~this is the default but I've included it because it has to be 0
Function maxNums(str As String)
Dim n As Long, nums() As Variant
Static rgx As Object, cmat As Object
'with rgx as static, it only has to be created once; beneficial when filling a long column with this UDF
If rgx Is Nothing Then
Set rgx = CreateObject("VBScript.RegExp")
End If
maxNums = vbNullString
With rgx
.Global = True
.MultiLine = False
.Pattern = "\d*\.\d*"
If .Test(str) Then
Set cmat = .Execute(str)
'resize the nums array to accept the matches
ReDim nums(cmat.Count - 1)
'populate the nums array with the matches
For n = LBound(nums) To UBound(nums)
nums(n) = CDbl(cmat.Item(n))
Next n
'test array
'Debug.Print Join(nums, ", ")
'return the maximum value found
maxNums = Application.Max(nums)
End If
End With
End Function
You don't really need VBA for this if you have a version of Excel (2010+) that includes the AGGREGATE
function, you can do it with a worksheet formula:
=AGGREGATE(14,6,--TRIM(MID(SUBSTITUTE(SUBSTITUTE(A1,",",REPT(" ",99)),"=",REPT(" ",99)),seq_99,99)),1)
where seq_99 is a Named Formula that refers to:
=IF(ROW(INDEX($1:$65535,1,1):INDEX($1:$65535,255,1))=1,1,(ROW(INDEX($1:$65535,1,1):INDEX($1:$65535,255,1))-1)*99)
The function results in an array, some of the values are numeric; the AGGREGATE
function returns the largest value in the array, ignoring errors.
The formulas below are for earlier versions of Excel and must be entered as array formulas, by holding down ctrl + shift while hitting enter If you do this correctly, Excel will place braces {...}
around the formula.
If you have 2007, you can use IFERROR
=MAX(IFERROR(--TRIM(MID(SUBSTITUTE(SUBSTITUTE(A2,",",REPT(" ",99)),"=",REPT(" ",99)),seq_99,99)),0))
For earlier versions, you can use:
=MAX(IF(ISERROR(--TRIM(MID(SUBSTITUTE(SUBSTITUTE(A3,",",REPT(" ",99)),"=",REPT(" ",99)),seq_99,99))),0,--TRIM(MID(SUBSTITUTE(SUBSTITUTE(A3,",",REPT(" ",99)),"=",REPT(" ",99)),seq_99,99))))