Чтобы получить соответствующее максимальное число из строки - PullRequest
0 голосов
/ 15 января 2019

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

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

Ответы [ 3 ]

0 голосов
/ 15 января 2019

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

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
0 голосов
/ 15 января 2019

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

0 голосов
/ 15 января 2019

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...