【问题标题】:Combine duplicate rows and sum the values using dictionary合并重复行并使用字典对值求和
【发布时间】:2019-03-21 01:20:09
【问题描述】:

我有一个如下所示的表格,基于黄色突出显示的列,我需要对绿色突出显示的列求和。

预期输出在这里:

我已经使用下面的代码完成了……

Sub test()
    lrow = ActiveSheet.Cells(ActiveSheet.Cells.Rows.Count, 1).End(xlUp).Row

    Set Rng = Range("A2:A" & lrow)

    For Each cell In Rng
        If Not IsEmpty(cell) Then
            a = cell
            b = cell.Offset(0, 1)
            c = cell.Offset(0, 5)
            r = cell.Row

            cnt = Application.WorksheetFunction.CountIf(Rng, cell)
            d = 0
            For i = 1 To cnt
                If Cells(r + i, 1) = a And Cells(r + i, 2) = b And Cells(r + i, 6) Then
                Cells(r, 7) = Cells(r + i, 7) + Cells(r, 7)
                Cells(r, 8) = Cells(r + i, 8) + Cells(r, 8)
                d = d + 1
                End If
            Next
            If d > 0 Then Range(Cells(r + 1, 1).Address, Cells(r + d, 1).Address).EntireRow.Delete                
        End If
    Next
End Sub

我想使用脚本字典来完成,这对我来说是新的。由于我是初学者,我无法修改以下网络中的示例代码!

here得到它

Sub MG02Sep59()
    Dim Rng As Range, Dn As Range, n As Long, nRng As Range
    Set Rng = Range(Range("A2"), Range("A" & Rows.Count).End(xlUp))
    With CreateObject("scripting.dictionary")
    .CompareMode = vbTextCompare
    For Each Dn In Rng
        If Not .Exists(Dn.Value) Then
            .Add Dn.Value, Dn
        Else
            If nRng Is Nothing Then Set nRng = Dn Else Set nRng = Union(nRng, Dn)
            .Item(Dn.Value).Offset(, 3) = .Item(Dn.Value).Offset(, 3) + Dn.Offset(, 3)
        End If
    Next
    If Not nRng Is Nothing Then nRng.EntireRow.Delete
    End With
End Sub

谁能帮帮我?如果可能的话,附上一些注释。

【问题讨论】:

  • 考虑使用数据透视表。
  • @jsheeran,我需要使用 VBA 来完成。谢谢!
  • @Linga 那么请在您的问题中更具体一些。你在哪里得到错误?你的代码有什么问题?你在哪里遇到困难?只是发布您的代码并希望我们为您修复它不太可能在 Stack Overflow 上工作(请参阅How to Ask)。

标签: excel vba


【解决方案1】:

我会这样做:

Option Explicit
Sub Test()

    Dim ws As Worksheet
    Dim arrData As Variant
    Dim i As Long, ConcatenateStr As String, Sum1 As Currency, Sum2 As Currency
    Dim DictSum1 As Scripting.Dictionary 'You need the Microsoft Scripting Runtime reference for this to work
    Dim DictSum2 As Scripting.Dictionary

    Set ws = ThisWorkbook.Sheets("SheetName") 'Change this to fit your sheet name
    Set DictSum1 = New Scripting.Dictionary 'This is how you initialize your dictionary
    Set DictSum2 = New Scripting.Dictionary

    'Store everything on your sheet into the array
    arrData = ws.UsedRange.Value 'this will get from A1 till ctrl+end cell I'd delete rows and columns that are blank

    'Loop through the array to fill the dictionary
    For i = 2 To UBound(arrData) '2 because row 1 are headers, UBound is the function to get the last item of your array like .count
        If arrData(i, 1) = vbNullString Then Exit For 'this will end the loop once finding an empty value on column A
        ConcatenateStr = arrData(i, 1) & arrData(i, 2) & arrData(i, 3) & arrData(i, 6) 'this is to work cleaner, each number is the number of the column concatenated
        Sum1 = arrData(i, 7) 'column Sum 1
        Sum2 = arrData(i, 8) 'column Sum 2
        If Not DictSum1.Exists(ConcatenateStr) Then 'For the column Sum 1
            DictSum1.Add ConcatenateStr, Sum1 'this will add the first item Key = Concatenate String and item = the money value
        Else
            DictSum1(ConcatenateStr) = DictSum1(ConcatenateStr) + Sum1 'this will sum the existing value on the dictionary + the current value of the loop
        End If

        If Not DictSum2.Exists(ConcatenateStr) Then 'For the column Sum 2
            DictSum2.Add ConcatenateStr, Sum2 'this will add the first item Key = Concatenate String and item = the money value
        Else
            DictSum2(ConcatenateStr) = DictSum2(ConcatenateStr) + Sum2 'this will sum the existing value on the dictionary + the current value of the loop
        End If
    Next i

    Erase arrData

    With ws
        .UsedRange.RemoveDuplicates Columns:=Array(1, 2, 3, 6), Header:=xlYes 'Again UsedRange will take everything, Columns as you can see are the ones highlighted in yellow
        arrData = .UsedRange.Value 'Store the results of deleting all the duplicates
        For i = 2 To UBound(arrData)  'Lets fill the array with the sums
            ConcatenateStr = arrData(i, 1) & arrData(i, 2) & arrData(i, 3) & arrData(i, 6)
            arrData(i, 8) = DictSum1(ConcatenateStr)
            arrData(i, 9) = DictSum2(ConcatenateStr)
        Next i
        .UsedRange.Value = arrData 'Paste back the array with all the sums
    End With

End Sub

我已经评论了代码,但要了解更多关于字典的信息,请查看这个很棒的tutorial

【讨论】:

  • 非常感谢!我在这里遇到运行时错误 9 arrData(i, 9) = DictSum2(ConcatenateStr).. 我正在处理它,需要时间哈哈!!
  • 这意味着DictSum2(ConcatenateStr) 是空的 寻找ConcatenateStr 如果它存在,不应该是空的,除非它没有数据...
  • Na 不是空的,我已将 arrData(i, 8) = DictSum1(ConcatenateStr), arrData(i, 9) = DictSum2(ConcatenateStr) 更改为 (i, 7) 和 (i, 8 )它现在正在工作.. 再次感谢您的教导!
  • 完全没有问题!
猜你喜欢
  • 2020-02-03
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 2019-09-21
  • 1970-01-01
相关资源
最近更新 更多