Help with converting multiple columns into rows

Punxsu

New Member
Joined
Aug 23, 2012
Messages
18
Hi Everyone,

I am trying to convert

Excel 2010
ABCDEFGHI
SchoolIDRaceAgeGenderGroup
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational

<colgroup><col style="width: 25pxpx"><col><col><col><col><col><col><col><col><col></colgroup><thead>
</thead><tbody>
[TD="align: center"]1[/TD]

[TD="align: right"]2010[/TD]
[TD="align: right"]2011[/TD]
[TD="align: right"]2012[/TD]

[TD="align: center"]2[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]15[/TD]

[TD="align: right"] 161 [/TD]
[TD="align: right"] 174 [/TD]
[TD="align: right"]307[/TD]

[TD="align: center"]3[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]16[/TD]

[TD="align: right"] 174 [/TD]
[TD="align: right"] 192 [/TD]
[TD="align: right"]509[/TD]

[TD="align: center"]4[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]17[/TD]

[TD="align: right"] 157 [/TD]
[TD="align: right"] 181 [/TD]
[TD="align: right"]121[/TD]

[TD="align: center"]5[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]15[/TD]

[TD="align: right"] 176 [/TD]
[TD="align: right"] 165 [/TD]
[TD="align: right"]106[/TD]

[TD="align: center"]6[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]16[/TD]

[TD="align: right"] 186 [/TD]
[TD="align: right"] 173 [/TD]
[TD="align: right"]190[/TD]

[TD="align: center"]7[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]17[/TD]

[TD="align: right"] 176 [/TD]
[TD="align: right"] 177 [/TD]
[TD="align: right"]404[/TD]

</tbody>
Data




to



Excel 2010
ABCDEFGH
SchoolIDRaceAgeGenderGroupYear Size
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMBlackFemaleLocal
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational
ADMCaucasianFemaleInternational

<colgroup><col style="width: 25pxpx"><col><col><col><col><col><col><col><col></colgroup><thead>
</thead><tbody>
[TD="align: center"]1[/TD]

[TD="align: center"]2[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]15[/TD]

[TD="align: right"]2010[/TD]
[TD="align: right"] 161 [/TD]

[TD="align: center"]3[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]15[/TD]

[TD="align: right"]2011[/TD]
[TD="align: right"] 174 [/TD]

[TD="align: center"]4[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]15[/TD]

[TD="align: right"]2012[/TD]
[TD="align: right"] 307 [/TD]

[TD="align: center"]5[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]16[/TD]

[TD="align: right"]2010[/TD]
[TD="align: right"] 174 [/TD]

[TD="align: center"]6[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]16[/TD]

[TD="align: right"]2011[/TD]
[TD="align: right"] 192 [/TD]

[TD="align: center"]7[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]16[/TD]

[TD="align: right"]2012[/TD]
[TD="align: right"] 509 [/TD]

[TD="align: center"]8[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]17[/TD]

[TD="align: right"]2010[/TD]
[TD="align: right"] 157 [/TD]

[TD="align: center"]9[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]17[/TD]

[TD="align: right"]2011[/TD]
[TD="align: right"] 181 [/TD]

[TD="align: center"]10[/TD]

[TD="align: right"]1[/TD]

[TD="align: right"]17[/TD]

[TD="align: right"]2012[/TD]
[TD="align: right"] 121 [/TD]

[TD="align: center"]11[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]15[/TD]

[TD="align: right"]2010[/TD]
[TD="align: right"] 176 [/TD]

[TD="align: center"]12[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]15[/TD]

[TD="align: right"]2011[/TD]
[TD="align: right"] 165 [/TD]

[TD="align: center"]13[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]15[/TD]

[TD="align: right"]2012[/TD]
[TD="align: right"] 106 [/TD]

[TD="align: center"]14[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]16[/TD]

[TD="align: right"]2010[/TD]
[TD="align: right"] 186 [/TD]

[TD="align: center"]15[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]16[/TD]

[TD="align: right"]2011[/TD]
[TD="align: right"] 173 [/TD]

[TD="align: center"]16[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]16[/TD]

[TD="align: right"]2012[/TD]
[TD="align: right"] 190 [/TD]

[TD="align: center"]17[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]17[/TD]

[TD="align: right"]2010[/TD]
[TD="align: right"] 176 [/TD]

[TD="align: center"]18[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]17[/TD]

[TD="align: right"]2011[/TD]
[TD="align: right"] 177 [/TD]

[TD="align: center"]19[/TD]

[TD="align: right"]2[/TD]

[TD="align: right"]17[/TD]

[TD="align: right"]2012[/TD]
[TD="align: right"] 404 [/TD]

</tbody>
Results




Any help with a VBA code (possibly with comments) would help. Thanks.

Bert
 
ok, here is my first effort, i am sure the purists will advise better methods, but I have tried to keep it simple for ease of understanding

Code:
Sub dorow2()
'
'****
' get current sheet name with old data and number of rows of data
'****
'
cursheet = ActiveSheet.Name
intNumRows = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row

'
'****
' Add a new sheet and copy the headers from old sheet and add in two new ones
'****
'
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "NewList"

Worksheets(cursheet).Range("A1:F1").Copy Destination:=Worksheets("NewList").Range("A1")
Worksheets("Newlist").Range("G1").Value = "Year"
Worksheets("Newlist").Range("H1").Value = "Size"

'
'****
' using the current sheet stop thru the old data
'****
'
Worksheets(cursheet).Select

newrow = 2
For j = 2 To intNumRows
    With ActiveSheet

'
'****
' get the last year column, could be 9 but some years might be missing
'****
'
        LastCol = .Cells(j, .Columns.Count).End(xlToLeft).Column
        
'
'****
' copy the fixed data, then add the year, and expand
'****
'
        For k = 7 To LastCol
            Worksheets(cursheet).Range("A" & j & ":F" & j).Copy Destination:=Worksheets("NewList").Range("A" & newrow)
            Worksheets("Newlist").Range("G" & newrow).Value = 2003 + k
            Worksheets("Newlist").Range("H" & newrow).Value = Worksheets(cursheet).Cells(j, k).Value
            newrow = newrow + 1
        Next k
    End With
Next j
End Sub
 
Upvote 0
Hello jimrward,

Thanks for the code. I was able to change a few things to use with my full data--the comments were very helpful. The real data has Years from 2010 to 2050 and over 120,000 rows so it naturally won't fit a single worksheet. I (manually) cut the file into smaller ones (like 7500 rows each) and it freezes. I would like your (or anyone's) suggestion on the matter. Ultimately, I intend to use the final (transposed) file to create Pivot Tables to summarize the file for analyses.

Thanks to you and anyone reading.

Bert




ok, here is my first effort, i am sure the purists will advise better methods, but I have tried to keep it simple for ease of understanding

Code:
Sub dorow2()
'
'****
' get current sheet name with old data and number of rows of data
'****
'
cursheet = ActiveSheet.Name
intNumRows = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row

'
'****
' Add a new sheet and copy the headers from old sheet and add in two new ones
'****
'
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "NewList"

Worksheets(cursheet).Range("A1:F1").Copy Destination:=Worksheets("NewList").Range("A1")
Worksheets("Newlist").Range("G1").Value = "Year"
Worksheets("Newlist").Range("H1").Value = "Size"

'
'****
' using the current sheet stop thru the old data
'****
'
Worksheets(cursheet).Select

newrow = 2
For j = 2 To intNumRows
    With ActiveSheet

'
'****
' get the last year column, could be 9 but some years might be missing
'****
'
        LastCol = .Cells(j, .Columns.Count).End(xlToLeft).Column
        
'
'****
' copy the fixed data, then add the year, and expand
'****
'
        For k = 7 To LastCol
            Worksheets(cursheet).Range("A" & j & ":F" & j).Copy Destination:=Worksheets("NewList").Range("A" & newrow)
            Worksheets("Newlist").Range("G" & newrow).Value = 2003 + k
            Worksheets("Newlist").Range("H" & newrow).Value = Worksheets(cursheet).Cells(j, k).Value
            newrow = newrow + 1
        Next k
    End With
Next j
End Sub
 
Upvote 0
ok, sounds good, the Lastcol piece of code should pick up the extra years

where does the data originate from, is it a text file you import ??

what sort of analysis are you trying to do with pivot tables ??

I am not sure how you are going to proceed with that amount of data when its on different sheets
 
Upvote 0
The table I am transposing is in Excel. A snapshot of it was what I provided earlier. I am able to create the pivot tables without even transposing the "Year" and "Size" over the rest of the rows but it limits the analyses (that can be done) because Excel then considers the "Year" as values on the row field. The excel data is resident in only one worksheet but when I run the macro (and consequently transposing it),the resulting table will be more than what one excel sheet can hold.

Nonetheless thanks for your help. I really appreciate your input.
 
Upvote 0
Can you post your amended code in case it of use to anyone else, you never know
 
Upvote 0
It's essentially the same as the one you provided. It is provided below. Thanks.

Public LastColumn As Long, LastRow As Long, NewRow As Long
Dim CurrSheet
Sub Some()
' Get current sheet name with old data and number of rows & columns of data
CurrSheet = ActiveSheet.Name
LastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row
LastColumn = ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column

' Change Headers to Years
ActiveSheet.Range("G1").Value = "2010 Size"
For i = 1 To LastColumn
With ActiveSheet
If InStr(UCase(.Cells(1, i).Value), "SIZE") Then
JustYears = Mid(.Cells(1, i).Value, 1, 4)
.Cells(1, i).Value = JustYears
End If
End With
Next i
End Sub
Sub DoRow()
' Add a new sheet and copy the headers from old sheet and add in two new ones
On Error Resume Next
ScreenUpdating = False
Worksheets("NewList").Delete
Worksheets.Add(After:=Worksheets(Worksheets.Count)).Name = "NewList"


Worksheets(CurrSheet).Range("A1:F1").Copy Destination:=Worksheets("NewList").Range("A1")
Worksheets("NewList").Range("G1").Value = "Year"
Worksheets("NewList").Range("H1").Value = "Size"

' Using the current sheet step thru the old data
Worksheets(CurrSheet).Select

NewRow = 2
For j = 2 To LastRow
With ActiveSheet

' Get the last year column, could be 9 but some years might be missing
LastColumn = .Cells(j, .Columns.Count).End(xlToLeft).Column

' Copy the fixed data, then add the year, and expand
For k = 7 To LastColumn
Worksheets(CurrSheet).Range("A" & j & ":F" & j).Copy Destination:=Worksheets("NewList").Range("A" & NewRow)
Worksheets("NewList").Range("G" & NewRow).Value = 2003 + k
Worksheets("NewList").Range("H" & NewRow).Value = Worksheets(CurrSheet).Cells(j, k).Value
NewRow = NewRow + 1
Next k
End With
Next j
End Sub


Sub CallEm()
Call Some
Call DoRow
End Sub
 
Upvote 0
Punsxu

Welcome to the MrExcel board!

Sorry I didn't get to comment on the code in the other thread you asked about but I'm assuming it was related to this problem so I have commented this code. You should find this code somewhat faster than the other code. I just hope it does what you want, or close enough that you can tweak it or ask for refinements.

Note that in the code the 'Fixed' columns and the 'Year' columns are hard-coded so adjust to suit your data. I guess the year columns could be calculated but I stopped short of that.

<font face=Courier New><br><SPAN style="color:#00007F">Sub</SPAN> Rearrange()<br>    <SPAN style="color:#00007F">Dim</SPAN> lr <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, rws <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>    <SPAN style="color:#00007F">Dim</SPAN> fixedcols <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, swapcols <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, blocksize <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>    <SPAN style="color:#00007F">Dim</SPAN> i <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, j <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, k <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, z <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, y <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN>, x <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">Long</SPAN><br>    <SPAN style="color:#00007F">Dim</SPAN> a, b, Headers<br><br>    <SPAN style="color:#00007F">Const</SPAN> ConstCols <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN> = "A:F"   <SPAN style="color:#007F00">'<- Adjust to suit</SPAN><br>    <SPAN style="color:#00007F">Const</SPAN> ColsToRows <SPAN style="color:#00007F">As</SPAN> <SPAN style="color:#00007F">String</SPAN> = "G:I"  <SPAN style="color:#007F00">'<- Adjust to suit ('Year' cols)</SPAN><br>    <br>    fixedcols = Columns(ConstCols).Columns.Count<br>    swapcols = Columns(ColsToRows).Columns.Count<br>    <br>    Application.ScreenUpdating = <SPAN style="color:#00007F">False</SPAN><br>    <br>    <SPAN style="color:#007F00">'With the original data sheet as the active sheet ..</SPAN><br>    <SPAN style="color:#00007F">With</SPAN> ActiveSheet<br>        <br>        <SPAN style="color:#007F00">'Collect headings from the 'fixed' columns + 2 more</SPAN><br>        Headers = .Range("A1").Resize(, fixedcols + 2).Value<br>        <br>        <SPAN style="color:#007F00">'Now change the last 2 headings</SPAN><br>        Headers(1, fixedcols + 1) = "Year"<br>        Headers(1, fixedcols + 2) = "Size"<br>        <br>        <SPAN style="color:#007F00">'Find how many rows of data we have. Assume headings in row 1</SPAN><br>        lr = .Cells(.Rows.Count, 1).End(xlUp).Row<br>        rws = lr - 1<br>        <br>        <SPAN style="color:#007F00">'Read all the data into an array</SPAN><br>        a = .Range("A1").Resize(lr, fixedcols + swapcols).Value<br>        <br>        <SPAN style="color:#007F00">'Work out how many rows we can process and still fit the results in a worksheet</SPAN><br>        blocksize = IIf(rws * swapcols < .Rows.Count, rws, (.Rows.Count - 1) / swapcols)<br>    <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">With</SPAN><br>    <br>    <SPAN style="color:#007F00">'Now process each block to go on a new sheet</SPAN><br>    <SPAN style="color:#00007F">For</SPAN> i = 2 <SPAN style="color:#00007F">To</SPAN> lr <SPAN style="color:#00007F">Step</SPAN> blocksize<br>        <br>        <SPAN style="color:#007F00">'Check in case we are up to the last block as it will likely be smaller</SPAN><br>        <SPAN style="color:#00007F">If</SPAN> i + blocksize > lr <SPAN style="color:#00007F">Then</SPAN><br>            blocksize = lr - i + 1<br>        <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">If</SPAN><br>        <br>        <SPAN style="color:#007F00">'Prepare an arry for the results of this block</SPAN><br>        <SPAN style="color:#00007F">ReDim</SPAN> b(1 <SPAN style="color:#00007F">To</SPAN> blocksize * swapcols, 1 <SPAN style="color:#00007F">To</SPAN> fixedcols + 2)<br>        <br>        <SPAN style="color:#007F00">'Work through each block of data</SPAN><br>        <SPAN style="color:#00007F">For</SPAN> j = 1 <SPAN style="color:#00007F">To</SPAN> blocksize<br>            <br>            <SPAN style="color:#007F00">'Temp variable to save recalculating this repeatedly</SPAN><br>            x = i + j - 1<br>            <br>            <SPAN style="color:#007F00">'Do a new result row for each 'year' column</SPAN><br>            <SPAN style="color:#00007F">For</SPAN> z = 1 <SPAN style="color:#00007F">To</SPAN> swapcols<br>                <br>                <SPAN style="color:#007F00">'Temp variable to save recalculating this repeatedly</SPAN><br>                y = (j - 1) * swapcols<br>                <br>                <SPAN style="color:#007F00">'Put the basic fixed column data into the results array row</SPAN><br>                <SPAN style="color:#00007F">For</SPAN> k = 1 <SPAN style="color:#00007F">To</SPAN> fixedcols<br>                    b(y + z, k) = a(x, k)<br>                <SPAN style="color:#00007F">Next</SPAN> k<br>                <br>                <SPAN style="color:#007F00">'Now put the year and size data into results array</SPAN><br>                b(y + z, fixedcols + 1) = a(1, fixedcols + z)<br>                b(y + z, fixedcols + 2) = a(x, fixedcols + z)<br>                <br>            <SPAN style="color:#00007F">Next</SPAN> z<br>            <br>        <SPAN style="color:#00007F">Next</SPAN> j<br>        <br>        <SPAN style="color:#007F00">'Add a new sheet to accept the results</SPAN><br>        Sheets.Add After:=Sheets(Sheets.Count)<br>        <br>        <SPAN style="color:#007F00">'Using the newly added sheet</SPAN><br>        <SPAN style="color:#00007F">With</SPAN> ActiveSheet<br>            <br>            <SPAN style="color:#007F00">'Put the headings in</SPAN><br>            .Range("A1").Resize(, fixedcols + 2).Value = Headers<br>            <br>            <SPAN style="color:#007F00">'Put the results array values into the sheet</SPAN><br>            .Range("A2").Resize(blocksize * swapcols, fixedcols + 2).Value = b<br>            <br>            <SPAN style="color:#007F00">'Adjust the column widths</SPAN><br>            .UsedRange.EntireColumn.AutoFit<br>        <SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">With</SPAN><br>        <br>    <SPAN style="color:#00007F">Next</SPAN> i<br>    Application.ScreenUpdating = <SPAN style="color:#00007F">True</SPAN><br><SPAN style="color:#00007F">End</SPAN> <SPAN style="color:#00007F">Sub</SPAN><br><br><br><br></FONT>
 
Upvote 0
Hello Peter_SSs,

I am lost for words. I am very impressed and I want to say a big Thank You for your time in developing and commenting the code. It works magnificently and very fastly. I spent a lot of time trying to understand the logic behind the "Processing each block to go on a new sheet". If you have time perhaps you can explain a little further.

It works great. Could you please provide (if you can) some help on how I can create pivot table(s) from the resulting sheets?

Thanks a ton. I am very grateful for your help.

Bertrand
 
Upvote 0
Hello Peter_SSs,

I am lost for words. I am very impressed and I want to say a big Thank You for your time in developing and commenting the code. It works magnificently and very fastly.
I'm glad I was on the right track for what you wanted. :)



I spent a lot of time trying to understand the logic behind the "Processing each block to go on a new sheet". If you have time perhaps you can explain a little further.
I'm not exactly sure what you are asking here but I'll try to explain the determination of the block size. Consider the data in your first post. As there are three 'year' columns (2010, 2011, 2012) each row of original data will occupy 3 rows when rearranged. Now just for a moment, let's pretend that a worksheet only contained 8 rows. In this case we could only convert 2 of your original rows on one sheet since 3 original rows would require 9 rows and we only have 8. So here we would have had to set the block size to 2 rows.

The other general comment is that the code is fast because it uses arrays. That is the data is manipulated in memory, not communucation back and forward between the code in memory and the worksheet itself.

To get a better understanding of the code, I suggest you again use your data from post number 1 and replace the first line below with the second, tricking the code into thinking we can only fit about 12 rows on a sheet (block size of 4 original rows * 3 year rows)
Code:
blocksize = IIf(rws * swapcols < .Rows.Count, rws, (.Rows.Count - 1) / swapcols)

blocksize = 4
Make sure the 'Locals' window is visible within the vba window (View|Locals Window)
Now, with that small sample data sheet active, step through the code a line at a time using the F8 key and keep checking what is happening to the variables in the Locals window.



Could you please provide (if you can) some help on how I can create pivot table(s) from the resulting sheets?
This is not an area I have much expertise in I'm afraid. If you are using Excel 2010, and haven't already, perhaps you should research the new PowerPivot feature. There is a new forum here (PowerPivot Questions.) devoted specially to it.
 
Upvote 0

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