Reputation: 2838
My string is su=45, nita = 30.8, raj = 60, gita = 40.8
. This has reference to SO question Extract maximum number from a string
I am utilizing maxNums
function and getting result as 40.8 whereas I would like it to be 60. Where an amendment in code line would get me the desired result.Code reproduced below to avoid cross reference.If this string contains all numbers with decimal point then I get the correct result but the data in consideration from external sources could have whole numbers.
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
Upvotes: 0
Views: 65
Reputation: 96781
Without Regex
:
Public Function maxNums(str As String) As Double
Dim i As Long, L As Long, s As String, wf As WorksheetFunction, brr()
Set wf = Application.WorksheetFunction
L = Len(str)
For i = 1 To L
s = Mid(str, i, 1)
If s Like "[0-9]" Or s = "." Then
Else
Mid(str, i, 1) = " "
End If
Next i
str = wf.Trim(str)
arr = Split(str, " ")
ReDim brr(LBound(arr) To UBound(arr))
For i = LBound(arr) To UBound(arr)
brr(i) = CDbl(arr(i))
Next i
maxNums = wf.Max(brr)
End Function
Upvotes: 0
Reputation: 5731
There are one or two issues with your code. The first one is that the regular expression isn't looking for decimal numbers. If you change it to
.Pattern = "\d+\.?(\d?)+"
it will work better. In short:
\d+ = At least one digit
.? = An optional dot
(\d?)+ = Optional numbers
This is not a waterproof expression, but it works to some extent at least.
The second issue is the potential problem of differing decimal symbols, in which case you will need to do some search and replace before processing.
Upvotes: 2
Reputation: 175936
If its always x=number I think it's simpler to loop over each delimited value then read past the =
for the value:
Function MaxValue(data As String)
Dim i As Long, value As Double
Dim tokens() As String: tokens = Split(data, ",")
For i = 0 To UBound(tokens)
'// get the value after = as a double
value = CDbl(Trim$(Mid$(tokens(i), InStr(tokens(i), "=") + 1)))
If (value > MaxValue) Then MaxValue = value
Next
End Function
Upvotes: 0