Unpivot/Transpose columns (without blanks)

2

I have an asset hierarchy table in Excel:

enter image description here


For testing purposes, the table can be copied/pasted into Excel by using the text below:

Hint: Copy the text from the Stack Overflow edit mode--instead of copying from the preview mode (the text from edit mode will parse correctly in Excel).

Hierarchy Path  Spec 1  Spec 2  Spec 3  Spec 4  Spec 5  Spec 6  Spec 7  Spec 8  Spec 9  Spec 10
Passenger Car   A   B   C   D   E   F   G   H   I   J
Sport Utility Vehicle   H   I   J   K   L   M   N   O   P   
1/2 Ton Pick-Up Truck   Q   R   S   T   U   V   W   X       
3/4 Ton Pick-Up Truck   Y   Z   A   B   C   D   E           
Compact Van F   G   H   I   J   K               
Cargo Van   L   M   N   O   P                   
Light Duty Truck    Q   R   S   T   

Question:

For each Hierarchy Path, I want to:

  • Transpose the specs
  • Fill in the Hierarchy Path for each spec

Note: The number of specs varies per Hierarchy Path. I would like the number of rows to match the number of specs. In other words, I wouldn't want blank specs in the output.

Example:

enter image description here


Is there a way to do this automatically in Excel 2016?

User1973

Posted 2020-01-22T22:40:50.023

Reputation: 165

Do you want to do this with vba, formula, power query,...? How is the data filled, is it static or formulas? – Scott Craner – 2020-01-22T22:44:09.657

1@ScottCraner My priority is for the solution to be simple enough that non-technical people can process their own data with ease. I'm open to any method that can achieve that. The data is static. – User1973 – 2020-01-22T22:47:41.637

Answers

3

You can use Power Query. Then your users can update things by selecting the Refresh option on the Data tab.

In PQ, all you need to do is

  • Select the Hierarchy Path column
  • **UN**pivot other columns
  • Delete the resultant Attribute column

All of the steps can be done from the UI, but here is the

M-Code

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"    Hierarchy Path", type text}, {"Spec 1", type text}, {"Spec 2", type text}, {"Spec 3", type text}, {"Spec 4", type text}, {"Spec 5", type text}, {"Spec 6", type text}, {"Spec 7", type text}, {"Spec 8", type text}, {"Spec 9", type text}, {"Spec 10", type text}}),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"    Hierarchy Path"}, "Attribute", "Value"),
    #"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"})
in
    #"Removed Columns"

enter image description here

Ron Rosenfeld

Posted 2020-01-22T22:40:50.023

Reputation: 3 333

Here are the instructions I've been using regarding refreshing the Power Query table/query: https://i.stack.imgur.com/sbvU5.png.

– User1973 – 2020-01-25T03:09:35.853

1@User1973 You can also select Refresh from any worksheet in the workbook. You could even trigger it on an Event -- for example, Worksheet_Activate, in which case it would run whenever someone selected the worksheet with the query output. – Ron Rosenfeld – 2020-01-25T12:48:44.157

3

enter image description here


VBA Macro:

Sub TransposeRows()
    Dim wb As Workbook
    Dim Row As Integer, LastRowInput As Integer, LastColumnInput As Integer, LastRowOutput As Integer
    Dim Path As String, Spec As String

    Set wb = ThisWorkbook
    Set InputData = wb.Sheets("Input")
    Set OutputData = wb.Sheets("Output")

    LastRowInput = InputData.UsedRange.Rows.Count
    LastColumnInput = InputData.UsedRange.Columns.Count

    OutputData.Range("A:Z").Clear
    OutputData.Range("A1").Value = "Hierarchy Path"
    OutputData.Range("B1").Value = "Spec"

    For Row = 2 To LastRowInput
        Path = InputData.Cells(Row, 1).Value
        For Col = 2 To LastColumnInput
            Spec = InputData.Cells(Row, Col).Value
            If Spec <> "" Then
                LastRowOutput = OutputData.UsedRange.Rows.Count + 1
                OutputData.Cells(LastRowOutput, 1).Value = Path
                OutputData.Cells(LastRowOutput, 2).Value = Spec
            End If
        Next
    Next

    OutputData.Select
End Sub

Result:

enter image description here


Notes:

The script accommodates blank specs.

It also can handle it if the user adds/removes rows or columns.

User1973

Posted 2020-01-22T22:40:50.023

Reputation: 165