【问题标题】:Extract maximum number from a string从字符串中提取最大数
【发布时间】:2018-02-04 17:22:47
【问题描述】:

我正在尝试使用 Excel 中的函数从字符串中提取所有数字。 第二次,我想提取字符串中包含的最大值。

我的字符串看起来像: ATCG=12.5,TTA=2.5,TGC=60.28

所需输出: 60.28

我第一次尝试用我的函数提取所有数字,但它只在第一个数字上停止。

Function MyCode(ByVal txt As String) As String
    With CreateObject("VBScript.RegExp")
        .Pattern = "\d.+"
        If .test(txt) Then MyCode = .Execute(txt)(0)
    End With
End Function

【问题讨论】:

    标签: string excel numbers vba


    【解决方案1】:

    这里有一些 VBA (不是 vbscript),您可以根据自己的需要进行调整:

    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
    

    注意:

    这给出了String 而不是Number

    编辑#1:

    在 Excel-VBA 中,代码必须放在标准模块中。

    用户定义函数 (UDF) 非常易于安装和使用:

    1. ALT-F11 调出 VBE 窗口
    2. ALT-I ALT-M 打开一个新模块
    3. 粘贴内容并关闭 VBE 窗口

    如果您保存工作簿,UDF 将与它一起保存。 如果您使用的是 2003 年以后的 Excel 版本,则必须保存 文件为 .xlsm 而不是 .xlsx

    要删除 UDF:

    1. 如上所示打开 VBE 窗口
    2. 清除代码
    3. 关闭 VBE 窗口

    要使用 Excel 中的 UDF:

    =MyCode(A1)
    

    要了解有关宏的更多信息,请参阅:

    http://www.mvps.org/dmcritchie/excel/getstarted.htm

    http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx

    有关 UDF 的详细信息,请参阅:

    http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx

    必须启用宏才能正常工作!

    【讨论】:

    • 嗨,加里,谢谢您的代码。它在我这边不起作用,在输出#NOM?也许是我的 Excel 版本
    • @user979974 我假设您的 #NOM? 与我的 #NAME? 相同。请参阅我的 EDIT#1。
    • 与#NAME 相同?我按照你在编辑中的建议做了,它返回-9999。我正在使用 Excel 2003。奇怪的是它在你身边而不是我的身边工作:-(
    • @user979974 得到 -9999 意味着宏找不到任何数字子字符串。确保您指向一个“好”的单元格。
    • 我在这个字符串上使用了函数:ATCG=12.5,TTA=2.5,TGC=60.28
    【解决方案2】:

    如果您拥有包含 AGGREGATE 函数的 Excel (2010+) 版本,则实际上不需要 VBA,您可以使用工作表公式来完成:

    =AGGREGATE(14,6,--TRIM(MID(SUBSTITUTE(SUBSTITUTE(A1,",",REPT(" ",99)),"=",REPT(" ",99)),seq_99,99)),1)
    

    其中 seq_99 是一个命名公式,它指的是:

    =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)
    

    函数产生一个数组,其中一些值是数字; AGGREGATE 函数返回数组中的最大值,忽略错误。

    以下公式适用于早期版本的 Excel,必须作为数组公式输入,方法是按住 ctrl + shift 同时点击 enter 如果您正确执行此操作,Excel 将在公式周围放置大括号 {...}

    如果你有2007,可以使用IFERROR

    =MAX(IFERROR(--TRIM(MID(SUBSTITUTE(SUBSTITUTE(A2,",",REPT(" ",99)),"=",REPT(" ",99)),seq_99,99)),0))
    

    对于早期版本,您可以使用:

    =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))))
    

    【讨论】:

      【解决方案3】:

      您的小数点分隔符可能与美国小数点分隔符不同。

      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
      

      【讨论】:

        【解决方案4】:

        将所有混合数作为双精度数收集到一个数组中并返回最大值。

        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
        

        【讨论】:

        • 嗨 Jeeped,我试过你的脚本,不幸的是,当我应用 maxNums(A2) 时,我在输出#VALUE
        • 好吧,TBH,我从不对我的结果进行 Photoshop 处理,所以如果你'有输出#VALUE',那么我建议停下来,一些手表和 F8 来逐步完成。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-06-21
        • 1970-01-01
        • 2017-11-13
        • 2021-12-23
        • 2019-04-11
        • 2021-03-15
        • 1970-01-01
        相关资源
        最近更新 更多