Чтобы получить соответствующее максимальное число из строки

69
5

Моя строка: su=45, nita = 30.8, raj = 60, gita = 40.8. Это имеет отношение к вопросу SO Извлечь максимальное число из строки. Я использую функцию maxNums и получаю результат как 40,8, тогда как я хотел бы, чтобы это было 60. Где поправка в строке кода даст мне желаемый результат. Код воспроизведен ниже, чтобы избежать перекрёстного reference.Если эта строка содержит все числа с десятичной точкой, я получаю правильный результат, но данные из внешних источников могут иметь целые числа.

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

спросил(а) 2019-01-15T20:08:00+03:00 1 год, 8 месяцев назад
1
Решение
70

Есть один или два вопроса с вашим кодом. Во-первых, регулярное выражение не ищет десятичные числа. Если вы измените его на

.Pattern = "\d+\.?(\d?)+"

это будет работать лучше. Короче:
\d+ = хотя бы одна цифра
.? = Необязательная точка
(\ d?) + = Дополнительные номера

Это не водостойкое выражение, но оно работает в некоторой степени, по крайней мере.

Вторая проблема - это потенциальная проблема различия десятичных символов, и в этом случае вам нужно будет выполнить поиск и замену перед обработкой.

ответил(а) 2019-01-15T20:23:00+03:00 1 год, 8 месяцев назад
41

Без 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


enter image description here

ответил(а) 2019-01-15T20:46:00+03:00 1 год, 8 месяцев назад
40

Если его всегда х = число, я думаю, что проще проходить по каждому значению с разделителями, а затем читать после = для значения:

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

ответил(а) 2019-01-15T20:30:00+03:00 1 год, 8 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема