Turning columns into blocks of rows

tonkerthomas

Board Regular
Joined
Feb 12, 2014
Messages
56
Good afternoon everybody.

I have a very large spreadsheet which contains around 2000 rows, the first six columns of which are master data. Thereafter, there is a number of six-column blocks that contain "sets" of transactional data. All rows have at least one six-column block, some have more, up to a maximum of 87 blocks (meaning 6*87 columns). Beyond the point at which any given row "runs out" of data, it's completely empty.

What I need to do is this: for any row which has more than one set of transactional data (i.e. any row with data in column M or beyond), I need to cut the data out, in six-column blocks, and paste that into new rows beneath the first set of transactional data.

So, we'd go from this:

ABCDEFGHIJKLMNOPQRSTUVWX
1M1M2M3M4M5M6T11T12T13T14T15T16T21T22T23T24T25T26T31T32T33T34T35T36
2M1M2M3M4M5M6T11T12T13T14T15T16
3M1M2M3M4M5M6T11T12T13T14T15T16T21T22T23T24T25T26

<tbody>
</tbody>

... to this:

ABCDEFGHIJKL
1M1M2M3M4M5M6T11T12T13T14T15T16
2T21T22T23T24T25T26
3T31T32T33T34T35T36
4M1M2M3M4M5M6T11T12T13T14T15T16
5M1M2M3M4M5M6T11T12T13T14T15T16
6T21T22T23T24T25T26

<tbody>
</tbody>


As you can see, the master data doesn't need to be copied down into the new rows, and once the transactional data "runs out" for any given line, I can stop inserting rows and cutting the data into them (so there won't be any empty rows in the final data).

Can anybody help me? I suspect this isn't terribly hard, but even though I think I understand the logic required I can't convert into into a macro.

My thanks, as ever, to anybody who has taken the time and trouble to read this, and in advance to anybody who has a crack at it.

Cheers

Jeff
 

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.
Try this for results on sheet2 Starting "A1".
Code:
[COLOR="Navy"]Sub[/COLOR] MG13Feb00
[COLOR="Navy"]Dim[/COLOR] Ray [COLOR="Navy"]As[/COLOR] Variant, Ac [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] n [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] c [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] St [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] num [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long[/COLOR]
Ray = ActiveSheet.Range("A1").CurrentRegion

ReDim nray(1 To UBound(Ray, 1) * 100, 1 To 12)
c = 1
[COLOR="Navy"]For[/COLOR] n = 1 To UBound(Ray, 1)
St = 6
[COLOR="Navy"]For[/COLOR] Ac = 1 To UBound(Ray, 2)
    [COLOR="Navy"]If[/COLOR] Not IsEmpty(Ray(n, Ac)) [COLOR="Navy"]Then[/COLOR]
    [COLOR="Navy"]If[/COLOR] Ac > 6 [COLOR="Navy"]Then[/COLOR] num = num + 1
        [COLOR="Navy"]If[/COLOR] Ac <= 12 [COLOR="Navy"]Then[/COLOR]
            nray(c, Ac) = Ray(n, Ac)
        [COLOR="Navy"]End[/COLOR] If
        
        [COLOR="Navy"]If[/COLOR] Ac > 12 [COLOR="Navy"]Then[/COLOR]
            [COLOR="Navy"]If[/COLOR] St Mod 6 = 0 [COLOR="Navy"]Then[/COLOR] c = c + 1: St = 6
            St = St + 1
            nray(c, St) = Ray(n, Ac)
        [COLOR="Navy"]End[/COLOR] If
    [COLOR="Navy"]End[/COLOR] If
 
 [COLOR="Navy"]Next[/COLOR] Ac
c = c + 1
[COLOR="Navy"]Next[/COLOR] n
Sheets("Sheet2").Range("A1").Resize(c, 12) = nray
[COLOR="Navy"]End[/COLOR] [COLOR="Navy"]Sub[/COLOR]
Regards Mick
 
Upvote 0
Ah, thank you, Mick. That's very, very nearly it, I reckon... it seems as though it's consolidating "blocks", though - so for instance, if the third cell of a block is blank, it's essentially deleting that cell in transit and I end up with five cells in the block rather than six. Can that be? And can we make it so that it keeps blank cells as valid data points? Have I explained that clearly?

Thanks a million for your help,

Jeff
 
Upvote 0
You're ending up with this:


ABCDEFGHIJKL
1M1M2M3M4M5M6T11T12T13T14T15T16
2T21T23T24T25T26
3T31T32T33T34T35T36

<tbody>
</tbody>

... where T22 in the source data is a blank cell.
 
Upvote 0
When I run the code on the first line with "T22" as an empty cell I Get this, not quite the same as your previous post . From columns 7, the three lines are shown as continuous (No Gaps)???:-


I'm not sure why that should be , But here is an alternative to show Blank cell as Blank cells:-
Code:
[COLOR=navy]Sub[/COLOR] MG13Feb49
[COLOR=navy]Dim[/COLOR] Ac [COLOR=navy]As[/COLOR] [COLOR=navy]Long,[/COLOR] n [COLOR=navy]As[/COLOR] [COLOR=navy]Long,[/COLOR] c [COLOR=navy]As[/COLOR] [COLOR=navy]Long,[/COLOR] St [COLOR=navy]As[/COLOR] [COLOR=navy]Long,[/COLOR] num [COLOR=navy]As[/COLOR] [COLOR=navy]Long,[/COLOR] t
[COLOR=navy]Dim[/COLOR] Rng [COLOR=navy]As[/COLOR] Range, Dn [COLOR=navy]As[/COLOR] Range
[COLOR=navy]Dim[/COLOR] Lst [COLOR=navy]As[/COLOR] [COLOR=navy]Long[/COLOR]
[COLOR=navy]Set[/COLOR] Rng = Range("A1", Range("A" & Rows.Count).End(xlUp))
c = 1
ReDim nray(1 To Rng.Count * 100, 1 To 12)
[COLOR=navy]For[/COLOR] [COLOR=navy]Each[/COLOR] Dn [COLOR=navy]In[/COLOR] Rng
 Lst = Cells(Dn.Row, Columns.Count).End(xlToLeft).Column
    [COLOR=navy]For[/COLOR] Ac = 1 To Lst
        [COLOR=navy]If[/COLOR] Ac <= 12 [COLOR=navy]Then[/COLOR]
            nray(c, Ac) = Rng(Dn.Row, Ac)
        [COLOR=navy]End[/COLOR] If
        
        [COLOR=navy]If[/COLOR] Ac > 12 [COLOR=navy]Then[/COLOR]
            [COLOR=navy]If[/COLOR] St Mod 6 = 0 [COLOR=navy]Then[/COLOR] c = c + 1: St = 6
            St = St + 1
            nray(c, St) = Rng(Dn.Row, Ac)
        [COLOR=navy]End[/COLOR] If
    [COLOR=navy]Next[/COLOR] Ac
c = c + 1
[COLOR=navy]Next[/COLOR] Dn
Sheets("Sheet2").Range("A1").Resize(c, 12) = nray
[COLOR=navy]End[/COLOR] [COLOR=navy]Sub[/COLOR]
Regards Mick
 
Last edited:
Upvote 0
When I run the code, this is how the first line looks, for me:-

M1M2M3M4M5M6T11T12T13T14T15T16
T21T23T24T25T26T31
T32T33T34T35T36

<colgroup><col width="64" span="12" style="width:48pt"> </colgroup><tbody>
</tbody>
 
Last edited:
Upvote 0
That's weird... for the first couple of hundred rows of the source data, it works perfectly, and then on row 206, it picks up the first cell of the first data block and then skips the next five, even though they're not blank. Thereafter the same thing happens regularly - dropping three, four, five data points at a time. I don't understand your code enough to figure out what might be happening. I can't see any reason that it works in most places and not in others - there doesn't seem to be anything different about the data which causes it to happen. Any ideas?

EDIT: the "first couple of hundred rows" thing is a red herring, because if I delete the first couple of hundred rows from the data and re-run, the same issues occur in the same place.
 
Last edited:
Upvote 0
Here's two source lines and two results: the first (Master1) fails, and the second (Master2) works perfectly. Does that help? Sorry, I'm not having much joy formatting this stuff after I've pasted it in... :(

12030Master119-4-201118-4-202018-4-2020#1018560213.144,98EUR19-4-201118-4-2020Annual#10185634.900,00EUR19-4-201118-4-2020Annual#1018645209.530,00EUR1-7-201018-4-2011n/a#26503222.000,00EUR19-4-201118-4-2020Annual#318561798.786,96EUR1-4-200230-6-2010Annual
12051Master21-10-201631-12-201831-12-2018#101689558.050,00EUR1-10-201631-12-2018Annual#101702338.700,00EUR1-7-201630-9-2016Annual#29449746.450,00EUR1-4-201630-6-2016n/a#297591638.700,00EUR1-7-201630-9-2016Annual
12030Master119-4-201118-4-202018-4-2020#1018560213.144,98EUR19-4-201118-4-2020Annual
#10185634.900,00EUR19-4-201118-4-2020Annual
#1018645209.530,00EUR1-7-201018-4-2011n/a
#26503222.000,00EUR19-4-201118-4-2020Annual
#318561798.786,96EUR1-4-200230-6-2010Annual
12051Master21-10-201612/31/201831-12-2018#1016895#101702338700EUR1-7-20169/30/2016
Annual#29449746450EUR1-4-20166/30/2016
n/a#297591638700EUR1-7-20169/30/2016
Annual

<tbody>
</tbody>
 
Upvote 0
I posted this on another Excel Board and they came up with this:

Code:
Sub RearrangeData()
Dim x, y(), z, i As Long, ii As Long, iii As Long, iv As Long, v As Long

With ActiveSheet.Cells(1).CurrentRegion
x = .Value2
For i = 1 To UBound(x, 1)
iii = iii + 1: ReDim Preserve y(1 To 12, 1 To iii)
For ii = 1 To 12
y(ii, iii) = x(i, ii)
Next
iv = 13
Do Until x(i, iv) = vbNullString
v = 6
iii = iii + 1: ReDim Preserve y(1 To 12, 1 To iii)
For ii = iv To iv + 5
v = v + 1
y(v, iii) = x(i, ii)
Next
iv = iv + 6
If iv >= UBound(x, 2) Then Exit Do
Loop
Next
If iii > .Parent.Rows.Count Then
MsgBox "There are insufficient rows on the worksheet to rearrange the data.", 16, "Data too large"
Exit Sub
End If
ReDim z(1 To iii, 1 To 12)
For i = 1 To iii
For ii = 1 To 12
z(i, ii) = y(ii, i)
Next
Next
.Clear
.Parent.[a1].Resize(iii, 12) = z
End With

End Sub

It works perfectly. The funny thing is, I have two source files, one of which works perfectly with your code, and the other not - so it MUST be something to do with the data itself. Whatever that is, though, the above code avoids the problem.

Thank you ever so much for your help, Mick. I don't generally crowdsource my help, but I was in a bit of a hurry with this so I needed to put more than one line in the water - I hope you're not offended, and if you are, I'm genuinely sorry. I hope the answer is as enlightening for you as it was for me.

Cheers

Jeff
 
Upvote 0

Forum statistics

Threads
1,214,583
Messages
6,120,378
Members
448,955
Latest member
BatCoder

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