在Excel VBA中,如何将求和函数转换为其显式形式?

在Excel VBA中,如何将求和函数转换为其显式形式?,excel,vba,excel-formula,Excel,Vba,Excel Formula,excel单元格的公式形式为=SUM(I1:I5)。我们如何将其转换为显式形式: =I1+I2+I3+I4+I5 我编写了一个函数,通过字符串操作来实现这一点 我试过了 前=SUM(C2:C4,E2:G2,D7:E8) =$C$2+$C$3+$C$4+$E$2+$F$2+$G$2+$D$7+$E$7+$D$8+$E$8之后 用法,使用目标单元格作为参数调用ExpandSum() Public Sub ExpandSum(ByVal r_target As Range) Dim f

excel单元格的公式形式为
=SUM(I1:I5)
。我们如何将其转换为显式形式:

=I1+I2+I3+I4+I5

我编写了一个函数,通过字符串操作来实现这一点

我试过了

  • =SUM(C2:C4,E2:G2,D7:E8)
  • =$C$2+$C$3+$C$4+$E$2+$F$2+$G$2+$D$7+$E$7+$D$8+$E$8之后
用法,使用目标单元格作为参数调用
ExpandSum()

Public Sub ExpandSum(ByVal r_target As Range)

    Dim f As String
    f = Mid(r_target.Formula, 2)
    ' Is it a SUM function
    If Left(f, 3) = "SUM" Then
        ' Take the arguments of SUM
        f = Mid(f, 5, Len(f) - 5)
        
        ' make an array of string with each
        ' arument
        Dim parts() As String
        parts = Split(f, ",")
        
        Dim i As Long, n As Long
        n = UBound(parts) + 1
        Dim rng As Range, cl As Range
        Dim col As New Collection
        For i = 1 To n
            ' for each argument find the range of cells
            Set rng = Range(parts(i - 1))
            For Each cl In rng
                ' Add each cell in range into a list
                col.Add cl.Address
            Next
        Next i
        ' Transfer list to array
        ReDim parts(0 To col.Count - 1)
        For i = 1 To col.Count
            parts(i - 1) = col(i)
        Next i
        ' Combine parts into one expression
        ' ["A1","A2","A3"] => "A1+A2+A3"
        f = Join(parts, "+")
        r_target.Formula = "=" & f
    End If

End Sub
使用当前选择调用的示例

Public Sub ThisExpandSum()
    Call ExpandSum(Selection)
End Sub

注意事项我不知道如果总和包含文字值或来自不同工作表的单元格,它将如何运行。这是以后添加的功能。

请使用下一个功能:

Function SUMbyItems(strFormula As String) As String
   If strFormula = "" Then Exit Function
  Dim rng As Range, Ar As Range, c As Range, strF As String
  Set rng = Range(left(Split(strFormula, "(")(1), Len(Split(strFormula, "(")(1)) - 1))
  For Each Ar In rng.Areas
        For Each c In Ar.cells
            strF = strF & c.Address(0, 0) & "+"
        Next c
  Next
  strF = left(strF, Len(strF) - 1)
  SUMbyItems = "=SUM(" & strF & ")"
End Function
可以使用它,选择具有包含范围的求和公式的单元格,然后运行下一个子单元格:

Sub testSumByItems()
   Debug.Print SUMbyItems(ActiveCell.Formula)
End Sub
如果它返回您想要的结果,并且您需要使用其扩展版本更改范围公式,您可以使用(在上面的测试子部分中):


这感觉就像是一篇关于代码高尔夫的帖子。这是我的函数版本,可以实现这一点

函数显式(ByVal表达式作为字符串)作为字符串
暗淡的strStart和长的一样,强壮的和长的一样
strStart=InStr(1,UCase(表达式),“和(“)+4
如果strStart=0,则
“找不到金额
ExplicitSum=表达式
退出功能
如果结束
strEnd=InStr(strStart+1,表达式“)”)
如果strEnd=0,则
'未找到右括号
ExplicitSum=表达式
退出功能
如果结束
调暗LeftText作为字符串,RightText作为字符串,AddressText作为字符串
LeftText=Replace(左(表达式,strStart-1),“sum”(“,”,Compare:=vbTextCompare)
AddressText=Mid(表达式、strStart、strEnd-strStart)
RightText=Right(表达式,Len(表达式)-强度+1)
如果InStr(1,UCase(rightext),“SUM”()0,则
'递归将处理同一公式中的多个和
RightText=明确(RightText)
如果结束
模糊范围作为范围
出错时继续下一步
设置SumRange=范围(AddressText)
错误转到0
如果SumRange什么都不是,那么
'无效的AddressText-命名范围或间接引用
ExplicitSum=左文本&地址文本&右文本
退出功能
如果结束
Dim Addresses()作为字符串
ReDim地址(1到SumRange.Cells.Count)
变暗单元格作为范围,i作为长度:i=1
对于SumRange中的每个单元格
地址(i)=单元格地址(假,假)
i=i+1
下一个细胞
ExplicitSum=LeftText&Join(地址“+”)&rightext
端函数
如何使用该功能的示例:

子测试()
MsgBox明确(“=5+和(A1:D1)/20”)
'显示“=5+(A1+B1+C1+D1)/20”
端接头
子示例用法()
'转换后将公式放回单元格中
范围(“E1”)。公式=明确(范围(“E1”)。公式)
端接头
私有子工作表_更改(ByVal目标作为范围)
'在公式中包含SUM的每个单元格上运行
如果LCase(Target.Cells(1,1).Formula)像“*sum(*”,那么Target.Cells(1,1).Formula=ExplicitSum(Target.Cells(1,1).Formula)
端接头
  • 将处理复杂的公式

  • 将在同一公式中处理多个和

  • 将在总和内使用命名范围


  • 有先例的另一种方法:

    Sub expandSUM()
        Range("A1").Formula = "=SUM(I1:I5)" 'the formula must be in the cell
        Output = "=SUM("
        
        For Each cl In Range("A1").Precedents
            Output = Output & "+" & cl.Address(False, False)
        Next
        Debug.Print Replace(Output, "(+", "(") & ")"
    End Sub
    

    没有内置的方法可以做到这一点。你想自己操纵字符串来完成这一点吗?要正确地做到这一点,你需要能够解析Excel公式语法;然后你的代码能够理解
    I1:I5
    如何代表5个单独单元格的
    范围。其他任何东西都是一种黑客行为(可能有用!)这就引出了一个问题……为什么?另外,
    =SUM(I1:I5)
    =I1+I2+I3+I4+I5
    不是一回事。@DarrenBartrup Cook将
    '1
    2
    TRUE
    输入三个单元格,比较SUM和+。然后将其中一个单元格更改为
    hello
    ,看看会发生什么。:)@MathieuGuindon为了回答您的原因,扩展的公式将保存在csv中,然后由另一个与excel函数无关的应用程序读取。tnxy您的函数不检查公式是否有求和。并在找到的第一个括号上拆分。任何输入,如
    =Count(A1:B5)/SUM(A1:B5)
    不会被正确转换。@Cubbleson:当然不会!这不是我的功能。这是OP问题的答案。他问过这样一个公式吗?我错过了?你希望它也在你的帐户里存一些钱吗…?是的,请!我非常希望。@Cubbleson:那么,请稍等一下…)大约一个小时后检查您的帐户。如果公式中的和前面有任何项,那么您的函数将不起作用。任何输入,如
    =1+Sum(A1:B1)
    都不起作用。@cubbleson-true,但这不是op问题中的要求。我正在等待有人发布表达式树解析器并使用它。
    Sub expandSUM()
        Range("A1").Formula = "=SUM(I1:I5)" 'the formula must be in the cell
        Output = "=SUM("
        
        For Each cl In Range("A1").Precedents
            Output = Output & "+" & cl.Address(False, False)
        Next
        Debug.Print Replace(Output, "(+", "(") & ")"
    End Sub