【问题标题】:How can I convert SUMIF to SUMIFS excel formula using VBA如何使用 VBA 将 SUMIF 转换为 SUMIFS excel 公式
【发布时间】:2018-04-15 20:55:18
【问题描述】:

我有使用 SUMIF(range,criteria,[sum_range]) 公式的旧 Excel 工作簿,但想将它们转换为 SUMIFS(sum_range,criteria_range1,criteria1),这是一个更易于使用的可扩展函数(可以添加多个条件和范围)。

我正在寻找 VBA 代码来为工作表中的所有公式进行此转换。公式的所有其他部分应与以前完全相同。

【问题讨论】:

    标签: excel vba sumifs


    【解决方案1】:

    下面的代码可以运行,但有点草率(例如使用 Select)。运行也需要一段时间。关于如何改进代码的任何其他想法或建议?

    Sub WSConvertSUMIF()
    
    Dim WS As Worksheet
    Set WS = ActiveSheet
    
    For Each cel In ActiveSheet.Cells
        cel.Select
        Call MakeSUMIFS
    Next cel
    
    End Sub
    
    Sub MakeSUMIFS()
    
    Dim formulastring As String
    Dim sumifPos As Integer
    
    formulastring = ActiveCell.Formula
    
    NewFormulaString = SUMIF2SUMIFS(formulastring)
    If NewFormulaString <> "" Then
        ActiveCell.Formula = NewFormulaString
    End If
    
    End Sub
    
    
    Function SUMIF2SUMIFS(formulastring As String)
    
    Dim arg1, arg2, arg3, StringFinal As String
    Dim NewFormulaString As String
    NewFormulaString = ""
    
    sumifPos = InStr(1, formulastring, "SUMIF(")
    
    If sumifPos = 0 Then
        SUMIF2SUMIFS = ""
        Exit Function
    Else
        formulastringTmp = formulastring
    End If
    
    Do While sumifPos <> 0
    
        Prefix = Left(formulastringTmp, sumifPos - 1)
    
        formulastringTmp = Mid(formulastringTmp, sumifPos + 6,Len(formulastringTmp) - sumifPos - 5)
    
        arg1 = returnArg(formulastringTmp)
    
        formulastringTmp = Right(formulastringTmp, Len(formulastringTmp) - Len(arg1) - 1)
    
        arg2 = returnArg(formulastringTmp)
    
        formulastringTmp = Right(formulastringTmp, Len(formulastringTmp) - Len(arg2) - 1)
    
        arg3 = returnArg(formulastringTmp, True)
    
        suffix = Right(formulastringTmp, Len(formulastringTmp) - Len(arg3))
    
        StringFinal = Prefix & "SUMIFS(" & arg3 & "," & arg1 & "," & arg2 & suffix
    
        formulastringTmp = StringFinal
    
        sumifPos = InStr(1, formulastringTmp, "SUMIF(")
    
    Loop
    
    SUMIF2SUMIFS = StringFinal
    
    End Function
    
    Function returnArg(formulastringTmp, Optional FinalArg As Boolean)
    
    Dim arg As String
    bracketPos = InStr(1, formulastringTmp, "(")
    commaPos = InStr(1, formulastringTmp, ",")
    bracketClsPos = InStr(formulastringTmp, ")")
    formulastringTmpArg = formulastringTmp
    
    If FinalArg = True Then
    
        Do Until bracketPos = 0 Or bracketClsPos < bracketPos
            arg = arg & Left(formulastringTmpArg, bracketClsPos - 1)
    
        Loop
    
    Else
    
        Do Until bracketPos = 0 Or bracketPos > commaPos
    
            bracketClsPos = InStr(formulastringTmpArg, ")")
            arg = arg & Left(formulastringTmpArg, bracketClsPos)
            formulastringTmpArg = Right(formulastringTmpArg, Len(formulastringTmpArg) - bracketClsPos)
    
            bracketPos = InStr(1, formulastringTmpArg, "(")
            commaPos = InStr(1, formulastringTmpArg, ",")
    
        Loop
    End If
    
    If FinalArg = True Then
        arg = arg & Mid(formulastringTmpArg, 1, bracketClsPos - 1)
    Else
        arg = arg & Mid(formulastringTmpArg, 1, commaPos - 1)
    End If
    
    returnArg = arg
    
    End Function
    

    【讨论】:

    • 如果您在更改公式时暂停自动计算,您的代码将运行得更快
    【解决方案2】:

    这似乎适用于 sumif 的两种语法变体。

    Sub sumifPlural()
        Dim fnd As Range, parm As Variant, tmp As String
    
        With Worksheets("sheet6")
            Set fnd = .Cells.Find(what:="=sumif(", after:=.Cells(1), LookIn:=xlFormulas, LookAt:=xlPart, _
                                  SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
            If Not fnd Is Nothing Then
                Do While Not fnd Is Nothing
                    tmp = Mid(Left(fnd.Formula, Len(fnd.Formula) - 1), 8)
                    parm = Split(tmp, Chr(44))
                    If UBound(parm) = 2 Then
                        fnd.Formula = "=sumifs(" & Join(Array(parm(2), parm(0), parm(1)), Chr(44)) & ")"
                    Else
                        fnd.Formula = "=sumifs(" & Join(Array(parm(0), parm(0), parm(1)), Chr(44)) & ")"
                    End If
                    Set fnd = .Cells.FindNext(after:=fnd)
                Loop
            End If
        End With
    End Sub
    

    【讨论】:

    • 事后考虑,您可能希望在处理转换之前使用application.calculation = xlcalculationmanual,在转换完成后使用application.calculation = xlcalculationautomatic。这不会停止新公式的计算,但会在此过程中停止不必要的重复计算。
    • 感谢您的回答。查找单元格和拆分公式的非常有效的方法。唯一的缺点是我需要它来处理更复杂的公式(在参数中可能有一个“,”,或者应该包含在输出中的“sumif(”之前或之后的其他部分)。
    • 呃 ...是的,这可能是您认为重要足以包含在您的询问中的内容。跨度>
    猜你喜欢
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多