Forum Discussion
How to transform excel text list to table
- 8 years ago
Hi Murat62,
I'm not sure if I get this straight, but based on what you had said, my understanding is the following:
The category column (named Column) is recursive, and whenever the sequence starts from the beginning (with "A" value), the record number increases with 1.
So, based on it, I don't know if there's any solution in the Power Query for that matter, but I figured out a way in Excel: if you create a new column with the following formula, you'll get the record numbers:
=IFERROR(IF(A1>A2;C1+1;C1);1)
If you load this table into PBI, you can create the pivot table in the Power Query you wanted. (with Column From Examples or even in Excel with the concatenate formula you can get the "record 1", "record 2"... format easily)
Let me know please if it solves your problem and whether it was helpful or not.
Best regards,
Andris
Thanks for your answer. It looks quite too high level for me.
Nevertheless, it gave the opportunity to discover & learn new functions as table.buffer in Power Query.
will need time to digest them...
My best regards
My code with explanatory comments:
let
// The Source is buffered (i.e. cached in memory). In general List.Accumulates performs better on a buffered table.
Source = Table.Buffer(ExcelTextList),
/* The purpose of the Accumulation step is to create a list with record numbers, starting with 1 and increasing with 1 each time the "Column" value is less than or equal to the previous "Column" value.
As this requires both the previous "Column" value and the previous record number, the list is accumulated with the "Column" and record values in 1 item, so a list of lists.
With Column values A,B,C,D,A,B, the list starts with {{A,0}}; after the first iteration it is {{A,0},{A,1}} etcetera.
The first argument supplied to List.Accumulate is the list with "Column" values: Source[Column]. List.Accumulate will iterate - or loop - over this list.
The second argument is the initial value or {{A,0}}.
The third argument is the actual accumulation function:
r refers to the accumulation so far, starting with {{A,0}}. The function transforms the value of r with each iteration.
c refers to the current item in the list of column values, starting with A.
So the first iteration takes r {{A,0}} and concatenates: {{A, 1}}:
List.Last(r) takes the last item of the accumulated list {A,0}, so:
List.Last(r){0} is the A from this pair.
List.Last(r){1} is the 0 from this pair. As the A from this pair is <= c (Value A), the second element of the new pair becomes 0 + 1.
The second iteration takes r {{A,0},{A,1}} and concatenates {B,1}, resulting in {{A,0},{A,1},{B,1}} etcetera.
After the accumulation, the first item {A,0} is removed with List.Skip.
*/
Accumulation = List.Skip(List.Accumulate(Source[Column],{{Source[Column]{0},0}},(r,c) => r & {{c, if List.Last(r){0} >= c then List.Last(r){1} + 1 else List.Last(r){1}}})),
// The list with list is converted to a table with 2 columns (default Column1 and Column2).
Tabled = Table.FromRows(Accumulation),
/* Column2 of this table (the record numbers) must be added as a new column to the original table.
Unfortunately, no function is available to do that.
But we can use Table.FromColumns which will take a list of lists, where each inner list contains column values.
So first the original table must be transformed to a list of lists, using Table.ToColumns.
Tabled[Column2] is concatenated to this list of list and this ensemble is converted to a table with Table.FromColumns.
The (optional) second argument of table columns, defines the columns of the result. Value.Type(Source) would give the column names and types of the Source table.
As the new table has an additional column (the record numbers), in this formula a dummy column is added to Source with column name "Record" and type Int64.Type.
So the Value.Type is taken from: Source with the added "Record" column.
*/
Combined = Table.FromColumns(Table.ToColumns(Source)&{Tabled[Column2]}, Value.Type(Table.AddColumn(Source, "Record", each null, Int64.Type))),
// The rest is straightforward.
#"Pivoted Column" = Table.Pivot(Combined, List.Distinct(Combined[Column]), "Column", "Text "),
#"Added Prefix" = Table.TransformColumns(#"Pivoted Column", {{"Record", each "Record " & Text.From(_, "en-US"), type text}})
in
#"Added Prefix"