Expanding table via Scripting dictionary

Michael M

Well-known Member
Joined
Oct 27, 2005
Messages
21,834
Office Version
  1. 365
  2. 2019
  3. 2013
  4. 2007
Platform
  1. Windows
Hi All
I've been trying to improve my knowledge of Dictionaries and have been using this code kindly submitted by @Rick Rothstein some time ago.
How can I expand the data so that it also sums column "C" as well. Any help would be much appreciated
VBA Code:
Sub Consolidate()
  Dim R As Long, Data As Variant
  Data = Range("A2", Cells(Rows.Count, "B").End(xlUp))
  With CreateObject("Scripting.Dictionary")
    For R = 1 To UBound(Data)
      .Item(Data(R, 1)) = .Item(Data(R, 1)) + Data(R, 2)
     Next R
    Range("D2").Resize(.Count) = Application.Transpose(.Keys)
    Range("E2").Resize(.Count) = Application.Transpose(.Items)
  End With
End Sub
 

Excel Facts

Spell Check in Excel
Press F7 to start spell check in Excel. Be careful, by default, Excel does not check Capitalized Werds (whoops)
This modification should put the sum of column "C" in column "F".
VBA Code:
Sub Consolidate2()
  Dim R As Long, Data As Variant
  Data = Range("A2", Cells(Rows.Count, "C").End(xlUp))
  With CreateObject("Scripting.Dictionary")
    For R = 1 To UBound(Data)
      .Item(Data(R, 1)) = .Item(Data(R, 1)) + Data(R, 2)
     Next R
    Range("D2").Resize(.Count) = Application.Transpose(.Keys)
    Range("E2").Resize(.Count) = Application.Transpose(.Items)
    .RemoveAll
    For R = 1 To UBound(Data)
      .Item(Data(R, 1)) = .Item(Data(R, 1)) + Data(R, 3)
     Next R
    Range("F2").Resize(.Count) = Application.Transpose(.Items)
  End With
End Sub
 
Upvote 0
Solution
@JoeMo Ahh, now I get it....it needed another loop, where I was trying inert an extra line in the first loop.
Much appreciated Joe...:cool:?
 
Upvote 0
Another option without an extra loop
VBA Code:
Sub Consolidate()
   Dim R As Long, Data As Variant, Tmp As Variant
   Data = Range("A2", Cells(Rows.Count, "C").End(xlUp))
   With CreateObject("Scripting.Dictionary")
      For R = 1 To UBound(Data)
         If Not .Exists(Data(R, 1)) Then
            .Add Data(R, 1), Array(Data(R, 2), Data(R, 3))
         Else
            Tmp = .Item(Data(R, 1))
            Tmp(0) = Tmp(0) + Data(R, 2)
            Tmp(1) = Tmp(1) + Data(R, 3)
            .Item(Data(R, 1)) = Tmp
         End If
      Next R
      Range("D2").Resize(.Count) = Application.Transpose(.Keys)
      Range("E2").Resize(.Count, 2) = Application.Index(.Items, 0, 0)
   End With
End Sub
 
Upvote 0
You could also process the additions in the array method directly without the Tmp array.
This and Fluff's code assume the default Option Base of 0

VBA Code:
Sub Consolidate3()
   Dim R As Long, Data As Variant
   Data = Range("A2", Cells(Rows.Count, "C").End(xlUp))
   With CreateObject("Scripting.Dictionary")
      For R = 1 To UBound(Data)
         If Not .Exists(Data(R, 1)) Then
            .Add Data(R, 1), Array(Data(R, 2), Data(R, 3))
         Else
            .Item(Data(R, 1)) = Array(.Item(Data(R, 1))(0) + Data(R, 2), .Item(Data(R, 1))(1) + Data(R, 3))
         End If
      Next R
      Range("D2").Resize(.Count) = Application.Transpose(.keys)
      Range("E2").Resize(.Count, 2) = Application.Index(.Items, 0, 0)
   End With
End Sub
 
Upvote 0
Thanks to @Peter_SSs , @Fluff and @JoeMo
As always more thasn one way to process data!!
Am I safe to assume that the code by Peter would be slightly quicker than that of Fluff and Joe??
I guess I can't mark ALL as a solution, as they all a re correct, but slightly different.....I'll let the Mods decide which should be considered the best solution
 
Upvote 0
We could add the first item with (0,0) and then add the values, just to simplify the Else.

VBA Code:
Sub Consolidate4()
  Dim R As Long, Data As Variant, dic As Object
  Data = Range("A2", Cells(Rows.Count, "C").End(xlUp))
  Set dic = CreateObject("Scripting.Dictionary")
  For R = 1 To UBound(Data)
    If Not dic.exists(Data(R, 1)) Then dic(Data(R, 1)) = Array(0, 0)
    dic(Data(R, 1)) = Array(dic(Data(R, 1))(0) + Data(R, 2), dic(Data(R, 1))(1) + Data(R, 3))
  Next
  Range("D2").Resize(dic.Count) = Application.Transpose(dic.Keys)
  Range("E2").Resize(dic.Count, 2) = Application.Index(dic.Items, 0, 0)
End Sub
 
Last edited:
Upvote 0
So I ran the code over 30000 rows and timed them.
I don't know why but the first code supplied by @JoeMo came up the fastest. Any explanation for that, apart from the bleeding obvious ( it was faster!!)
Scripting Dictionary Example multi.xls
IJKL
2DanteAmor=0.34765625seconds
3Peter_SSs=0.421875seconds
4Fluff=0.3125seconds
5JoeMo=0.2890265seconds
Sum Data
 
Upvote 0
It's definitely adding a condition, programs are slower when you add conditions. The JoeMo code has no condition.
 
Upvote 0

Forum statistics

Threads
1,214,613
Messages
6,120,515
Members
448,968
Latest member
Ajax40

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