Summarize using VBA Scripting Dictionary

deba2020

New Member
Joined
Jan 8, 2020
Messages
26
Office Version
  1. 2019
  2. 2016
  3. 2013
Platform
  1. Windows
I have a data which contains 18 columns, I need to summarize the data based on the 1st 2 columns and in the summary there will be just 3 columns as shown in below table
Raw Data in Sheet1

DEPOT / CUSTOMERSKUDESCRIPTIONBUSINESS LINEPRIMARY UOMSECONDARY UOMUNIT VOLUMEC1 (Y/N)SORQISOISO DATEDLVORDEREDSHIPPEDPENDINGPICKEDWEIGHT
Customer_1SKU1Product 1Business1EL5YES1498763764816354295409-Nov-2237627225110288200
Customer_2SKU2Product 2Business2EL1NO3575499337074806-Jun-223762722668451616800
Customer_3SKU1Product 3Business3EL2YES2055753500505330178505-Apr-22376272271500132018000
Customer_1SKU1Product 4Business4EL2YES2055753500507330178705-Apr-2237627228150014683200
Customer_5SKU5Product 5Business5EL2YES2055753566757336267830-May-223762722960035224800
Customer_3SKU1Product 6Business6EL10YES835863528928332785028-Apr-2237627230118211612100
Customer_1SKU1Product 7Business7EL4YES1909703534232333275402-May-22376272311521203200
Customer_2SKU1Product 8Business8EL18YES804583535595333406503-May-22376272329509311900
Customer_3SKU2Product 9Business9EL1NO3544187334195710-May-2237627233180017168400
Customer_1SKU2Product 10Business10EL16YES1316023516206331624218-Apr-2237627234100841600
Customer_2SKU2Product 11Business11EL10YES783723539301333743806-May-2237627235140013653500
Customer_2SKU2Product 12Business12EL1NO3545288334297611-May-223762723682862420400
Customer_13SKU2Product 13Business13EL10NO3545293334298011-May-223762723796722400
Customer_14SKU3Product 14Business14EL20NO3597923339112325-Jun-22376272382702502000
Customer_15SKU2Product 15Business15EL14NO3611702340392906-Jul-2237627239150717900



Need Summary in Sheet 2 as follows with these 3 columns (1st 2 columns and Sum of Column "Pending")

DEPOT / CUSTOMERSKUPENDING
Customer_1SKU1146
Customer_1SKU216
Customer_13SKU224
Customer_14SKU320
Customer_15SKU279
Customer_2SKU119
Customer_2SKU2407
Customer_3SKU1201
Customer_3SKU284
Customer_5SKU5248
 

Attachments

  • Summary.jpg
    Summary.jpg
    35.1 KB · Views: 6
  • Raw Data.jpg
    Raw Data.jpg
    196.4 KB · Views: 7

Excel Facts

Save Often
If you start asking yourself if now is a good time to save your Excel workbook, the answer is Yes
You can give this a try
VBA Code:
Sub deba2020()
            Dim wk1 As Worksheet, wk2 As Worksheet
            Set wk1 = Sheets("sheet14")            ' change your input sheet
            Set wk2 = Sheets("sheet15")             'change your output sheet
            Dim lr, k As Long
            Dim V, S
           
            lr = wk1.Range("A" & Rows.Count).End(xlUp).Row
            Dim dic As Object
            Set dic = CreateObject("Scripting.Dictionary")
            Dim TempStore As String
            With wk1
                    For k = 2 To lr
                            TempStore = .Range("A" & k).Value & "|" & .Range("B" & k).Value
                            If dic.Exists(TempStore) = False Then
                                    dic(TempStore) = .Range("P" & k).Value
                            Else: dic(TempStore) = dic(TempStore) + .Range("P" & k).Value
                            End If
                    Next k
            End With
            k = 0
           

            With wk2
                For Each S In dic.Keys
                     V = Split(S, "|")
                     .Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Resize(1, 2) = V
                Next S
                .Range("C" & Rows.Count).End(xlUp).Offset(1, 0).Resize(dic.Count) = WorksheetFunction.Transpose(dic.Items)
            End With
           
            S = Array("DEPOT / CUSTOMER", "SKU", "PENDING")
            wk2.Range("A1").Resize(1, UBound(S) + 1) = S
End Sub
 

Attachments

  • 1674907000628.png
    1674907000628.png
    33.7 KB · Views: 10
Upvote 0
Solution
What about using Excel's built-in Pivot Table feature (on the Insert ribbon tab)?

23 01 28.xlsm
ABPSTUVW
1DEPOT / CUSTOMERSKUPENDINGDEPOT / CUSTOMERSKUSum of PENDING
2Customer_1SKU182Customer_1SKU1146
3Customer_2SKU2168Customer_1SKU216
4Customer_3SKU1180Customer_13SKU224
5Customer_1SKU132Customer_14SKU320
6Customer_5SKU5248Customer_15SKU279
7Customer_3SKU121Customer_2SKU119
8Customer_1SKU132Customer_2SKU2407
9Customer_2SKU119Customer_3SKU1201
10Customer_3SKU284Customer_3SKU284
11Customer_1SKU216Customer_5SKU5248
12Customer_2SKU235
13Customer_2SKU2204
14Customer_13SKU224
15Customer_14SKU320
16Customer_15SKU279
Summary
 
Upvote 0
You can give this a try
VBA Code:
Sub deba2020()
            Dim wk1 As Worksheet, wk2 As Worksheet
            Set wk1 = Sheets("sheet14")            ' change your input sheet
            Set wk2 = Sheets("sheet15")             'change your output sheet
            Dim lr, k As Long
            Dim V, S
          
            lr = wk1.Range("A" & Rows.Count).End(xlUp).Row
            Dim dic As Object
            Set dic = CreateObject("Scripting.Dictionary")
            Dim TempStore As String
            With wk1
                    For k = 2 To lr
                            TempStore = .Range("A" & k).Value & "|" & .Range("B" & k).Value
                            If dic.Exists(TempStore) = False Then
                                    dic(TempStore) = .Range("P" & k).Value
                            Else: dic(TempStore) = dic(TempStore) + .Range("P" & k).Value
                            End If
                    Next k
            End With
            k = 0
          

            With wk2
                For Each S In dic.Keys
                     V = Split(S, "|")
                     .Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Resize(1, 2) = V
                Next S
                .Range("C" & Rows.Count).End(xlUp).Offset(1, 0).Resize(dic.Count) = WorksheetFunction.Transpose(dic.Items)
            End With
          
            S = Array("DEPOT / CUSTOMER", "SKU", "PENDING")
            wk2.Range("A1").Resize(1, UBound(S) + 1) = S
End Sub
Thank you very much. It worked exactly as I wanted!!
 
Upvote 0
What about using Excel's built-in Pivot Table feature (on the Insert ribbon tab)?

23 01 28.xlsm
ABPSTUVW
1DEPOT / CUSTOMERSKUPENDINGDEPOT / CUSTOMERSKUSum of PENDING
2Customer_1SKU182Customer_1SKU1146
3Customer_2SKU2168Customer_1SKU216
4Customer_3SKU1180Customer_13SKU224
5Customer_1SKU132Customer_14SKU320
6Customer_5SKU5248Customer_15SKU279
7Customer_3SKU121Customer_2SKU119
8Customer_1SKU132Customer_2SKU2407
9Customer_2SKU119Customer_3SKU1201
10Customer_3SKU284Customer_3SKU284
11Customer_1SKU216Customer_5SKU5248
12Customer_2SKU235
13Customer_2SKU2204
14Customer_13SKU224
15Customer_14SKU320
16Customer_15SKU279
Summary
I wrote some VBA code which runs before this consolidation so I wanted to eliminate manual consolidation using pivot table and to have the summary being prepared using scripting dictionary.
 
Upvote 0
I wrote some VBA code which runs before this consolidation so I wanted to eliminate manual consolidation using pivot table and to have the summary being prepared using scripting dictionary.
Fair enough. This would be my method.

VBA Code:
Sub Make_Summary()
  Dim d As Object
  Dim a As Variant
  Dim i As Long
  
  Set d = CreateObject("Scripting.Dictionary")
  With Sheets("Data").Range("A1").CurrentRegion '<- Edit sheet name to suit
    a = Application.Index(.Cells, Evaluate("row(1:" & .Rows.Count & ")"), Array(1, 2, 16))
  End With
  For i = 2 To UBound(a)
    d(a(i, 1) & ";" & a(i, 2)) = d(a(i, 1) & ";" & a(i, 2)) + a(i, 3)
  Next i
  With Sheets.Add(After:=Sheets(Sheets.Count))
    With .Range("A2:B2").Resize(d.Count)
      .Value = Application.Transpose(Array(d.Keys, d.Items))
      .Sort Key1:=.Columns(1), Order1:=xlAscending, Header:=xlNo
      .Columns(2).Insert
      .Columns(1).TextToColumns DataType:=xlDelimited, Semicolon:=True, Other:=False
      .Rows(0).Value = Application.Index(a, 1, 0)
      .EntireColumn.AutoFit
    End With
  End With
End Sub
 
Upvote 0
Fair enough. This would be my method.

VBA Code:
Sub Make_Summary()
  Dim d As Object
  Dim a As Variant
  Dim i As Long
 
  Set d = CreateObject("Scripting.Dictionary")
  With Sheets("Data").Range("A1").CurrentRegion '<- Edit sheet name to suit
    a = Application.Index(.Cells, Evaluate("row(1:" & .Rows.Count & ")"), Array(1, 2, 16))
  End With
  For i = 2 To UBound(a)
    d(a(i, 1) & ";" & a(i, 2)) = d(a(i, 1) & ";" & a(i, 2)) + a(i, 3)
  Next i
  With Sheets.Add(After:=Sheets(Sheets.Count))
    With .Range("A2:B2").Resize(d.Count)
      .Value = Application.Transpose(Array(d.Keys, d.Items))
      .Sort Key1:=.Columns(1), Order1:=xlAscending, Header:=xlNo
      .Columns(2).Insert
      .Columns(1).TextToColumns DataType:=xlDelimited, Semicolon:=True, Other:=False
      .Rows(0).Value = Application.Index(a, 1, 0)
      .EntireColumn.AutoFit
    End With
  End With
End Sub

It worked fantastically...Summed up the data exactly as I wanted. Thanks.
 
Last edited by a moderator:
Upvote 0
You're welcome. Glad to offer options. Thanks for the follow-up. :)

Speaking of options, here is another fairly compact code, that does not require the dictionary object, that you could try.
Check the original data sheet name in the code still.

VBA Code:
Sub Make_Summary_v2()
  Application.ScreenUpdating = False
  Sheets("Data").Copy After:=Sheets(Sheets.Count)
  With Sheets(Sheets.Count).UsedRange
    .Columns(3).FormulaR1C1 = Replace("=SUMIFS(R2C16:R#C16,R2C1:R#C1,RC1,R2C2:R#C2,RC2)", "#", .Rows.Count)
    .Columns(3).Value = .Columns(3).Value
    .Range("P1").Copy Destination:=.Range("C1")
    .Offset(, 3).Clear
    .Sort Key1:=.Columns(1), Order1:=xlAscending, Key2:=.Columns(2), Order2:=xlAscending, Header:=xlYes
    .RemoveDuplicates Columns:=Array(1, 2)
    .Columns.AutoFit
  End With
  Application.ScreenUpdating = True
End Sub
 
Upvote 0
You're welcome. Glad to offer options. Thanks for the follow-up. :)

Speaking of options, here is another fairly compact code, that does not require the dictionary object, that you could try.
Check the original data sheet name in the code still.

VBA Code:
Sub Make_Summary_v2()
  Application.ScreenUpdating = False
  Sheets("Data").Copy After:=Sheets(Sheets.Count)
  With Sheets(Sheets.Count).UsedRange
    .Columns(3).FormulaR1C1 = Replace("=SUMIFS(R2C16:R#C16,R2C1:R#C1,RC1,R2C2:R#C2,RC2)", "#", .Rows.Count)
    .Columns(3).Value = .Columns(3).Value
    .Range("P1").Copy Destination:=.Range("C1")
    .Offset(, 3).Clear
    .Sort Key1:=.Columns(1), Order1:=xlAscending, Key2:=.Columns(2), Order2:=xlAscending, Header:=xlYes
    .RemoveDuplicates Columns:=Array(1, 2)
    .Columns.AutoFit
  End With
  Application.ScreenUpdating = True
End Sub
Humbled by the knowledge you possess. Both the solutions work perfectly. Thank you.
 
Upvote 0

Forum statistics

Threads
1,223,888
Messages
6,175,205
Members
452,618
Latest member
Tam84

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top