Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 从字符串中获取适当的最大值_Excel_Vba - Fatal编程技术网

Excel 从字符串中获取适当的最大值

Excel 从字符串中获取适当的最大值,excel,vba,Excel,Vba,我的字符串是su=45,nita=30.8,raj=60,gita=40.8。这与上述问题有关 我正在使用maxNums函数,得到的结果是40.8,而我希望它是60。如果代码行中的修改将得到所需的结果。下面复制代码以避免交叉引用。如果此字符串包含所有带小数点的数字,则我将得到正确的结果,但考虑的来自外部来源的数据可能包含整数 Option Explicit Option Base 0 '<~~this is the default but I've included it becau

我的字符串是
su=45,nita=30.8,raj=60,gita=40.8
。这与上述问题有关 我正在使用
maxNums
函数,得到的结果是40.8,而我希望它是60。如果代码行中的修改将得到所需的结果。下面复制代码以避免交叉引用。如果此字符串包含所有带小数点的数字,则我将得到正确的结果,但考虑的来自外部来源的数据可能包含整数

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
选项显式

选项库0'您的代码有一两个问题。第一个是正则表达式不寻找十进制数。如果你把它改成

.Pattern = "\d+\.?(\d?)+"
这样会更好。简而言之:
\d+=至少一位数字
.? = 可选点
(\d?)+=可选数字

这不是一个防水表达式,但至少在某种程度上是有效的


第二个问题是不同十进制符号的潜在问题,在这种情况下,您需要在处理之前进行一些搜索和替换。

您的代码有一两个问题。第一个是正则表达式不寻找十进制数。如果你把它改成

.Pattern = "\d+\.?(\d?)+"
这样会更好。简而言之:
\d+=至少一位数字
.? = 可选点
(\d?)+=可选数字

这不是一个防水表达式,但至少在某种程度上是有效的

第二个问题是不同十进制符号的潜在问题,在这种情况下,您需要在处理之前进行一些搜索和替换。

如果其始终为x=number,我认为循环每个分隔值,然后读取值的
=
更简单:

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
如果它总是x=number,我认为循环每个分隔值更简单,然后读取值的
=

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

不带
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

不带
正则表达式

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

将表达式更改为
\d+\.?(\d?)+
将允许在decimal@Sam我使用了基于正则表达式的解决方案,以便在链接的SO帖子的各种备选方案中更加熟悉正则表达式。在链接文章中,你能对这种方法与其他方法进行比较吗?在很多情况下,熟练使用正则表达式是一个很好的理由。拆分(如@alex-k的例子)可能更容易阅读,我也可以选择其中之一。如果在同一个系统中有其他用途,我通常会选择regexp,如果只有一个地方可以使用,我会避免使用它。@Sam感谢您坦率而清晰的意见。在决定这两种方法之前,我想再做一点测试。@Sam感谢你引导我走向正确的方向。我还觉得熟练使用正则表达式是在很多情况下使用它的一个很好的理由将表达式改为
\d+\。(\d?)+
将允许在decimal@Sam我使用了基于正则表达式的解决方案,以便在链接的SO帖子的各种备选方案中更加熟悉正则表达式。在链接文章中,你能对这种方法与其他方法进行比较吗?在很多情况下,熟练使用正则表达式是一个很好的理由。拆分(如@alex-k的例子)可能更容易阅读,我也可以选择其中之一。如果在同一个系统中有其他用途,我通常会选择regexp,如果只有一个地方可以使用,我会避免使用它。@Sam感谢您坦率而清晰的意见。在决定这两种方法之前,我想再做一点测试。@Sam感谢你引导我走向正确的方向。我还觉得熟练使用正则表达式是在许多情况下使用它的一个充分理由。即使忽略数值前的等号,我们的解决方案也能给出正确的结果。谢谢你的宽容。不过,我选择基于正则表达式的解决方案,以便更流畅地使用基于正则表达式的解决方案。即使忽略数值前的等号,您的解决方案也会给出正确的结果。谢谢你的宽容。不过,我选择基于正则表达式的解决方案,以便更流畅地使用基于正则表达式的解决方案。您的解决方案为原始声明的样本数据字符串提供了正确的结果。由于此解决方案在代码中使用
InStr(标记(i),“=”
,因此在某些数据字符串中省略
=
符号的情况下,可能会限制灵活性。谢谢你的宽容。不过,我选择基于正则表达式的解决方案,以便更流畅地使用基于正则表达式的解决方案。您的解决方案为原始声明的样本数据字符串提供了正确的结果。由于此解决方案在代码中使用
InStr(标记(i),“=”
,因此在某些数据字符串中省略
=
符号的情况下,可能会限制灵活性。谢谢你的宽容。不过,我选择了基于正则表达式的解决方案,以便更流畅地使用基于正则表达式的解决方案。