Macro to merging for multiple columns contain same headers

Maklil

Board Regular
Joined
Jun 23, 2022
Messages
181
Office Version
  1. 2019
Platform
  1. Windows
Hi Guys,
I search for macro to deal with about 15000 rows for SUMMARY sheet.
so in FINAL
FINAL sheet will be result with formatting and borders.
in SUMMARY sheet should merge amounts (D:G) are existed in the same column based on name and sheet name in columns B:C
the headers in row1 will transfer as column in C column and repeat it for each name in column B is relating with the header in row1
also insert two rows to the bottom TOTAL ,NET to calculation.
as to sorting data should be from A-Z based n column B .
should delete data in FINAL sheet before show report.
so the data in SUMMARY sheet.
mk1.xlsm
ABCDEFGHIJ
1MKMTMSATS
2DATENAMEPAIDNOT PAIDRECEIVEDNOT REICEVEDRECEIVEDNOT REICEVEDPAIDNOT PAID
320/08/2023MVS6,800.00-2,800.00-340.00345.00--
420/08/2023MVS10,000.00-------
521/08/2023MVS-19,600.001000-655.00---
621/08/2023MVS-4,750.00
721/08/2023MSS-11,580.00---495.00--
821/08/2023MTT---1,950.00----
921/08/2023MLL10,000.00--3,470.00----
1024/08/2023MKK--84,400.00----1,245.00
1124/08/2023MLL10,000.00--3,960.00----
1225/08/2023MKK12,000.00-----460.00-
1325/08/2023MSS-100---200640.00-
1425/08/2023MLL--1000---950.00-
1525/08/2023MKK1,000.00-10001000--450.00-
16TOTAL49,800.0036,030.0090,200.0010,380.00995.001,040.002,500.001,245.00
17NET38,895.00
SUMMARY
Cell Formulas
RangeFormula
C16:J16C16=SUM(C3:C15)
J17J17=(E16+G16)-(C16+I16)



mk1.xlsm
ABCDEFG
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FINAL



the output should be
mk1.xlsm
ABCDEFG
1ITEMNAMESheet namePAIDNOT PAIDRECEIVEDNOT REICEVED
21MKKMK13,000.00---
32MKKMT--85,400.00-
43MKKATS910.00---
54MKKATS-1,245.00--
65MKKMT---1,000.00
76MLLMK20,000.00---
87MLLMT--1,000.00-
98MLLMT---7,430.00
109MLLATS950.00---
1110MTTMT---1,950.00
1211MVSMK16,800.0024,350.00--
1312MVSMT--3,800.00-
1413MVSMS---345.00
1514MVSMS-995-
1615MSSMK-11,680.00--
1716MSSMS---695.00
1817MSSATS640.00---
19TOTAL52,300.0037,275.0091,195.0011,420.00
20NET38,895.00
FINAL
Cell Formulas
RangeFormula
D19:G19D19=SUM(D2:D18)
G20G20=F19-D19

by the way I don't want power query or pivot table, just macro to deal data .
thanks
 

Excel Facts

Select all contiguous cells
Pressing Ctrl+* (asterisk) will select the "current region" - all contiguous cells in all directions.
I think some values in your output example are not grouped in the correct row:

1736883608364.png

This is what I get as a result
Dante Amor
ABCDEFG
1ITEMNAMESHEET NAMEPAIDNOT PAIDRECEIVEDNOT REICEVED
21MKKMK13,000.00
32MKKMT85,400.001,000.00
43MKKATS910.001,245.00
54MLLMK20,000.00
65MLLMT1,000.007,430.00
76MLLATS950.00
87MSSMK11,680.00
98MSSMS695.00
109MSSATS640.00
1110MTTMT1,950.00
1211MVSMK16,800.0024,350.00
1312MVSMT3,800.00
1413MVSMS995.00345.00
15TOTAL52,300.0037,275.0091,195.0011,420.00
16NET38,895.00
FINAL


Try the following macro:
VBA Code:
Sub merging_multiple_columns()
  Dim a As Variant, b As Variant, ky As Variant
  Dim dic As Object
  Dim i&, j&, u&, y&, lr&, nRow
  
  Set dic = CreateObject("Scripting.Dictionary")
  
  With Sheets("SUMMARY")
    lr = .Range("B" & Rows.Count).End(3).Row
    a = .Range("A1:J" & lr).Value
    u = Evaluate(Replace("=SUMPRODUCT((@<>"""")/COUNTIF(@,@&""""))", "@", .Name & "!B3:B" & lr)) 'unique
  End With
  
  ReDim b(1 To (u * 4) + 2, 1 To 7)
  For i = 3 To UBound(a)
    For j = 3 To 10
      If a(i, j) <> 0 Then
        ky = a(i, 2) & "|" & IIf(a(1, j) = "", j - 1 & "@" & a(1, j - 1), j & "@" & a(1, j))
        If Not dic.exists(ky) Then
          y = y + 1
          dic(ky) = y
        End If
        nRow = dic(ky)
        b(nRow, 2) = Split(ky, "|")(0)
        b(nRow, 3) = Split(ky, "|")(1)
        Select Case j
          Case 3, 9
            b(nRow, 4) = b(nRow, 4) + a(i, j)
          Case 4, 10
            b(nRow, 5) = b(nRow, 5) + a(i, j)
          Case 5, 7
            b(nRow, 6) = b(nRow, 6) + a(i, j)
          Case 6, 8
            b(nRow, 7) = b(nRow, 7) + a(i, j)
        End Select
      End If
    Next
  Next
  
  Application.ScreenUpdating = False
  With Sheets("FINAL")
    .Range("A:G").Clear
    .Range("A:G").HorizontalAlignment = xlCenter
    .Range("D:G").NumberFormat = "#,##0.00"
    
    With .Range("A1").Resize(1, 7)
      .Value = Array("ITEM", "NAME", "SHEET NAME", "PAID", "NOT PAID", "RECEIVED", "NOT REICEVED")
      .Borders.LineStyle = xlContinuous
      .Borders.Color = 11184814
      .Interior.ColorIndex = 16
    End With
    
    With .Range("A2").Resize(y, UBound(b, 2))
      .Value = b
      .Borders.LineStyle = xlContinuous
      .Borders.Color = 11184814
      .Sort .Range("B2"), xlAscending, .Range("C2"), , xlAscending, Header:=xlNo
    End With
    
    With .Range("A2")
      .Value = 1
      .Resize(y).DataSeries Rowcol:=xlColumns, Type:=xlLinear, Date:=xlDay, Step:=1, Trend:=False
    End With
    
    With .Range("C:C")
      .Replace "3@", "", xlPart
      .Replace "5@", "", xlPart
      .Replace "7@", "", xlPart
      .Replace "9@", "", xlPart
    End With
    
    With .Range("A" & y + 2)
      .Value = "TOTAL"
      .Interior.Color = vbYellow
      .Font.Bold = True
      .Offset(0, 3).Value = WorksheetFunction.Sum(.Parent.Range("D2:D" & y + 1))
      .Offset(0, 4).Value = WorksheetFunction.Sum(.Parent.Range("E2:E" & y + 1))
      .Offset(0, 5).Value = WorksheetFunction.Sum(.Parent.Range("F2:F" & y + 1))
      .Offset(0, 6).Value = WorksheetFunction.Sum(.Parent.Range("G2:G" & y + 1))
      With .Resize(2, 7)
        .Borders.LineStyle = xlContinuous
        .Borders.Color = 11184814
      End With
    End With
    
    With .Range("A" & y + 3)
      .Value = "NET"
      .Interior.Color = vbYellow
      .Font.Bold = True
      .Offset(0, 6).Value = .Parent.Range("F" & y + 2) - .Parent.Range("D" & y + 2)
    End With
  End With
  Application.ScreenUpdating = True
End Sub

😅
 
Upvote 0
thanks Dante.
I think some values in your output example are not grouped in the correct row:
I agree with you .
I tested , I have two things :
first I would show zero as hyphen in empty cells.
second about running speed with 15000 row I think the code is slow , gives me 24.50 sec.
 
Upvote 0
first I would show zero as hyphen in empty cells.
ok

second about running speed with 15000 row I think the code is slow , gives me 24.50 sec.
In your final result you have too many formats in the cells. And it also have to sort the data.

Try the following macro to know how long the macro runs without formats. I also made some improvements.

VBA Code:
Sub merging_multiple_columns()
  Dim a As Variant, b As Variant, ky As Variant
  Dim dic As Object
  Dim i&, j&, u&, y&, lr&, nRow&
  Dim t1 As Double, t2 As Double, t3 As Double, t4 As Double
  
  Set dic = CreateObject("Scripting.Dictionary")
  
  With Sheets("SUMMARY")
    lr = .Range("B" & Rows.Count).End(3).Row
    a = .Range("A1:J" & lr).Value
'    u = Evaluate(Replace("=SUMPRODUCT((@<>"""")/COUNTIF(@,@&""""))", "@", .Name & "!B3:B" & lr)) 'unique
    For i = 3 To UBound(a)
      dic(a(i, 2)) = Empty
    Next
    u = dic.Count
  End With
  
  ReDim b(1 To (u * 4) + 2, 1 To 7)
  For i = 3 To UBound(a)
    For j = 3 To 10
      If a(i, j) <> 0 Then
        ky = a(i, 2) & "|" & IIf(a(1, j) = "", a(1, j - 1), a(1, j))
'        ky = a(i, 2) & "|" & IIf(a(1, j) = "", j - 1 & "@" & a(1, j - 1), j & "@" & a(1, j))
        If Not dic.exists(ky) Then
          y = y + 1
          dic(ky) = y
        End If
        nRow = dic(ky)
        b(nRow, 2) = Split(ky, "|")(0)
        b(nRow, 3) = Split(ky, "|")(1)
        Select Case j
          Case 3, 9
            b(nRow, 4) = b(nRow, 4) + a(i, j)
            t1 = t1 + a(i, j)
          Case 4, 10
            b(nRow, 5) = b(nRow, 5) + a(i, j)
            t2 = t2 + a(i, j)
          Case 5, 7
            b(nRow, 6) = b(nRow, 6) + a(i, j)
            t3 = t3 + a(i, j)
          Case 6, 8
            b(nRow, 7) = b(nRow, 7) + a(i, j)
            t4 = t4 + a(i, j)
        End Select
      End If
    Next
  Next
  
  Application.ScreenUpdating = False
  With Sheets("FINAL")
    .Range("A:G").Clear
    .Range("A:G").HorizontalAlignment = xlCenter
    .Range("D:G").NumberFormat = "#,##0.00;;-"
    
    With .Range("A1").Resize(1, 7)
      .Value = Array("ITEM", "NAME", "SHEET NAME", "PAID", "NOT PAID", "RECEIVED", "NOT REICEVED")
      .Interior.ColorIndex = 16
    End With
    
    With .Range("A2").Resize(y, UBound(b, 2))
      .Value = b
      .Parent.Range("D2:G" & y + 1).SpecialCells(xlCellTypeBlanks).Value = 0
      .Sort .Range("B2"), xlAscending, .Range("C2"), , xlAscending, Header:=xlNo
    End With
    
    With .Range("A2")
      .Value = 1
      .Resize(y).DataSeries Rowcol:=xlColumns, Type:=xlLinear, Date:=xlDay, Step:=1, Trend:=False
    End With
    
'    With .Range("C:C")
'      .Replace "3@", "", xlPart
'      .Replace "5@", "", xlPart
'      .Replace "7@", "", xlPart
'      .Replace "9@", "", xlPart
'    End With
    
    With .Range("A" & y + 2)
      .Value = "TOTAL"
      .Offset(0, 3).Value = t1
      .Offset(0, 4).Value = t2
      .Offset(0, 5).Value = t3
      .Offset(0, 6).Value = t4
    End With
    
    With .Range("A" & y + 3)
      .Value = "NET"
      .Offset(0, 6).Value = .Parent.Range("F" & y + 2) - .Parent.Range("D" & y + 2)
    End With
    
    lr = .Range("G" & Rows.Count).End(3).Row
'    With .Range("A1:G" & lr)
'      .Borders.LineStyle = xlContinuous
'      .Borders.Color = 11184814
'    End With

    With .Range("A" & lr - 1 & ":A" & lr)
      .Interior.Color = vbYellow
      .Font.Bold = True
    End With
    
  End With
  Application.ScreenUpdating = True
End Sub

🫡
 
Upvote 0
Solution
Try the following macro to know how long the macro runs without formats. I also made some improvements.
Awesome !
really fast and gives 0.610 sec
also when enable theses
VBA Code:
 With .Range("C:C")
      .Replace "3@", "", xlPart
      .Replace "5@", "", xlPart
      .Replace "7@", "", xlPart
      .Replace "9@", "", xlPart
    End With
    
    
  
    With .Range("A1:G" & lr)
      .Borders.LineStyle = xlContinuous
      .Borders.Color = 11184814
    End With
the same speed , there is no difference.
indeed I don't understand theses
With .Range("C:C")
.Replace "3@", "", xlPart
.Replace "5@", "", xlPart
.Replace "7@", "", xlPart
.Replace "9@", "", xlPart
End With
what work for it?:(
anyway thank you so much for your time and help.;)
 
Upvote 0
the same speed , there is no difference.
indeed I don't understand theses
It is to sort columns B and C with respect to the order in which they appear in the columns:
1737037164302.png

also when enable theses

Then try this:
VBA Code:
Sub merging_multiple_columns()
  Dim a As Variant, b As Variant, ky As Variant
  Dim dic As Object
  Dim i&, j&, u&, y&, lr&, nRow&
  Dim t1 As Double, t2 As Double, t3 As Double, t4 As Double
  
  Set dic = CreateObject("Scripting.Dictionary")
  
  With Sheets("SUMMARY")
    lr = .Range("B" & Rows.Count).End(3).Row
    a = .Range("A1:J" & lr).Value

    For i = 3 To UBound(a)
      dic(a(i, 2)) = Empty
    Next
    u = dic.Count
  End With
  
  ReDim b(1 To (u * 4) + 2, 1 To 7)
  For i = 3 To UBound(a)
    For j = 3 To 10
      If a(i, j) <> 0 Then
'        ky = a(i, 2) & "|" & IIf(a(1, j) = "", a(1, j - 1), a(1, j))
        ky = a(i, 2) & "|" & IIf(a(1, j) = "", j - 1 & "@" & a(1, j - 1), j & "@" & a(1, j))
        If Not dic.exists(ky) Then
          y = y + 1
          dic(ky) = y
        End If
        nRow = dic(ky)
        b(nRow, 2) = Split(ky, "|")(0)
        b(nRow, 3) = Split(ky, "|")(1)
        Select Case j
          Case 3, 9
            b(nRow, 4) = b(nRow, 4) + a(i, j)
            t1 = t1 + a(i, j)
          Case 4, 10
            b(nRow, 5) = b(nRow, 5) + a(i, j)
            t2 = t2 + a(i, j)
          Case 5, 7
            b(nRow, 6) = b(nRow, 6) + a(i, j)
            t3 = t3 + a(i, j)
          Case 6, 8
            b(nRow, 7) = b(nRow, 7) + a(i, j)
            t4 = t4 + a(i, j)
        End Select
      End If
    Next
  Next
  
  Application.ScreenUpdating = False
  With Sheets("FINAL")
    .Range("A:G").Clear
    .Range("A:G").HorizontalAlignment = xlCenter
    .Range("D:G").NumberFormat = "#,##0.00;;-"
    
    With .Range("A1").Resize(1, 7)
      .Value = Array("ITEM", "NAME", "SHEET NAME", "PAID", "NOT PAID", "RECEIVED", "NOT REICEVED")
      .Interior.ColorIndex = 16
    End With
    
    With .Range("A2").Resize(y, UBound(b, 2))
      .Value = b
      .Parent.Range("D2:G" & y + 1).SpecialCells(xlCellTypeBlanks).Value = 0
      .Sort .Range("B2"), xlAscending, .Range("C2"), , xlAscending, Header:=xlNo
    End With
    
    With .Range("A2")
      .Value = 1
      .Resize(y).DataSeries Rowcol:=xlColumns, Type:=xlLinear, Date:=xlDay, Step:=1, Trend:=False
    End With
    
    With .Range("C:C")
      .Replace "3@", "", xlPart
      .Replace "5@", "", xlPart
      .Replace "7@", "", xlPart
      .Replace "9@", "", xlPart
    End With
    
    With .Range("A" & y + 2)
      .Value = "TOTAL"
      .Offset(0, 3).Value = t1
      .Offset(0, 4).Value = t2
      .Offset(0, 5).Value = t3
      .Offset(0, 6).Value = t4
    End With
    
    With .Range("A" & y + 3)
      .Value = "NET"
      .Offset(0, 6).Value = .Parent.Range("F" & y + 2) - .Parent.Range("D" & y + 2)
    End With
    
    lr = .Range("G" & Rows.Count).End(3).Row
    With .Range("A1:G" & lr)
      .Borders.LineStyle = xlContinuous
      .Borders.Color = 11184814
    End With

    With .Range("A" & lr - 1 & ":A" & lr)
      .Interior.Color = vbYellow
      .Font.Bold = True
    End With
    
  End With
  Application.ScreenUpdating = True
End Sub

second about running speed with 15000 row I think the code is slow , gives me 24.50 sec.
Consider that there are 15,000 records but 8 columns have to be reviewed, 120 thousand cells are actually read.

;)
 
Upvote 0
it keep the code in post#4 is the best despite of this is not big difference.;)
the last version will give 0.9 and in post#4 gives 0.6 .
thanks again.:)
 
Upvote 0

Forum statistics

Threads
1,225,743
Messages
6,186,777
Members
453,370
Latest member
juliewar

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