Excel 在小计中插入求和公式的多个(嵌套)小计VBA代码

Excel 在小计中插入求和公式的多个(嵌套)小计VBA代码,excel,vba,Excel,Vba,我想创建一个嵌套的小计宏,这意味着“国家”列有一个小计,而“城市”列有一个小计。我使用下面的代码来获取国家的小计,但我不知道如何扩展代码来获取城市的小计 代码中的一个条件是小计行中应该存在求和公式,以确保具有正确的范围 我尝试了不同的方法来获取城市小计,但是当宏插入一个新的小计以创建一个新的小计时,总和公式的范围将会改变 我的想法是分两步编写代码: 将国家的小计作为硬值--->具有硬值有助于我们避免公式扭曲,因为宏为城市创建小计 以总和公式获取城市小计 下面是我用来为国家创建小计的当前代码,作为

我想创建一个嵌套的小计宏,这意味着“国家”列有一个小计,而“城市”列有一个小计。我使用下面的代码来获取国家的小计,但我不知道如何扩展代码来获取城市的小计

代码中的一个条件是小计行中应该存在求和公式,以确保具有正确的范围

我尝试了不同的方法来获取城市小计,但是当宏插入一个新的小计以创建一个新的小计时,总和公式的范围将会改变

我的想法是分两步编写代码:

  • 将国家的小计作为硬值--->具有硬值有助于我们避免公式扭曲,因为宏为城市创建小计
  • 以总和公式获取城市小计 下面是我用来为国家创建小计的当前代码,作为内部的总和公式
  • 我用于为列国家/地区创建小计的代码:

    Dim iCol As Integer 'number of columns
    Dim i As Integer 'Macro starts from this row number
    Dim j As Integer 'Macro continues with this row number in the loop
    
    Worksheets("Example").Activate
    
    Application.ScreenUpdating = False
    i = 2 'starts from row 2
    j = i
    'Loops throught Col A Checking for match then when there is no match add Sum
    Do While Range("A" & i) <> ""
        If Range("A" & i) <> Range("A" & (i + 1)) Then
            Rows(i + 1).Insert
            Range("A" & (i + 1)) = "Subtotal " & Range("A" & i).Value
            For iCol = 3 To 4 'Columns to Sum
                Cells(i + 1, iCol).Formula = "=SUM(R" & j & "C:R" & i & "C)"
            Next iCol
            Range(Cells(i + 1, 1), Cells(i + 1, 4)).Font.Bold = True
            Range(Cells(i + 1, 1), Cells(i + 1, 4)).Interior.Color = RGB(221, 237, 245)
            i = i + 2
            j = i
        Else
            i = i + 1
        End If
    Loop
    Application.ScreenUpdating = True
    
    Dim iCol As Integer'列数
    Dim i As Integer'宏从此行号开始
    “Dim j As Integer”宏在循环中继续此行号
    工作表(“示例”)。激活
    Application.ScreenUpdating=False
    i=2'从第2行开始
    j=i
    '循环通过Col A检查匹配,然后在没有匹配时添加和
    Do While范围(“A”和“i”)
    如果范围(“A”&i)范围(“A”&i+1”),则
    行(i+1)。插入
    范围(“A”和(i+1))=“小计”和范围(“A”和i).值
    对于iCol=3到4'列的总和
    单元格(i+1,iCol)。公式=“=SUM(R”&j&“C:R”&i&“C)”
    下一个iCol
    范围(单元格(i+1,1)、单元格(i+1,4))。Font.Bold=True
    范围(单元格(i+1,1),单元格(i+1,4)).Interior.Color=RGB(221237245)
    i=i+2
    j=i
    其他的
    i=i+1
    如果结束
    环
    Application.ScreenUpdating=True
    
    下面是运行代码后我想要的屏幕截图

    这是我想要的输出


    感谢您的帮助。

    事实上,这比看起来要复杂得多:

    它可以对无限条件列和无限小计行执行此操作。只是别忘了调整成本:

    Const StartRow As Long = 2      'omit headers
    Const CriteriaCount As Long = 3 'amount of criteria columns (here countries + cities + Houses)
    Const SumtotalCount As Long = 3 'amount columns to sumtotal
    
    守则:

    Option Explicit
    
    Public Sub CreateSubtotals()
        Dim ws As Worksheet
        Set ws = ThisWorkbook.Worksheets("Example")
    
        Const StartRow As Long = 2      'omit headers
        Const CriteriaCount As Long = 3 'amount of criteria columns (here countries + cities + Hauses)
        Const SumtotalCount As Long = 3 'amount columns to sumtotal
    
        Dim Criteria() As Variant
        Criteria = ws.Cells(StartRow, 1).Resize(ColumnSize:=CriteriaCount).Value
    
        ReDim StartRows(1 To CriteriaCount)
        Dim i As Long
        For i = LBound(StartRows) To UBound(StartRows)
            StartRows(i) = StartRow
        Next i
    
        Dim iRow As Long, iCol As Long
        iRow = StartRow + 1
    
        Dim LastRow As Long
        LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
        Dim RowsAdded As Long, CriteriaChanged As Boolean
    
        Do While iRow < LastRow + 2
            For iCol = CriteriaCount To 1 Step -1
                CriteriaChanged = False
                For i = 1 To iCol
                    If Criteria(1, i) <> ws.Cells(iRow, i).Value Then CriteriaChanged = True
                Next i
    
                If CriteriaChanged Then
                    ws.Rows(iRow).Insert
                    RowsAdded = RowsAdded + 1
    
                    ws.Cells(iRow, iCol).Value = "Subtotal " & Criteria(1, iCol)
                    If iCol = CriteriaCount Then
                        ws.Cells(iRow, CriteriaCount + 1).Resize(ColumnSize:=SumtotalCount).Formula = "=Sum(" & ws.Cells(StartRows(iCol), CriteriaCount + 1).Resize(RowSize:=iRow - StartRows(iCol)).Address(True, False) & ")"
                    Else
                        ws.Cells(iRow, CriteriaCount + 1).Resize(ColumnSize:=SumtotalCount).Formula = "=Sumif(" & ws.Cells(StartRows(iCol), iCol + 1).Resize(RowSize:=iRow - StartRows(iCol)).Address(True, True) & ",""Subtotal*""," & ws.Cells(StartRows(iCol), CriteriaCount + 1).Resize(RowSize:=iRow - StartRows(iCol)).Address(True, False) & ")"
                    End If
    
                    ws.Cells(iRow, iCol).Resize(ColumnSize:=SumtotalCount + CriteriaCount - iCol + 1).Interior.ThemeColor = 7 + iCol 'whatever you want
    
                    For i = iCol To UBound(StartRows)
                        StartRows(i) = 0
                    Next i
                    iRow = iRow + 1
                End If
            Next iCol
    
            If RowsAdded <> 0 Then
                Criteria = ws.Cells(iRow, 1).Resize(ColumnSize:=CriteriaCount).Value
                For i = LBound(StartRows) To UBound(StartRows)
                    If StartRows(i) = 0 Then StartRows(i) = iRow
                Next i
    
                LastRow = LastRow + RowsAdded 'if we insert a row we must increas last row
                RowsAdded = 0
            End If
    
            iRow = iRow + 1
        Loop
    End Sub
    
    选项显式
    公共小计()
    将ws设置为工作表
    设置ws=ThisWorkbook.Worksheets(“示例”)
    Const StartRow长度=2'忽略标题
    Const CriteriaCount As Long=3'标准列的数量(此处为国家+城市+住宅)
    Const SumtotalCount As Long=3'金额列到SUMTOTALL
    Dim Criteria()作为变量
    Criteria=ws.Cells(StartRow,1)。调整大小(ColumnSize:=CriteriaCount)。值
    ReDim StartRows(1到标准计数)
    我想我会坚持多久
    对于i=LBound(StartRows)到UBound(StartRows)
    StartRow(i)=StartRow
    接下来我
    暗淡的iRow和长的一样,iCol和长的一样
    iRow=StartRow+1
    最后一排一样长
    LastRow=ws.Cells(ws.Rows.Count,“A”).End(xlUp).Row
    Dim RowsAdded为Long,Criteria更改为Boolean
    当iRow

    实际上,这比看起来要复杂得多:

    它可以对无限条件列和无限小计行执行此操作。只是别忘了调整成本:

    Const StartRow As Long = 2      'omit headers
    Const CriteriaCount As Long = 3 'amount of criteria columns (here countries + cities + Houses)
    Const SumtotalCount As Long = 3 'amount columns to sumtotal
    
    守则:

    Option Explicit
    
    Public Sub CreateSubtotals()
        Dim ws As Worksheet
        Set ws = ThisWorkbook.Worksheets("Example")
    
        Const StartRow As Long = 2      'omit headers
        Const CriteriaCount As Long = 3 'amount of criteria columns (here countries + cities + Hauses)
        Const SumtotalCount As Long = 3 'amount columns to sumtotal
    
        Dim Criteria() As Variant
        Criteria = ws.Cells(StartRow, 1).Resize(ColumnSize:=CriteriaCount).Value
    
        ReDim StartRows(1 To CriteriaCount)
        Dim i As Long
        For i = LBound(StartRows) To UBound(StartRows)
            StartRows(i) = StartRow
        Next i
    
        Dim iRow As Long, iCol As Long
        iRow = StartRow + 1
    
        Dim LastRow As Long
        LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    
        Dim RowsAdded As Long, CriteriaChanged As Boolean
    
        Do While iRow < LastRow + 2
            For iCol = CriteriaCount To 1 Step -1
                CriteriaChanged = False
                For i = 1 To iCol
                    If Criteria(1, i) <> ws.Cells(iRow, i).Value Then CriteriaChanged = True
                Next i
    
                If CriteriaChanged Then
                    ws.Rows(iRow).Insert
                    RowsAdded = RowsAdded + 1
    
                    ws.Cells(iRow, iCol).Value = "Subtotal " & Criteria(1, iCol)
                    If iCol = CriteriaCount Then
                        ws.Cells(iRow, CriteriaCount + 1).Resize(ColumnSize:=SumtotalCount).Formula = "=Sum(" & ws.Cells(StartRows(iCol), CriteriaCount + 1).Resize(RowSize:=iRow - StartRows(iCol)).Address(True, False) & ")"
                    Else
                        ws.Cells(iRow, CriteriaCount + 1).Resize(ColumnSize:=SumtotalCount).Formula = "=Sumif(" & ws.Cells(StartRows(iCol), iCol + 1).Resize(RowSize:=iRow - StartRows(iCol)).Address(True, True) & ",""Subtotal*""," & ws.Cells(StartRows(iCol), CriteriaCount + 1).Resize(RowSize:=iRow - StartRows(iCol)).Address(True, False) & ")"
                    End If
    
                    ws.Cells(iRow, iCol).Resize(ColumnSize:=SumtotalCount + CriteriaCount - iCol + 1).Interior.ThemeColor = 7 + iCol 'whatever you want
    
                    For i = iCol To UBound(StartRows)
                        StartRows(i) = 0
                    Next i
                    iRow = iRow + 1
                End If
            Next iCol
    
            If RowsAdded <> 0 Then
                Criteria = ws.Cells(iRow, 1).Resize(ColumnSize:=CriteriaCount).Value
                For i = LBound(StartRows) To UBound(StartRows)
                    If StartRows(i) = 0 Then StartRows(i) = iRow
                Next i
    
                LastRow = LastRow + RowsAdded 'if we insert a row we must increas last row
                RowsAdded = 0
            End If
    
            iRow = iRow + 1
        Loop
    End Sub
    
    选项显式
    公共小计()
    将ws设置为工作表
    设置ws=ThisWorkbook.Worksheets(“示例”)
    Const StartRow长度=2'忽略标题
    Const CriteriaCount As Long=3'标准列的数量(此处为国家+城市+住宅)
    Const SumtotalCount As Long=3'金额列到SUMTOTALL
    Dim Criteria()作为变量
    Criteria=ws.Cells(StartRow,1)。调整大小(ColumnSize:=CriteriaCount)。值
    ReDim StartRows(1到标准计数)
    我想我会坚持多久
    对于i=LBound(StartRows)到UBound(StartRows)
    StartRow(i)=StartRow
    接下来我
    暗淡的iRow和长的一样,iCol和长的一样
    iRow=StartRow+1
    最后一排一样长
    LastRow=ws.Cells(ws.Rows.Count,“A”).End(xlUp).Row
    Dim RowsAdded为Long,Criteria更改为Boolean
    趁热