Using power query to group alternate rows - powerquery

Starting with the table above, the headers and their respective values are in alternating rows. For example for Nike, the Serial for the boots is 123 and Part No. is ABC, and it is sold on 12 Apr 22 for $23.03 with 20 left in stock. What I am trying to achieve by using power query is the following table:
I have tried adding an index and divide-integer 2 as there are 2 rows (1 header, 1 value) for each item sold and grouping using the resultant index. Then unpivot all except the index.
Then split the Attribute and Value columns using #(lf)
But I'm stuck here and running out of ideas. Any advice will be greatly appreciated. Thanks.

Try
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"AlternateRows"=Table.AlternateRows(Source,0,1,1),
#"Added Index" = Table.AddIndexColumn(AlternateRows, "Index", 0, 1, Int64.Type),
#"Added Custom" = Table.AddColumn( #"Added Index", "Custom", each Text.Split([Column2],"#(lf)")),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom.1", each Text.Split([Column4],"#(lf)")),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Custom.2", each
Table.AddColumn(
Table.UnpivotOtherColumns(
Table.AddIndexColumn(
Table.FromColumns({[Custom],[Custom.1]})
, "Index", 0, 1, Int64.Type)
, {"Index"}, "Attribute", "Value")
,"Key", each Text.From([Index]) & Text.End([Attribute],1))
),
#"Expanded Custom.2" = Table.ExpandTableColumn(#"Added Custom2", "Custom.2", {"Value", "Key"}, {"Value", "Key"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Custom.2",{"Column2", "Column4", "Custom", "Custom.1"}),
#"Pivoted Column" = Table.Pivot(#"Removed Columns", List.Distinct(#"Removed Columns"[Key]), "Key", "Value"),
#"Renamed Columns" = Table.RenameColumns(#"Pivoted Column",{{"01", "Serial"}, {"02", "Date"}, {"11", "PartNo"}, {"12", "Price"}, {"22", "Item"}, {"32", "Stocks Left"}, {"Column1", "Currency"}, {"Column3", "Brand"}}),
#"Removed Columns1" = Table.RemoveColumns(#"Renamed Columns",{"Index"}),
#"Changed Type" = Table.TransformColumnTypes(#"Removed Columns1",{{"Date", type date}, {"Price", type number}, {"Stocks Left", type number}})
in #"Changed Type"

Related

Max Group Filter Power Query

I'm trying to use the following code to get a new added column with information about a max value from a given field.
But what I would want is to have the possiblity to group a table where I filter it by a condition where the Custom column value would be 1.
I need to transform somehow the following parte of the code:
[
filter = [ID] /*should I add here another filter?/,
max2=Table.Group(
Source, {"ID"},
{{"MaxFiltered2", each List.Max([CODE])}}
){[ID=filter]}[MaxFiltered2]
][max2]
)
Here follows the code sequence:
#"Added Custom" = Table.AddColumn(
#"Changed Type",
"maxInt",
each
[
filter = [ID],
max=Table.Group(
Source, {"ID"},
{{"MaxFiltered", each List.Max([TAX])}}
){[ID=filter]}[MaxFiltered]
][max]
),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom", each if [maxInt]=[TAX] then 1 else 0),
#"Filtered Rows" = Table.SelectRows(#"Added Custom1", each ([Custom] = 1)),
#"Added Custom2" = Table.AddColumn(
#"Changed Type",
"maxInt2",
each
[
filter = [ID],
max2=Table.Group(
Source, {"ID"},
{{"MaxFiltered2", each List.Max([CODE])}}
){[ID=filter]}[MaxFiltered2]
][max2]
)
in
#"Added Custom2"
Inputput desired:
ID TAX CODE
A 4 921
A 6 500
A 6 200
B 2 700
B 2 500
B 1,5 100
Output desired:
ID TAX CODE
A 6 500
B 2 700
(to get the max for A and B IDs both on TAX and CODE variables)
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WclTSUTIBYksjQ6VYHQjfDIhNDQxQ+EZQvhOIDcTmaHxTJL6hnimIBInEAgA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, TAX = _t, CODE = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", type text}, {"TAX", type number}, {"CODE", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"ID"}, {{"All", each _, type table [ID=nullable text, TAX=nullable number, CODE=nullable number]}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom",
each Table.First(
Table.Sort([All],{{"TAX", Order.Descending},{"CODE", Order.Descending}})
)
),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"ID", "All"}),
#"Expanded Custom" = Table.ExpandRecordColumn(#"Removed Columns", "Custom", {"ID", "TAX", "CODE"}, {"ID", "TAX", "CODE"})
in
#"Expanded Custom"
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WclTSUTIBYksjQ6VYHQjfDIhNDQxQ+EZQvhOIDcTmaHxTJL6hnimIBInEAgA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, TAX = _t, CODE = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", type text}, {"TAX", type number}, {"CODE", Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"ID"}, {{"TAX", each List.Max([TAX]), type nullable number}, {"CODE", each List.Max([CODE]), type nullable number}})
in
#"Grouped Rows"

Max Per Group Power Query

I'm using this code for creating a custom column!
max per group
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(
Source,
{{"Column1", type text}, {"Column2", Int64.Type}}
),
#"Added Custom" = Table.AddColumn(
#"Changed Type",
"maxInt",
each
[
filter = [Column1],
max=Table.Group(
Source, {"Column1"},
{{"MaxFiltered", each List.Max([Column2])}}
){[Column1=filter]}[MaxFiltered]
][max]
) in
#"Added Custom"
It works fine for getting the maxInt new column with the expected values!
But if I go on and try to reapeat the same code for adding another column to look for another maxInt but for another field, it gives me the output for this last column, and the other dissapears.
Can someone give a feedback on this matter?
Here follows my code:
#"Added Custom" = Table.AddColumn(
#"Changed Type",
"maxInt",
each
[
filter = [ID],
max=Table.Group(
Source, {"ID"},
{{"MaxFiltered", each List.Max([TAX])}}
){[BOOKING ID=filter]}[MaxFiltered]
][max]
),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom", each if [maxInt]=[TAX] then 1 else 0),
#"Filtered Rows" = Table.SelectRows(#"Added Custom1", each ([Custom] = 1)),
#"Added Custom2" = Table.AddColumn(
#"Changed Type",
"maxInt2",
each
[
filter = [ID],
max2=Table.Group(
Source, {"ID"},
{{"MaxFiltered2", each List.Max([CODE])}}
){[BOOKING ID=filter]}[MaxFiltered2]
][max2]
)
in
#"Added Custom2"
The Added Custom Column dissapears and it only gives me the Added Custom2.

Powerquery - rows to columns

I have sample data like below and I am trying to use PowerQuery to transpose it into different shape.
Here is my data:
Identifier Id
Account Type 1
Account Type 2
Account Type 3
Here is what I need:
Identifier Column.1 Column.2 Column.3
Account Type 1 2 3
I tried all combinations of Transpose + Unpivot but nothing worked.
You can Group by Identifier; then do a custom Text Aggregation which you can split into columns:
let
Source = Excel.CurrentWorkbook(){[Name="Table25"]}[Content],
//type the ID column as text for later purposes
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Identifier", type text}, {"Id", type text}}),
//group by Identifier, then custom Text aggregation with delimiter
#"Grouped Rows" = Table.Group(#"Changed Type", {"Identifier"}, {
{"Id",each Text.Combine([Id],";")}}),
//split the column by the delimiter, and set the data types
#"Split Column by Delimiter" = Table.SplitColumn(#"Grouped Rows", "Id", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Id.1", "Id.2", "Id.3"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Id.1", Int64.Type}, {"Id.2", Int64.Type}, {"Id.3", Int64.Type}})
in
#"Changed Type1"
How about this?
Method1: If there will only be one identifier type, then Add column... index column .... Then click select the index column and use transform...pivot column... and select ID as the values column, advanced options Don't Aggregate
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1),
#"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Added Index", {{"Index", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Added Index", {{"Index", type text}}, "en-US")[Index]), "Index", "Id")
in #"Pivoted Column"
Method2: If you plan to have different identifiers, then you need something a bit more complex. This adds the index within each group. Then you can pivot
let Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Grouped Rows" = Table.Group(Source, {"Identifier"}, {{"data", each Table.AddIndexColumn(_, "Index", 1, 1), type table}}),
#"Expanded data" = Table.ExpandTableColumn(#"Grouped Rows", "data", {"Id", "Index"}, {"Id", "Index"}),
#"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Expanded data", {{"Index", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Expanded data", {{"Index", type text}}, "en-US")[Index]), "Index", "Id", List.Sum)
in #"Pivoted Column"

Power query column editing

I have a table in power bi query with dates
01.01.2020
02.01.2020
and so on..
I need to duplicate this table and replace values 01.01.2020 into 20200101 and so on. Is there an obvious, easy way for this?
First option:
Here is the simplest option I found:
Create a custom column and apply "Text.Reverse" to your column
Create a custom column and apply to the newly created "Text.Remove" for "." which will remove the "." of your string.
Here is what you will get, with "reverse date" as your column in the reverse order, and "reverse date without point" as the second column without the point.
Here is the M code:
#"Promoted Headers" = Table.PromoteHeaders(Sheet2_Sheet, [PromoteAllScalars=true]),
#"Changed Type3" = Table.TransformColumnTypes(#"Promoted Headers",{{"Date", type text}}),
#"Added Custom3" = Table.AddColumn(#"Changed Type3", "reverse date", each Text.Reverse([Date])),
#"Added Custom4" = Table.AddColumn(#"Added Custom3", "reverse date witout point", each Text.Remove([reverse date], {"."}))
Second option:
Here is a second option, which is longer:
Break down your column in three distinct columns with "." as delimiter
Add new columns with padding zero to day and months (I called them "month with zero" and "day with zero")
Concatenate
and you get you result!
Here is my starting point:
Here is the first step, "breaking the column" in "columns":
Here is the custom column with zero padding:
Here is how you concatenate:
Here is the M code:
#"Split Column by Delimiter" = Table.SplitColumn(#"Promoted Headers", "Date", Splitter.SplitTextByDelimiter(".", QuoteStyle.Csv), {"Date.1", "Date.2", "Date.3"}),
#"Changed Type" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Date.1", Int64.Type}, {"Date.2", Int64.Type}, {"Date.3", Int64.Type}}),
#"Changed Type1" = Table.TransformColumnTypes(#"Changed Type",{{"Date.1", type text}, {"Date.2", type text}}),
#"Renamed Columns" = Table.RenameColumns(#"Changed Type1",{{"Date.1", "Day"}, {"Date.2", "Month"}, {"Date.3", "Year"}}),
#"Added Custom" = Table.AddColumn(#"Renamed Columns", "Month with zero", each Text.PadStart(Text.From([Month]),2,"0")),
#"Added Custom2" = Table.AddColumn(#"Added Custom", "Day with zero", each Text.PadStart(Text.From([Day]),2,"0")),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom2",{"Day", "Month"}),
#"Changed Type2" = Table.TransformColumnTypes(#"Removed Columns",{{"Year", type text}}),
#"Added Custom1" = Table.AddColumn(#"Changed Type2", "New Date", each [Year] & [Month with zero] & [Day with zero])
in
#"Added Custom1"

Is this possible in a power query?

Can I convert the original data into the format I want through Power Query? I'm not sure if it's possible with PowerQuery or if I need to implement it with VBA, so I really need your advice.
See if this works for you.
Assumes 4 columns in source data {Group A, Group B, Date, Value}
Basic Method [1] Group data by Date and GroupA, and add index [2] Create separate table that inverts Value, and add index [3] Join the two tables and remove original Value column [4] Remove extra columns [5] Expand [6] Pivot
Below code can be pasted into Powerquery in Home ... Advanced Editor ...
let Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Group A", type text}, {"Group B", type text}, {"Date", type date}, {"Value", Int64.Type}}),
#"Sorted Rows" = Table.Sort(#"Changed Type",{{"Group A", Order.Ascending}, {"Date", Order.Ascending}, {"Group B", Order.Ascending}}),
// Group by Date and Group A, and add Index Column
#"Grouped Rows" = Table.Group( #"Sorted Rows" , {"Group A","Date"}, {{"Data", each Table.AddIndexColumn(_, "Index", 1, 1), type table}}),
//Create new table with inverted Values for each Group A Date, with index
#"Added Custom2" = Table.AddColumn(#"Grouped Rows", "Custom.2", each Table.AddIndexColumn(Table.FromList(List.Reverse(Table.Column([Data],"Value")) , Splitter.SplitByNothing(), null, null, ExtraValues.Error), "Index", 1, 1)),
//Join the two tables
#"Added Custom3" = Table.AddColumn(#"Added Custom2", "Custom.3", each Table.RemoveColumns(Table.Join([Data] , "Index", [Custom.2] , "Index", JoinSide.Left),{"Index","Value"})),
//Remove Excess Columns
#"Removed Columns1" = Table.RemoveColumns(#"Added Custom3",{"Group A", "Date", "Data", "Custom.2"}),
// Expand and pivot
#"Expanded Custom.3" = Table.ExpandTableColumn(#"Removed Columns1", "Custom.3", {"Group A", "Group B", "Date", "Column1"}, {"Group A", "Group B", "Date", "Column1"}),
#"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Expanded Custom.3", {{"Date", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Expanded Custom.3", {{"Date", type text}}, "en-US")[Date]), "Date", "Column1", List.Sum)
in #"Pivoted Column"

Resources