VBA to Transpose Data

jrock8859

New Member
Joined
Oct 11, 2022
Messages
5
Office Version
  1. 365
Platform
  1. Windows
Hi,

I would like a VBA that will transpose the data set like this below. I am at a loss of where to start. I am good with VBA for the basic excel functions but I learn by reverse engineering things.

Columns A,B,C is how I am starting, I want to finish with it looking like Columns F and beyond

Tank you

Data.png
 

Excel Facts

Best way to learn Power Query?
Read M is for (Data) Monkey book by Ken Puls and Miguel Escobar. It is the complete guide to Power Query.
This will work for your example:

VBA Code:
Sub transpose()
    Dim lRow As Integer
    Dim c As Integer
    Dim r As Integer
    c = 6
    r = 1

    lRow = Cells(Rows.Count, 1).End(xlUp).Row
    For i = 2 To lRow
        If Cells(i, 1).Value = Cells(i - 1, 1).Value Then
            For ii = 0 To 1
                Cells(r, c).Value = Cells(i, 2 + ii).Value
                c = c + 1
            Next
        Else
            c = 6
            r = r + 1
            For ii = 0 To 2
                Cells(r, c).Value = Cells(i, 1 + ii).Value
                c = c + 1
            Next
        End If
    Next
End Sub
 
Upvote 0
Hi and welcome to MrExcel!

Here is another macro for you to consider:

VBA Code:
Sub TransposeData()
  Dim dic As Object
  Dim a As Variant, b As Variant
  Dim i As Long, n As Long, lr As Long, y As Long
  Dim nrow As Long, ncol As Long
 
  lr = Range("A" & Rows.Count).End(3).Row
  a = Range("A1:C" & lr).Value
  n = Evaluate("=MAX(COUNTIF(A2:A" & lr & ",A2:A" & lr & "))")
  ReDim b(1 To UBound(a, 1), 1 To (n * 2) + 1)
 
  Set dic = CreateObject("Scripting.Dictionary")
 
  y = 1
  b(1, 1) = a(1, 1)
  For i = 2 To UBound(a, 1)
    If Not dic.exists(a(i, 1)) Then
      y = y + 1
      dic(a(i, 1)) = y & "|" & 2
      b(y, 1) = a(i, 1)
    End If
   
    nrow = Split(dic(a(i, 1)), "|")(0)
    ncol = Split(dic(a(i, 1)), "|")(1)
   
    b(1, ncol) = a(1, 2)
    b(1, ncol + 1) = a(1, 3)
    b(nrow, ncol) = a(i, 2)
    b(nrow, ncol + 1) = a(i, 3)
   
    ncol = ncol + 2
    dic(a(i, 1)) = nrow & "|" & ncol
   
  Next
 
  Range("F1").Resize(y, UBound(b, 2)).Value = b
End Sub
 
Upvote 0
If it's not a lot of data, try this macro:

VBA Code:
Sub TransposeData2()
  Dim c As Range, f As Range
  
  For Each c In Range("A2", Range("A" & Rows.Count).End(3))
    Set f = Range("F:F").Find(c.Value, , xlValues, xlWhole)
    If f Is Nothing Then
      Range("F" & Rows.Count).End(3)(2).Resize(1, 3).Value = c.Resize(1, 3).Value
    Else
      Cells(f.Row, Columns.Count).End(1)(1, 2).Resize(1, 2).Value = c.Offset(0, 1).Resize(1, 2).Value
    End If
  Next
End Sub
 
Upvote 0
This will work for your example:

VBA Code:
Sub transpose()
    Dim lRow As Integer
    Dim c As Integer
    Dim r As Integer
    c = 6
    r = 1

    lRow = Cells(Rows.Count, 1).End(xlUp).Row
    For i = 2 To lRow
        If Cells(i, 1).Value = Cells(i - 1, 1).Value Then
            For ii = 0 To 1
                Cells(r, c).Value = Cells(i, 2 + ii).Value
                c = c + 1
            Next
        Else
            c = 6
            r = r + 1
            For ii = 0 To 2
                Cells(r, c).Value = Cells(i, 1 + ii).Value
                c = c + 1
            Next
        End If
    Next
End Sub

Thank you for this, I have a better understanding on how this functions now. Is there a way to have it run faster if the data set is rather large, say a couple hundred rows?
 
Upvote 0
Using arrays may help. Also consider to turn off and on screen update.

VBA Code:
Sub transpose()
  Application.ScreenUpdating = False
  // Code here
  Application.ScreenUpdating = True
End Sub
@DanteAmor 's dictionary solution might be faster.
 
Upvote 0
Hi and welcome to MrExcel!

Here is another macro for you to consider:

VBA Code:
Sub TransposeData()
  Dim dic As Object
  Dim a As Variant, b As Variant
  Dim i As Long, n As Long, lr As Long, y As Long
  Dim nrow As Long, ncol As Long
 
  lr = Range("A" & Rows.Count).End(3).Row
  a = Range("A1:C" & lr).Value
  n = Evaluate("=MAX(COUNTIF(A2:A" & lr & ",A2:A" & lr & "))")
  ReDim b(1 To UBound(a, 1), 1 To (n * 2) + 1)
 
  Set dic = CreateObject("Scripting.Dictionary")
 
  y = 1
  b(1, 1) = a(1, 1)
  For i = 2 To UBound(a, 1)
    If Not dic.exists(a(i, 1)) Then
      y = y + 1
      dic(a(i, 1)) = y & "|" & 2
      b(y, 1) = a(i, 1)
    End If
  
    nrow = Split(dic(a(i, 1)), "|")(0)
    ncol = Split(dic(a(i, 1)), "|")(1)
  
    b(1, ncol) = a(1, 2)
    b(1, ncol + 1) = a(1, 3)
    b(nrow, ncol) = a(i, 2)
    b(nrow, ncol + 1) = a(i, 3)
  
    ncol = ncol + 2
    dic(a(i, 1)) = nrow & "|" & ncol
  
  Next
 
  Range("F1").Resize(y, UBound(b, 2)).Value = b
End Sub

Hi Dante,

Thank you for your solution. If you wouldn't mind, for my learning purposes. Let's say I only have 2 columns now instead of 3, how would this effect the vba?
 
Upvote 0
for my learning purposes. Let's say I only have 2 columns now instead of 3

I added a * to the changed lines in the macro. By the way, jrock8859's macro is quite fast.

VBA Code:
Sub TransposeData_1col()
  Dim dic As Object
  Dim a As Variant, b As Variant
  Dim i As Long, n As Long, lr As Long, y As Long
  Dim nrow As Long, ncol As Long
  
  lr = Range("A" & Rows.Count).End(3).Row
  a = Range("A1:B" & lr).Value              '*
  n = Evaluate("=MAX(COUNTIF(A2:A" & lr & ",A2:A" & lr & "))")
  ReDim b(1 To UBound(a, 1), 1 To n + 1)    '*
  
  Set dic = CreateObject("Scripting.Dictionary")
  
  y = 1
  b(1, 1) = a(1, 1)
  For i = 2 To UBound(a, 1)
    If Not dic.exists(a(i, 1)) Then
      y = y + 1
      dic(a(i, 1)) = y & "|" & 2
      b(y, 1) = a(i, 1)
    End If
    
    nrow = Split(dic(a(i, 1)), "|")(0)
    ncol = Split(dic(a(i, 1)), "|")(1)
    
    b(1, ncol) = a(1, 2)
    'b(1, ncol + 1) = a(1, 3)         '*
    b(nrow, ncol) = a(i, 2)
    'b(nrow, ncol + 1) = a(i, 3)      '*
    
    ncol = ncol + 1                   '*
    dic(a(i, 1)) = nrow & "|" & ncol
    
  Next
  
  Range("F1").Resize(y, UBound(b, 2)).Value = b
End Sub
 
Upvote 0

Forum statistics

Threads
1,224,816
Messages
6,181,141
Members
453,021
Latest member
Justyna P

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