在工作表中组合行和求和值

Combine Rows & Sum Values in a Worksheet

我有一个 excel sheet 数据如下(竖线“|”分隔列)。

A|B|C|X|50|60
D|E|F|X|40|30
A|B|C|X|10|20
A|B|C|Y|20|20
A|B|C|X|20|70
D|E|F|X|10|50
A|B|C|Y|10|10

我想要得到的结果是:

A|B|C|X|80|150
A|B|C|Y|30|30
D|E|F|X|50|80

值 A、B、C 和 D、E、F 就像唯一标识符。实际上只能考虑A或D。值 X 和 Y 类似于​​ "types",整数是要求和的值。这个示例被简化了,有数千个唯一标识符、十几种类型和几十个值要求和。行未排序,类型可以位于较高或较低的行中。我试图避免使用枢轴 table.

Dim LastRow As Integer
Dim LastCol As Integer
Dim i As Integer

LastCol = Sheets(1).Cells(1, Columns.Count).End(xlToLeft).Column
LastRow = Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row

For i = 1 To LastRow
????
Next i

上面的代码到达了遍历行的地步,但我不清楚在那之后要做什么。

  1. 按您认为重要的所有字母列对它们进行排序。
  2. 在右侧未使用的列中,在第二行中使用如下公式,

    =IF($A2&$B2&$C2&$D2=$A3&$B3&$C3&$D3, "", SUMIFS(E:E,$A:$A, $A2,$B:$B, $B2,$C:$C,$C2,$D:$D,$D2))

  3. 复制该公式右边的一列,然后根据您的数据填写两列

  4. 过滤两列,删除空白。

  5. 可选择将数据复制到新的报告工作表并删除 E 和 F 列。

附录:

可以使用某种形式的数组和一些简单的数学运算来实现更加自动化的方法。我选择了字典 object 以便利用其索引 Key 来识别前四个字母标识符中的模式。

要使用脚本字典,您需要进入 VBE 的工具 ► 参考并添加 Microsoft 脚本运行时。如果没有它,以下代码将无法编译。

以下已针对键和整数的动态列进行了调整。

Sub rad_collection()
    Dim rw As Long, nc As Long, sTMP As String, v As Long, vTMP As Variant
    Dim i As Long, iNumKeys As Long, iNumInts As Long
    Dim dRADs As New Scripting.Dictionary

    dRADs.CompareMode = vbTextCompare
    iNumKeys = 5    'possibly calculated by num text (see below)
    iNumInts = 2    'possibly calculated by num ints (see below)

    With ThisWorkbook.Sheets("Sheet4").Cells(1, 1).CurrentRegion
        'iNumKeys = Application.CountA(.Rows(2)) - Application.Count(.Rows(2))  'alternate count of txts
        'iNumInts = Application.Count(.Rows(2))    'alternate count of ints
        For rw = 2 To .Cells(Rows.Count, 1).End(xlUp).row
                vTMP = .Cells(rw, 1).Resize(1, iNumKeys).Value2
                sTMP = Join(Application.Index(vTMP, 1, 0), Chr(183))
                If Not dRADs.Exists(sTMP) Then
                    dRADs.Add Key:=sTMP, Item:=Join(Application.Index(.Cells(rw, iNumKeys + 1).Resize(1, iNumInts).Value2, 1, 0), Chr(183))
                Else
                    vTMP = Split(dRADs.Item(sTMP), Chr(183))
                    For v = LBound(vTMP) To UBound(vTMP)
                        vTMP(v) = vTMP(v) + .Cells(rw, iNumKeys + 1 + v).Value2
                    Next v
                    dRADs.Item(sTMP) = Join(vTMP, Chr(183))
                End If

        Next rw

        rw = 1
        nc = iNumKeys + iNumInts + 1
        .Cells(rw, nc + 1).CurrentRegion.ClearContents  'clear previous
        .Cells(rw, nc + 1).Resize(1, nc - 1) = .Cells(rw, 1).Resize(1, nc - 1).Value2
        For Each vTMP In dRADs.Keys
            'Debug.Print vTMP & "|" & dRADs.Item(vTMP)
            rw = rw + 1
            .Cells(rw, nc + 1).Resize(1, iNumKeys) = Split(vTMP, Chr(183))
            .Cells(rw, nc + iNumKeys + 1).Resize(1, iNumInts) = Split(dRADs.Item(vTMP), Chr(183))
            .Cells(rw, nc + iNumKeys + 1).Resize(1, iNumInts) = _
              .Cells(rw, nc + iNumKeys + 1).Resize(1, iNumInts).Value2
        Next vTMP
    End With

    dRADs.RemoveAll: Set dRADs = Nothing

End Sub

只是 运行 宏与您作为示例提供的数字相对应。我在第一行假设了某种形式的列 header 标签。字典 object 被填充,组合标识符中的重复项的数字相加。剩下的就是将它们分开并 return 它们到工作表中未使用的区域。

Microsoft 脚本运行时的位置 - 在 Visual Basic 编辑器(又名 VBE)中选择工具 ► 参考 (Alt+T,R) 然后向下滚动一半多一点找到它。