Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.
Hi, I have not found the exact answer for this yet, so would be happy with some help. I have data is spread over eight columns, but I would like to have it in one long list. I cannot figure out how to do it in PowerQuery so I'd gladly appreciate some help. My data looks like this now:
Value | Date | Value_1 | Date_1 | Value_2 | Date_2 | Value_3 | Date_3 |
1000 | 01-01-2020 | 1004 | 01-01-2020 | 1008 | 01-02-2020 | 1012 | 01-03-2020 |
1001 | 01-01-2020 | 1005 | 01-02-2020 | 1009 | 01-02-2020 | 1013 | 01-03-2020 |
1002 | 01-01-2020 | 1006 | 01-02-2020 | 1010 | 01-02-2020 | 1014 | 01-03-2020 |
1003 | 01-01-2020 | 1007 | 01-02-2020 | 1011 | 01-02-2020 | 1015 | 01-03-2020 |
And I would need it to look like this:
Value | Date |
1001 | 01-01-2020 |
1002 | 01-01-2020 |
1003 | 01-01-2020 |
1004 | 01-01-2020 |
1005 | 01-02-2020 |
1006 | 01-02-2020 |
1007 | 01-02-2020 |
1008....... | 01-02-2020...... |
Thanks in advance 🙂
Solved! Go to Solution.
@Anonymous
Solution I:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bcxbCoAwDETRveS7wiRtfayldP/bsGpB0Av5yYG5rZlLsmTyZVwormdYAdunxWse0/JjPd1Fh3X9r3VAMWMxoLjCWmAFixmKG6wdrH6K/QQ=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Value = _t, Date = _t, Value_1 = _t, Date_1 = _t, Value_2 = _t, Date_2 = _t, Value_3 = _t, Date_3 = _t]),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(Source, {}, "Attribute", "V"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Columns",{"Attribute"}),
#"Added Index" = Table.AddIndexColumn(#"Removed Columns", "Index", 0, 1, Int64.Type),
#"Integer-Divided Column" = Table.TransformColumns(#"Added Index", {{"Index", each Number.IntegerDivide(_, 2), Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Integer-Divided Column", {"Index"}, {{"All", each Text.Combine(_[V],"#(tab)")}}),
#"Removed Columns1" = Table.RemoveColumns(#"Grouped Rows",{"Index"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns1", "All", Splitter.SplitTextByDelimiter("#(tab)", QuoteStyle.Csv), {"Value", "Date"}),
#"Sorted Rows" = Table.Sort(#"Split Column by Delimiter",{{"Value", Order.Ascending}})
in
#"Sorted Rows"
Solution II, which borrowed @Jimmy801 's elegant solution but with a bit amendment,
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bcxbCoAwDETRveS7wiRtfayldP/bsGpB0Av5yYG5rZlLsmTyZVwormdYAdunxWse0/JjPd1Fh3X9r3VAMWMxoLjCWmAFixmKG6wdrH6K/QQ=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Value = _t, Date = _t, Value_1 = _t, Date_1 = _t, Value_2 = _t, Date_2 = _t, Value_3 = _t, Date_3 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Value", Int64.Type}, {"Date", type date}, {"Value_1", Int64.Type}, {"Date_1", type date}, {"Value_2", Int64.Type}, {"Date_2", type date}, {"Value_3", Int64.Type}, {"Date_3", type date}}),
ListSplit = List.Split(Table.ColumnNames(#"Changed Type"), 2),
CreateTableGroups = List.Transform(ListSplit,
each Table.FromColumns(List.Accumulate({0..List.Count(_)-1}, {}, (s,c)=>s&{Table.Column(#"Changed Type", _{c})}), {"Date","Value"})
),
TableCombine = Table.Combine(CreateTableGroups)
in
TableCombine
Thanks to the great efforts by MS engineers to simplify syntax of DAX! Most beginners are SUCCESSFULLY MISLED to think that they could easily master DAX; but it turns out that the intricacy of the most frequently used RANKX() is still way beyond their comprehension! |
DAX is simple, but NOT EASY! |
Hi, @Anonymous , you might follow these steps,
Thanks to the great efforts by MS engineers to simplify syntax of DAX! Most beginners are SUCCESSFULLY MISLED to think that they could easily master DAX; but it turns out that the intricacy of the most frequently used RANKX() is still way beyond their comprehension! |
DAX is simple, but NOT EASY! |
Hello @Anonymous
you have to dig in the M-code to make things work. You can create your query (read from Workbook) and goto the advanved editor and replace your in statement with this code (Add a "," after your your code before pasting. Subsitute the #"Changed Type" with your last stepname.
ListSplit = List.Split(Table.ColumnNames(#"Changed Type"), 2),
CreateTableGroups = List.Transform( ListSplit, (lst)=> Table.FromColumns({Table.Column(#"Changed Type", lst{0}),Table.Column(#"Changed Type", lst{1})}, {"Value", "Date"})),
TableCombine = Table.Combine(CreateTableGroups)
in
TableCombine
this is the most straightforward you can do. You can also use a more professional way to handle it, to create a new function like this @Anonymous mentioned it already. Create a new blank query and copy paste this code there an name the query TransformYourTable
(tbl as table) =>
let
ListSplit = List.Split(Table.ColumnNames(tbl), 2),
CreateTableGroups = List.Transform( ListSplit, (lst)=> Table.FromColumns({Table.Column(tbl, lst{0}),Table.Column(tbl, lst{1})}, {"Value", "Date"})),
TableCombine = Table.Combine(CreateTableGroups)
in
TableCombine
then go to your query from the workbook, click on the table-symbol and select "invoke custom function"
Right click on your last step and select "Insert Step After"
go to the formula bar and put your new custom function
Before
After
Hope this helps
If this post helps or solves your problem, please mark it as solution (to help other users find useful content and to acknowledge the work of users that helped you)
Kudoes are nice too
Have fun
Jimmy
= Table.Combine(List.Transform(List.Split(Table.ToColumns(Source),2),each Table.FromColumns(_,{"Value","Date"})))
@Anonymous
Solution I:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bcxbCoAwDETRveS7wiRtfayldP/bsGpB0Av5yYG5rZlLsmTyZVwormdYAdunxWse0/JjPd1Fh3X9r3VAMWMxoLjCWmAFixmKG6wdrH6K/QQ=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Value = _t, Date = _t, Value_1 = _t, Date_1 = _t, Value_2 = _t, Date_2 = _t, Value_3 = _t, Date_3 = _t]),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(Source, {}, "Attribute", "V"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Columns",{"Attribute"}),
#"Added Index" = Table.AddIndexColumn(#"Removed Columns", "Index", 0, 1, Int64.Type),
#"Integer-Divided Column" = Table.TransformColumns(#"Added Index", {{"Index", each Number.IntegerDivide(_, 2), Int64.Type}}),
#"Grouped Rows" = Table.Group(#"Integer-Divided Column", {"Index"}, {{"All", each Text.Combine(_[V],"#(tab)")}}),
#"Removed Columns1" = Table.RemoveColumns(#"Grouped Rows",{"Index"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns1", "All", Splitter.SplitTextByDelimiter("#(tab)", QuoteStyle.Csv), {"Value", "Date"}),
#"Sorted Rows" = Table.Sort(#"Split Column by Delimiter",{{"Value", Order.Ascending}})
in
#"Sorted Rows"
Solution II, which borrowed @Jimmy801 's elegant solution but with a bit amendment,
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bcxbCoAwDETRveS7wiRtfayldP/bsGpB0Av5yYG5rZlLsmTyZVwormdYAdunxWse0/JjPd1Fh3X9r3VAMWMxoLjCWmAFixmKG6wdrH6K/QQ=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Value = _t, Date = _t, Value_1 = _t, Date_1 = _t, Value_2 = _t, Date_2 = _t, Value_3 = _t, Date_3 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Value", Int64.Type}, {"Date", type date}, {"Value_1", Int64.Type}, {"Date_1", type date}, {"Value_2", Int64.Type}, {"Date_2", type date}, {"Value_3", Int64.Type}, {"Date_3", type date}}),
ListSplit = List.Split(Table.ColumnNames(#"Changed Type"), 2),
CreateTableGroups = List.Transform(ListSplit,
each Table.FromColumns(List.Accumulate({0..List.Count(_)-1}, {}, (s,c)=>s&{Table.Column(#"Changed Type", _{c})}), {"Date","Value"})
),
TableCombine = Table.Combine(CreateTableGroups)
in
TableCombine
Thanks to the great efforts by MS engineers to simplify syntax of DAX! Most beginners are SUCCESSFULLY MISLED to think that they could easily master DAX; but it turns out that the intricacy of the most frequently used RANKX() is still way beyond their comprehension! |
DAX is simple, but NOT EASY! |
Hi @CNENFRNL , thank you, but maybe I was a bit unclear. What I meant is that, the data I showed in my example is just example data, and my real query where I have the data contains "real data" (and is a big file). So I would need to modify the code that @Jimmy801 and @mahoneypat kindly provided in order to 'plug' my source into the rest of the steps specified below. Since the source I have is an excel web file I'd need to paste my source somewhere in below code to make it work - but I cannot figure out where.
Hi, @Anonymous , you might follow these steps,
Thanks to the great efforts by MS engineers to simplify syntax of DAX! Most beginners are SUCCESSFULLY MISLED to think that they could easily master DAX; but it turns out that the intricacy of the most frequently used RANKX() is still way beyond their comprehension! |
DAX is simple, but NOT EASY! |
Hi all,
I have slightly modified the solution to make it a function. It accepts a table and a list of resulting columns and split the table to the number of columns provided.
Copy this bit into a new blank query (name it fSplitColumns, otherwise change the function name in the calling line):
(mTable as table, listResultColumns as list) =>
let
//listResultColumns = {"Date", "Value"},
ListSplit = List.Split(Table.ColumnNames(mTable), List.Count(listResultColumns)),
CreateTableGroups = List.Transform(ListSplit, each Table.FromColumns(List.Accumulate({0..List.Count(_)-1}, {}, (s,c)=>s&{Table.Column(#"Changed Type", _{c})}), listResultColumns)),
TableCombine = Table.Combine(CreateTableGroups)
in
TableCombine
Call it in your code like this passing your last step in pre-processing instead of #"Changed Type" and your column names in the function call:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bcxbCoAwDETRveS7wiRtfayldP/bsGpB0Av5yYG5rZlLsmTyZVwormdYAdunxWse0/JjPd1Fh3X9r3VAMWMxoLjCWmAFixmKG6wdrH6K/QQ=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Value = _t, Date = _t, Value_1 = _t, Date_1 = _t, Value_2 = _t, Date_2 = _t, Value_3 = _t, Date_3 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Value", Int64.Type}, {"Date", type date}, {"Value_1", Int64.Type}, {"Date_1", type date}, {"Value_2", Int64.Type}, {"Date_2", type date}, {"Value_3", Int64.Type}, {"Date_3", type date}}),
Output = fSplitColumns(#"Changed Type", {"Date", "Value"})
in Output
Kind regards,
JB
Hi @Jimmy801 @mahoneypat thank you for your answers. Can you tell me which parts I would need to replace to make it work with my query (source)? My source is an excel file on Teams, so technically an excel online workbook. Thanks in advance.
Hello @Anonymous
you have to dig in the M-code to make things work. You can create your query (read from Workbook) and goto the advanved editor and replace your in statement with this code (Add a "," after your your code before pasting. Subsitute the #"Changed Type" with your last stepname.
ListSplit = List.Split(Table.ColumnNames(#"Changed Type"), 2),
CreateTableGroups = List.Transform( ListSplit, (lst)=> Table.FromColumns({Table.Column(#"Changed Type", lst{0}),Table.Column(#"Changed Type", lst{1})}, {"Value", "Date"})),
TableCombine = Table.Combine(CreateTableGroups)
in
TableCombine
this is the most straightforward you can do. You can also use a more professional way to handle it, to create a new function like this @Anonymous mentioned it already. Create a new blank query and copy paste this code there an name the query TransformYourTable
(tbl as table) =>
let
ListSplit = List.Split(Table.ColumnNames(tbl), 2),
CreateTableGroups = List.Transform( ListSplit, (lst)=> Table.FromColumns({Table.Column(tbl, lst{0}),Table.Column(tbl, lst{1})}, {"Value", "Date"})),
TableCombine = Table.Combine(CreateTableGroups)
in
TableCombine
then go to your query from the workbook, click on the table-symbol and select "invoke custom function"
Right click on your last step and select "Insert Step After"
go to the formula bar and put your new custom function
Before
After
Hope this helps
If this post helps or solves your problem, please mark it as solution (to help other users find useful content and to acknowledge the work of users that helped you)
Kudoes are nice too
Have fun
Jimmy
Hello @Anonymous
check out this solution. It splits the table into pieces of 2 columns and change the column names to value and date. Afterwards the tables are combined again
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bcxbCoAwDETRveS7wiRtfayldP/bsGpB0Av5yYG5rZlLsmTyZVwormdYAdunxWse0/JjPd1Fh3X9r3VAMWMxoLjCWmAFixmKG6wdrH6K/QQ=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Value = _t, Date = _t, Value_1 = _t, Date_1 = _t, Value_2 = _t, Date_2 = _t, Value_3 = _t, Date_3 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Value", Int64.Type}, {"Date", type date}, {"Value_1", Int64.Type}, {"Date_1", type date}, {"Value_2", Int64.Type}, {"Date_2", type date}, {"Value_3", Int64.Type}, {"Date_3", type date}}),
ListSplit = List.Split(Table.ColumnNames(#"Changed Type"), 2),
CreateTableGroups = List.Transform( ListSplit, (lst)=> Table.FromColumns({Table.Column(#"Changed Type", lst{0}),Table.Column(#"Changed Type", lst{1})}, {"Value", "Date"})),
TableCombine = Table.Combine(CreateTableGroups)
in
TableCombine
Copy paste this code to the advanced editor in a new blank query to see how the solution works.
If this post helps or solves your problem, please mark it as solution (to help other users find useful content and to acknowledge the work of users that helped you)
Kudoes are nice too
Have fun
Jimmy
Here is one way to do it with your example data. To see how it works, just create a blank query, go to Advanced Editor, and replace the text there with the M code below.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bcxbCoAwDETRveS7wiRtfayldP/bsGpB0Av5yYG5rZlLsmTyZVwormdYAdunxWse0/JjPd1Fh3X9r3VAMWMxoLjCWmAFixmKG6wdrH6K/QQ=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Value = _t, Date = _t, Value_1 = _t, Date_1 = _t, Value_2 = _t, Date_2 = _t, Value_3 = _t, Date_3 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Value", Int64.Type}, {"Date", type date}, {"Value_1", Int64.Type}, {"Date_1", type date}, {"Value_2", Int64.Type}, {"Date_2", type date}, {"Value_3", Int64.Type}, {"Date_3", type date}}),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1, Int64.Type),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Added Index", {"Index"}, "Attribute", "Value.1"),
#"Extracted Text Before Delimiter" = Table.TransformColumns(#"Unpivoted Other Columns", {{"Attribute", each Text.BeforeDelimiter(_, "_"), type text}}),
#"Added Index1" = Table.AddIndexColumn(#"Extracted Text Before Delimiter", "Index2", 1, 1, Int64.Type),
#"Inserted Addition" = Table.AddColumn(#"Added Index1", "Addition", each Number.RoundUp([Index2] / 2,0), type number),
#"Removed Columns2" = Table.RemoveColumns(#"Inserted Addition",{"Index", "Index2"}),
#"Pivoted Column" = Table.Pivot(#"Removed Columns2", List.Distinct(#"Removed Columns2"[Attribute]), "Attribute", "Value.1"),
#"Removed Columns" = Table.RemoveColumns(#"Pivoted Column",{"Addition"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Removed Columns",{{"Date", type date}, {"Value", Int64.Type}}),
#"Sorted Rows" = Table.Sort(#"Changed Type1",{{"Value", Order.Ascending}})
in
#"Sorted Rows"
Regards,
Pat
To learn more about Power BI, follow me on Twitter or subscribe on YouTube.
Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City
Check out the April 2024 Power BI update to learn about new features.