Table Manipulation

lbird2

Board Regular
Joined
Dec 10, 2014
Messages
78
Office Version
  1. 365
Platform
  1. Windows
Info1Info2Info3Info4Data1Data2Data3Data4
A1BlueHot0.40.51.32.7
B2WhiteCold2.30.11.58.1
C3GoldHot2.67.16.10.8
D4BrownCold0.92.62.31.1
E1WhiteHot0.10.62.32.0
F7RedCold5.21.08.15.1
G2PurpleCold1.60.14.03.5

<tbody>
</tbody>


I find I need to do this often so I'm looking for a way to automate. I would like to repeat the "Info" rows and move each of the "Data" values to a single column of data. The table below shows what the result would be for the first two "Data" columns.

I get data in this format often and find the converted table to be much more flexible for analysis.

To make matters harder, the number of Info and Data items vary so I would like to account for that.

Any help would be greatly appreciated and would make my life a lot less tedious.


Info1Info2Info3Info4Data
A1BlueHot0.4
B2WhiteCold2.3
C3GoldHot2.6
D4BrownCold0.9
E1WhiteHot0.1
F7RedCold5.2
G2PurpleCold1.6
A1BlueHot0.5
B2WhiteCold0.1
C3GoldHot7.1
D4BrownCold2.6
E1WhiteHot0.6
F7RedCold1.0
G2PurpleCold0.1

<tbody>
</tbody>
 

Excel Facts

How can you automate Excel?
Press Alt+F11 from Windows Excel to open the Visual Basic for Applications (VBA) editor.
Try this for results on sheet2.
Code:
[COLOR="Navy"]Sub[/COLOR] MG08Jun12
[COLOR="Navy"]Dim[/COLOR] Ray [COLOR="Navy"]As[/COLOR] Variant, col [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long,[/COLOR] n [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long[/COLOR]
[COLOR="Navy"]Dim[/COLOR] Ac [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] Ac2 [COLOR="Navy"]As[/COLOR] [COLOR="Navy"]Long[/COLOR]
Ray = Cells(1).CurrentRegion
St = 1
ReDim nray(1 To UBound(Ray, 1) * UBound(Ray, 2) - 4, 1 To 5)
[COLOR="Navy"]For[/COLOR] Ac = 5 To UBound(Ray, 2)
    col = col + 1
    St = IIf(c = 0, 1, 2)
    [COLOR="Navy"]For[/COLOR] n = St To UBound(Ray, 1)
        c = c + 1
        [COLOR="Navy"]For[/COLOR] Ac2 = 1 To 4
            nray(c, Ac2) = Ray(n, Ac2)
            nray(c, 5) = Ray(n, Ac)
        [COLOR="Navy"]Next[/COLOR] Ac2
     [COLOR="Navy"]Next[/COLOR] n
[COLOR="Navy"]Next[/COLOR] Ac
Sheets("Sheet2").Range("A1").Resize(c, 5).Value = nray
[COLOR="Navy"]End[/COLOR] [COLOR="Navy"]Sub[/COLOR]
Regards Mick
 
Upvote 0
Get and transform helps tremendously here, just convert to table, click from table and choose the right unpivot feature from the transformation tab. You either select the info columns or the data columns before choosing either unpivot columns or unpivot other columns.
 
Upvote 0
Thanks Mick. This works great but if I add another "Info" column, it does not catch it.
It works fine if I add additional "Data" columns.

I would have no problem editing the macro as needed to account for more "Info" columns. Which line do I edit to do that?

Thanks again it's a neat little macro.
 
Upvote 0
The code should catch any column and row within the "CurrentRegion"
If you have a complete blank row or blank column at the end of your data that's where the Current region will end.
So is there a blank column between you basic data and the "Info Column".???

Maybe you can show an Example of your data with the "info column "
 
Upvote 0
If I add additional "Data" columns they get picked up nicely but if I add an additional "Info" column (say Info5 between Info4 and Data1), it gets ignored. Hope that makes sense.

I think the Get Transform may solve a lot of issues but I can't install the addon due to firewall issues at the workplace.
 
Upvote 0
Example 1:
BEFORE
Info1Info2Info3Info4Data1Data2Data3Data4
A1ZHot2.31.50.87.4
B2YCold2.31.50.87.4
C3XHot2.31.50.87.4
D4WCold2.31.50.87.4
E5VHot2.31.50.87.4
F6UCold2.31.50.87.4
G7THot2.31.50.87.4

<colgroup><col width="64" span="8" style="width:48pt"> </colgroup><tbody>
</tbody>


AFTER
Info1Info2Info3Info4Data
A1ZHot2.3
B2YCold2.3
C3XHot2.3
D4WCold2.3
E5VHot2.3
F6UCold2.3
G7THot2.3
A1ZHot1.5
B2YCold1.5
C3XHot1.5
D4WCold1.5
E5VHot1.5
F6UCold1.5
G7THot1.5
A1ZHot0.8
B2YCold0.8
C3XHot0.8
D4WCold0.8
E5VHot0.8
F6UCold0.8
G7THot0.8
A1ZHot7.4
B2YCold7.4
C3XHot7.4
D4WCold7.4
E5VHot7.4
F6UCold7.4
G7THot7.4

<colgroup><col width="64" span="5" style="width:48pt"> </colgroup><tbody>
</tbody>


Example 2:

BEFORE
Y1Y2Y3Y4Y5Y6Data AData B
1990AFallNorthUofMAlpha58
1991BSummerEastMSUAlpha58
1992CWinterNorthCMUAlpha58

<colgroup><col width="64" span="8" style="width:48pt"> </colgroup><tbody>
</tbody>


AFTER
Y1Y2Y3Y4Y5Y6Data
1990AFallNorthUofMAlpha5
1991BSummerEastMSUAlpha5
1992CWinterNorthCMUAlpha5
1990AFallNorthUofMAlpha8
1991BSummerEastMSUAlpha8
1992CWinterNorthCMUAlpha8

<colgroup><col width="64" span="7" style="width:48pt"> </colgroup><tbody>
</tbody>
 
Upvote 0
I installed the Power Query addon and was able to do what I wanted. Thanks all!
 
Upvote 0
This should work in all cases, provided your data columns always start with the word data:

Code:
Option Explicit

Sub StartUnpivotData()
    Dim oSource As Range
    Dim oTarget As Range
    On Error Resume Next
    Set oSource = Application.InputBox("Please select the source data", "Unpivot tool, source data", ActiveCell.CurrentRegion.Address, , , , , 8)
    If Not oSource Is Nothing Then
        Set oTarget = Application.InputBox("Please select where you want the result to go", "Unpivot tool, target location", , , , , , 8)
        If Not oTarget Is Nothing Then
            On Error GoTo 0
            Unpivot oSource, oTarget
        End If
    End If
End Sub

Sub Unpivot(oSource As Range, oTarget As Range)
    Dim vData As Variant
    Dim vNewData() As Variant

    Dim lRow As Long
    Dim lCol As Long
    Dim lNewRow As Long
    Dim lNewCol As Long

    Dim lInfoColCt As Long
    Dim lDataColCt As Long
    Dim bDataFound As Boolean
    vData = oSource.Value2
    'Get # of info columns
    For lInfoColCt = 1 To UBound(vData, 2)
        If LCase(vData(1, lInfoColCt)) Like "data*" Then
            bDataFound = True
            Exit For
        End If
    Next
    If bDataFound Then
        lInfoColCt = lInfoColCt - 1
        lDataColCt = UBound(vData, 2) - lInfoColCt

        ReDim vNewData(1 To lDataColCt * (UBound(vData, 1)), 1 To lInfoColCt + 1)
        For lCol = 1 To lInfoColCt
            vNewData(1, lCol) = vData(1, lCol)
        Next
        lNewRow = 1
        vNewData(1, lInfoColCt + 1) = "Data"
        For lRow = 2 To UBound(vData, 1)
            For lNewCol = 1 To lDataColCt
                lNewRow = lNewRow + 1
                For lCol = 1 To lInfoColCt
                    vNewData(lNewRow, lCol) = vData(lRow, lCol)
                Next
                vNewData(lNewRow, lInfoColCt + 1) = vData(lRow, lInfoColCt + lNewCol)
            Next
        Next
        oTarget.Resize(UBound(vNewData, 1), UBound(vNewData, 2)).Value2 = vNewData
    Else
        MsgBox "Unable to find any data columns"
    End If
End Sub
 
Upvote 0

Forum statistics

Threads
1,216,098
Messages
6,128,812
Members
449,468
Latest member
AGreen17

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