简体   繁体   中英

Excel script or formula to transform from wide to long format, with a caveat

For the purposes of simplicity, I'll say I have this table (the original table extends much wider, with let's say, up to 30 items, prices and amounts):

 Date| Requester|  Item1|  Amount1|  Price1|  Item2|  Amount2|  Price2|
12-10|         A|   Shoe|      200|      30|  Shirt|       40|      10|
12-10|         B|  Socks|       20|      10|       |         |        |
13-10|         A|       |         |        | Gloves|        5|       3|

And I need exactly this output:

 Date| Requester|   Item|   Amount|   Price|  
12-10|         A|   Shoe|      200|      30|  
12-10|         A|  Shirt|       40|      10| 
12-10|         B|  Socks|       20|      10|
13-10|         A| Gloves|        5|       3|

I've already come across some unpivot formulas that display the 3 variables in a single column called "variable", but that's not suitable for me, I'd like to reduce the number of columns, yes, but also keep the 3 key variables split in 3 columns. Also, since the original table has records by the thousands, I'd like the output not to create unnecesary rows for empty columns, or else it might crash or become unmanageable. All scripts I've found create unnecesary rows for empty data. Note that In the example I posted, the output table doesn't print an unnecesary row if the item,amount and price data are empty.

Thanks.

You can do this with Power Query , available in Excel 2010+

Step through the "applied steps' window of the PQ Editor to better understand what is going on

  • Replace any blanks with null (So they will be excluded at the next step)
  • UNPIVOT the columns except for Date and Requestor
  • We now will want to group in bunches of three: Item, Amount, Price
    • Add an Index column
    • Add an Integer/Divide column based on the Index column which will result in a series like {0,0,0,1,1,1,2,2,2...}
  • GroupBy the Integer/Divide column
  • Extract the required data from Group table
  • Rename the new columns and delete the unneeded columns.

M-Code

let
    Source = Excel.CurrentWorkbook(){[Name="Table5"]}[Content],
    //Replace blanks with null
    #"Replaced Value" = Table.ReplaceValue(Source,"",null,Replacer.ReplaceValue,Table.ColumnNames(Source)),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Replaced Value", {"Date", "Requester"}, "Attribute", "Value"),
    #"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"}),
    #"Added Index" = Table.AddIndexColumn(#"Removed Columns", "Index", 0, 1, Int64.Type),
    #"Inserted Integer-Division" = Table.AddColumn(#"Added Index", "Integer-Division", each Number.IntegerDivide([Index], 3), Int64.Type),
    #"Removed Columns1" = Table.RemoveColumns(#"Inserted Integer-Division",{"Index"}),
    #"Grouped Rows" = Table.Group(#"Removed Columns1", {"Integer-Division"}, {{"Group", each _, type table [Date=nullable date, Requester=nullable text, Value=any, #"Integer-Division"=number]}}),
    #"Removed Columns2" = Table.RemoveColumns(#"Grouped Rows",{"Integer-Division"}),
    #"Added Custom" = Table.AddColumn(#"Removed Columns2", "Date", each Table.Column([Group],"Date"){0}),
    #"Added Custom1" = Table.AddColumn(#"Added Custom", "Requester", each Table.Column([Group],"Requester"){0}),
    #"Added Custom2" = Table.AddColumn(#"Added Custom1", "Custom", each Table.Column([Group],"Value")),
    #"Extracted Values" = Table.TransformColumns(#"Added Custom2", {"Custom", each Text.Combine(List.Transform(_, Text.From), ";"), type text}),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Extracted Values", "Custom", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Custom.1", "Custom.2", "Custom.3"}),
    #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Date", type date}, {"Custom.1", type text}, {"Custom.2", Int64.Type}, {"Custom.3", Currency.Type}}),
    #"Renamed Columns" = Table.RenameColumns(#"Changed Type1",{{"Custom.1", "Item"}, {"Custom.2", "Amount"}, {"Custom.3", "Price"}}),
    #"Removed Columns3" = Table.RemoveColumns(#"Renamed Columns",{"Group"})
in
    #"Removed Columns3"

You should be able to add more "triplets" of data to any of the rows; or more rows; without having to change the code.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM