Combining Data w/ VBA

jetstrike

New Member
Joined
Jan 17, 2019
Messages
4
Hello everyone,

I am a long time lurker and excel novice. I have a data set that has multiple entries per date and per group and I would like to combine those entries into a single line. I have given an before and after example below. I am hoping for a VBA solution so that I can save it as a macro but the method to do so escapes me. The actual data set is approximately 250,000 records. I have had mixed success's with various methods and any assistance would be greatly appreciated.

NameDateGroupTime
Jeff1/1/19G1284
Jeff1/1/19G2767
Jeff1/1/19G3451
Jeff1/2/19G2568
Jeff1/2/19G7489
Steve1/1/19G13654
Steve1/1/19G77789
Steve1/2/19G31413
Steve1/2/19G23877

<tbody>
</tbody>


NameDateGroupTime
Jeff1/1/19G1;G2;G31502
Jeff1/2/19G2;G71057
Steve1/1/19G13;G771443
Steve1/2/19G31;G231290

<tbody>
</tbody>


Thank you for your time and have a wonderful day!
 

Excel Facts

Fastest way to copy a worksheet?
Hold down the Ctrl key while dragging tab for Sheet1 to the right. Excel will make a copy of the worksheet.
just for fun without VBA but with PowerQuery aka Get&Transform

NameDateGroupTimeNameDateGroupSum of Time
Jeff
01/01/2019​
G1
284​
Jeff
01/01/2019​
G1;G2;G3
1502​
Jeff
01/01/2019​
G2
767​
Jeff
01/02/2019​
G2;G7
1057​
Jeff
01/01/2019​
G3
451​
Steve
01/01/2019​
G13;G77
1443​
Jeff
01/02/2019​
G2
568​
Steve
01/02/2019​
G31;G23
1290​
Jeff
01/02/2019​
G7
489​
Steve
01/01/2019​
G13
654​
Steve
01/01/2019​
G77
789​
Steve
01/02/2019​
G31
413​
Steve
01/02/2019​
G23
877​

Code:
[SIZE=1]let
    Source = Excel.CurrentWorkbook(){[Name="Table8"]}[Content],
    #"Grouped Rows" = Table.Group(Source, {"Name", "Date"}, {{"Count", each _, type table}}),
    #"Added Custom" = Table.AddColumn(#"Grouped Rows", "Group", each Table.Column([Count],"Group")),
    #"Aggregated Count" = Table.AggregateTableColumn(#"Added Custom", "Count", {{"Time", List.Sum, "Sum of Time"}}),
    #"Extracted Values" = Table.TransformColumns(#"Aggregated Count", {"Group", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
    #"Reordered Columns" = Table.ReorderColumns(#"Extracted Values",{"Name", "Date", "Group", "Sum of Time"}),
    #"Changed Type" = Table.TransformColumnTypes(#"Reordered Columns",{{"Date", type date}})
in
    #"Changed Type"[/SIZE]
 
Upvote 0
Howdy,

I think I understand what you'd like to do. Just a few questions:

1) Is the data always in date order?

2) Will all the Jeffs and Steves be clumped together like in your example, or will they be spread out with different names in between?

3) Should the macro put the combined data in a new sheet or overwrite the data on the current sheet?

-Matt
 
Upvote 0
Howdy,

I think I understand what you'd like to do. Just a few questions:

1) Is the data always in date order?

2) Will all the Jeffs and Steves be clumped together like in your example, or will they be spread out with different names in between?

3) Should the macro put the combined data in a new sheet or overwrite the data on the current sheet?

-Matt

1. I can definitly sort the data to be date order quickly with a macro but the source data is not always in order.
2. There are about 900 users and they will be spread out with others in between.
3. Either is fine I am just struggling with the steps to combine the data. New sheet would be best so I can test without destroying data.

For the first two questions it seems to me I could just sort by name and then date or vice versa if that helps.
 
Upvote 0
I really appreciate this. Unfortunately my workplace is extremely strict in terms of security and I cannot use power query.


just for fun without VBA but with PowerQuery aka Get&Transform

[COLOR=[URL=https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=FFFFFF]#FFFFFF[/URL] ]Name[/COLOR][COLOR=[URL=https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=FFFFFF]#FFFFFF[/URL] ]Date[/COLOR][COLOR=[URL=https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=FFFFFF]#FFFFFF[/URL] ]Group[/COLOR][COLOR=[URL=https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=FFFFFF]#FFFFFF[/URL] ]Time[/COLOR][COLOR=[URL=https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=FFFFFF]#FFFFFF[/URL] ]Name[/COLOR][COLOR=[URL=https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=FFFFFF]#FFFFFF[/URL] ]Date[/COLOR][COLOR=[URL=https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=FFFFFF]#FFFFFF[/URL] ]Group[/COLOR][COLOR=[URL=https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=FFFFFF]#FFFFFF[/URL] ]Sum of Time[/COLOR]
Jeff
01/01/2019​
G1
284​
Jeff
01/01/2019​
G1;G2;G3
1502​
Jeff
01/01/2019​
G2
767​
Jeff
01/02/2019​
G2;G7
1057​
Jeff
01/01/2019​
G3
451​
Steve
01/01/2019​
G13;G77
1443​
Jeff
01/02/2019​
G2
568​
Steve
01/02/2019​
G31;G23
1290​
Jeff
01/02/2019​
G7
489​
Steve
01/01/2019​
G13
654​
Steve
01/01/2019​
G77
789​
Steve
01/02/2019​
G31
413​
Steve
01/02/2019​
G23
877​

<tbody>
</tbody>


Code:
[SIZE=1]let
    Source = Excel.CurrentWorkbook(){[Name="Table8"]}[Content],
    #"Grouped Rows" = Table.Group(Source, {"Name", "Date"}, {{"Count", each _, type table}}),
    #"Added Custom" = Table.AddColumn(#"Grouped Rows", "Group", each Table.Column([Count],"Group")),
    #"Aggregated Count" = Table.AggregateTableColumn(#"Added Custom", "Count", {{"Time", List.Sum, "Sum of Time"}}),
    #"Extracted Values" = Table.TransformColumns(#"Aggregated Count", {"Group", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
    #"Reordered Columns" = Table.ReorderColumns(#"Extracted Values",{"Name", "Date", "Group", "Sum of Time"}),
    #"Changed Type" = Table.TransformColumnTypes(#"Reordered Columns",{{"Date", type date}})
in
    #"Changed Type"[/SIZE]
 
Upvote 0
Sorry, I had a go at it, but this seems to be above my knowledge level. I'm pretty sure this should be doable using VBA though; maybe someone else will weigh it. I don't know anything about PowerQuery, but Sandy666's solution looks exactly like what you need if you could convince the powers that be to allow it. Good luck!

-Matt
 
Upvote 0
How about
Code:
Sub Jetstrike()
   Dim Ary As Variant, Ky As Variant, K As Variant
   Dim i As Long
   Dim Dic As Object
   Dim Tmp1 As String, Tmp2 As Long
   
   Ary = Sheets("Sheet1").Range("A1").CurrentRegion.Value2
   Set Dic = CreateObject("Scripting.dictionary")
   For i = 1 To UBound(Ary)
      If Not Dic.Exists(Ary(i, 1)) Then Dic.Add Ary(i, 1), CreateObject("scripting.dictionary")
      If Not Dic(Ary(i, 1)).Exists(Ary(i, 2)) Then
         Dic(Ary(i, 1)).Add (Ary(i, 2)), Array(Ary(i, 3), Ary(i, 4))
      Else
         Tmp1 = Dic(Ary(i, 1))(Ary(i, 2))(0) & ", " & Ary(i, 3)
'         Debug.Print Dic(Ary(i, 1))(Ary(i, 2))(2)
         Tmp2 = Dic(Ary(i, 1))(Ary(i, 2))(1) + Ary(i, 4)
         Dic(Ary(i, 1))(Ary(i, 2)) = Array(Tmp1, Tmp2)
      End If
   Next i
   With Sheets("Sheet2")
      For Each Ky In Dic.Keys
         For Each K In Dic(Ky)
            .Range("A" & Rows.Count).End(xlUp).Offset(1).Value = Ky
            .Range("B" & Rows.Count).End(xlUp).Offset(1).Value = K
            .Range("C" & Rows.Count).End(xlUp).Offset(1).Resize(, 2).Value = Application.Index(Dic(Ky)(K), 1, 0)
         Next K
      Next Ky
   End With
End Sub
 
Upvote 0
This works, thank you.

How about
Code:
Sub Jetstrike()
   Dim Ary As Variant, Ky As Variant, K As Variant
   Dim i As Long
   Dim Dic As Object
   Dim Tmp1 As String, Tmp2 As Long
   
   Ary = Sheets("Sheet1").Range("A1").CurrentRegion.Value2
   Set Dic = CreateObject("Scripting.dictionary")
   For i = 1 To UBound(Ary)
      If Not Dic.Exists(Ary(i, 1)) Then Dic.Add Ary(i, 1), CreateObject("scripting.dictionary")
      If Not Dic(Ary(i, 1)).Exists(Ary(i, 2)) Then
         Dic(Ary(i, 1)).Add (Ary(i, 2)), Array(Ary(i, 3), Ary(i, 4))
      Else
         Tmp1 = Dic(Ary(i, 1))(Ary(i, 2))(0) & ", " & Ary(i, 3)
'         Debug.Print Dic(Ary(i, 1))(Ary(i, 2))(2)
         Tmp2 = Dic(Ary(i, 1))(Ary(i, 2))(1) + Ary(i, 4)
         Dic(Ary(i, 1))(Ary(i, 2)) = Array(Tmp1, Tmp2)
      End If
   Next i
   With Sheets("Sheet2")
      For Each Ky In Dic.Keys
         For Each K In Dic(Ky)
            .Range("A" & Rows.Count).End(xlUp).Offset(1).Value = Ky
            .Range("B" & Rows.Count).End(xlUp).Offset(1).Value = K
            .Range("C" & Rows.Count).End(xlUp).Offset(1).Resize(, 2).Value = Application.Index(Dic(Ky)(K), 1, 0)
         Next K
      Next Ky
   End With
End Sub
 
Upvote 0
You're welcome & thanks for the feedback
 
Upvote 0

Forum statistics

Threads
1,214,641
Messages
6,120,691
Members
448,978
Latest member
rrauni

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