编辑VBA UDF以对括号中的数字求和,同时忽略括号中的单词

时间:2018-05-22 22:00:05

标签: excel vba excel-vba user-defined-functions excel-vba-mac

我有一个UDF,它会在给定的单元格中查找括号内的数字,然后对给定单元格中括号内的所有数字求和,它在90%的时间内运行良好,但是当我在括号内有一些不是一个数字即一个单词或短语,它将返回#VALUE!我试图解决这个问题,以便忽略括号内的单词等。也出于某种原因,有一个"。"在括号之后使得括号中的数字在"。"之前。当他们不应该被忽略时被忽略。

上面解释的问题的屏幕截图

screenshot of problems explained above

功能如下

Public Function Addum(rng As Range) As Double
    Dim s As String, L As Long, temp As String
    Dim CH As String
    s = rng.Value
    L = Len(s)
    For i = 1 To L
        CH = Mid(s, i, 1)
        If CH Like "[0-9]" Or CH = "." Or CH = "(" Or CH = ")" Then
            temp = temp & CH
        Else
            temp = temp & " "
        End If
    Next i

    temp = Application.WorksheetFunction.Trim(temp)
    arr = Split(temp, " ")
    For Each a In arr
        If Left(a, 1) = "(" Then
            a = Mid(a, 2, Len(a) - 2)
            If IsNumeric(a) Then
                Addum = Addum + CDbl(a)
            End If
        End If
    Next a
End Function

此问题与Excel: Sum numbers inside a text block in a cell不同 因为我要求它在括号内有单词时有效,并且有"。"在括号后面。

提前感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:1)

这是一个迟到的 udf。

Function sumNums(str As String) As Double
    Dim n As Long
    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

    sumNums = 0

    With rgx
        .Global = True
        .MultiLine = False
        .Pattern = "\(\d+(\.\d{1,2})?\)"
        If .Test(str) Then
            Set cmat = .Execute(str)
            'sum the matches
            For n = 0 To cmat.Count - 1
                sumNums = sumNums + Abs(CDbl(cmat.Item(n)))
            Next n
        End If
    End With
End Function

对于遇到问题的,这是我能想到的最简单的。

Option Explicit

Public Function Addum(str As String) As Double
    Dim i As Long, j As Long, tmp As Variant

    tmp = Split(str, Chr(40))

    For i = LBound(tmp) + 1 To UBound(tmp)
        If IsNumeric(Split(tmp(i), Chr(41))(0)) Then _
            Addum = Application.Sum(Addum, Split(tmp(i), Chr(41))(0))
    Next i

End Function

enter image description here

答案 1 :(得分:1)

Public Function Addum(rng As Range) As Double
    Dim s As String, temp As String, i As Long
    Dim CH As String, inParens As Boolean, q As String
    s = rng.Value
    For i = 1 To Len(s)
        CH = Mid(s, i, 1)
        If CH = "(" Then
            inParens = True
            q = ""
        ElseIf CH = ")" Then
            inParens = False
            temp = temp & " " & q
        Else
            If inParens Then q = q & _
               IIf(CH Like "[0-9]" Or CH = ".", CH, " ")
        End If
    Next i

    temp = Application.WorksheetFunction.Trim(temp)
    arr = Split(temp, " ")
    For Each a In arr
        If IsNumeric(a) Then Addum = Addum + CDbl(a)
    Next a
End Function