Powerquery - Converting single column information having column names and values to table - transform

I have a data in a single column as under
CName1
CName2
CName3
.
.
.
row1 col1 value1
row1 col2 value2
row1 col2 value3
.
.
.
row2 col1 value4
row2 col2 value5
row2 col3 value6
.
.
.
row3 col1 value7
row3 col2 value8
row3 col3 value9
.
.
.
.
What I would like to have is
CName1
CName2
CName3
.....
.....
.....
Value1
value2
value3
.....
.....
.....
Value4
value5
value6
.....
.....
.....
Value7
value8
value9
.....
.....
.....
.....
.....
.....
.....
.....
How can this be achieved ?
Thanks for help.

Here's one method:
Assumptions
The positional entries in each data row are not really there
if they are, we would modify the algorithm
All column headers are in the first group
each group is separated by at least one empty row
each group's columns start with the first (but they don't all have to have the same number of columns)
Please read the code comments, and explore the Applied Steps window, to understand the algorithm
M Code
edited to remove hard-coded column names from last line
let
Source = Excel.CurrentWorkbook(){[Name="Table12"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}}),
//add shifted column
shifted = Table.FromColumns(
Table.ToColumns(#"Changed Type") &
{{null} & List.RemoveLastN(#"Changed Type"[Column1])},
type table[Column1=text, shiftedCol1 =text]),
//create a column which adds an index number at the first row of each group
//then fill down to create a column on which to group
#"Added Index" = Table.AddIndexColumn(shifted, "Index", 0, 1, Int64.Type),
#"Added Custom" = Table.AddColumn(#"Added Index", "grouper", each if [Column1] <> null and [shiftedCol1] = null then [Index] else null),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Index"}),
#"Filled Down" = Table.FillDown(#"Removed Columns",{"grouper"}),
#"Removed Columns1" = Table.RemoveColumns(#"Filled Down",{"shiftedCol1"}),
//remove the empty rows
#"Filtered Rows" = Table.SelectRows(#"Removed Columns1", each ([Column1] <> null)),
//group by the "grouper" column
//then transpose each sub table
#"Grouped Rows" = Table.Group(#"Filtered Rows", {"grouper"}, {
{"transpose", each Table.Transpose(Table.SelectColumns(_,"Column1"))}
}),
#"Removed Columns2" = Table.RemoveColumns(#"Grouped Rows",{"grouper"}),
//combine the grouped subtables, and promote the headers
comb = Table.Combine(#"Removed Columns2"[transpose]),
#"Promoted Headers" = Table.PromoteHeaders(comb, [PromoteAllScalars=true]),
#"Changed Type1" = Table.TransformColumnTypes(#"Promoted Headers",
List.Transform(Table.ColumnNames(#"Promoted Headers"), each {_, type text}))
in
#"Changed Type1"
Edit
If, as implied in your comments, there really are NO blank rows between the data sets, but you know the number of columns in the final result,
hard code the number of columns (or set it as a parameter)
change how to construct the "grouper" column by doing an IntegerDivide on the Index column, instead of the formula I used in the above.
M Code
let
Source = Excel.CurrentWorkbook(){[Name="dataTable"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Data", type text}}),
//hard coded number of columns
numCols = 3,
//add grouper
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),
#"Inserted Integer-Division" = Table.AddColumn(#"Added Index", "grouper", each Number.IntegerDivide([Index], numCols), Int64.Type),
#"Removed Columns" = Table.RemoveColumns(#"Inserted Integer-Division",{"Index"}),
//group by the "grouper" column
//then transpose each sub table
#"Grouped Rows" = Table.Group(#"Removed Columns", {"grouper"}, {
{"transpose", each Table.Transpose(Table.SelectColumns(_,"Data"))}
}),
#"Removed Columns2" = Table.RemoveColumns(#"Grouped Rows",{"grouper"}),
//combine the grouped subtables, and promote the headers
comb = Table.Combine(#"Removed Columns2"[transpose]),
#"Promoted Headers" = Table.PromoteHeaders(comb, [PromoteAllScalars=true]),
#"Changed Type1" = Table.TransformColumnTypes(#"Promoted Headers",
List.Transform(Table.ColumnNames(#"Promoted Headers"), each {_, type text}))
in
#"Changed Type1"

Related

Unpivot Several Columns to Result in Two

I receive data that looks like this:
Name
01/01/2023
01/02/2023
Revenue
Revenue
Chris
1
3
£100
£300
Colin
5
8
£500
£800
Pete
2
5
£200
£500
Where name is self-explanatory, the next two columns are dates (in UK format) with the number of days worked in the period shown below, and the final two columns are revenue.
I want to modify this data in Power Query so it looks like this:
Name
Date
Work Days
Revenue
Chris
01/01/2023
1
£100
Chris
01/02/2023
3
£300
Colin
01/01/2023
5
£500
Colin
01/02/2023
8
£800
Pete
01/01/2023
2
£200
Pete
01/02/2023
5
£500
I thought this would be some kind of a pivot operation but I can't figure it out.
Any assistance will be gratefully received.
Thanks,
Chris
One simple way
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Set0=List.FirstN(Table.ColumnNames(Source),1),
Set1= List.Combine({Set0,List.Alternate(Table.ColumnNames(Source),1,1)}),
Set2=List.Combine({Set0,List.Alternate(List.RemoveFirstN(Table.ColumnNames(Source),1),1,1)}),
Part1 = Table.SelectColumns(Source,Set1),
Part2 = Table.SelectColumns(Source,Set2),
Date1 = Table.AddColumn(Part1,"Date" , each Table.ColumnNames(Part1){1}),
Date2 = Table.AddColumn(Part2,"Date" , each Table.ColumnNames(Part2){1}),
Rename1 = Table.RenameColumns(Date1,{{Table.ColumnNames(Part1){2}, "Revenue"}, {Table.ColumnNames(Part1){1}, "Work Days"}}),
Rename2 = Table.RenameColumns(Date2,{{Table.ColumnNames(Part2){2}, "Revenue"}, {Table.ColumnNames(Part2){1}, "Work Days"}}),
combined = Rename1 & Rename2
in combined
or
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Added Index", {"Index", "Name"}, "Attribute", "Value"),
#"Added Custom" = Table.AddColumn(#"Unpivoted Other Columns", "Date", each if Text.Start([Attribute],3)="Rev" then null else [Attribute]),
#"Added Custom2" = Table.AddColumn(#"Added Custom", "count", each if Text.Start([Attribute],3)="Rev" then null else [Value]),
#"Added Index1" = Table.AddIndexColumn(#"Added Custom2", "Index.1", 0, 1, Int64.Type),
#"Inserted Modulo" = Table.AddColumn(#"Added Index1", "Modulo", each Number.Mod([Index.1], 2), type number),
#"Sorted Rows" = Table.Sort(#"Inserted Modulo",{{"Index", Order.Ascending}, {"Modulo", Order.Ascending}, {"Attribute", Order.Ascending}}),
#"Filled Down" = Table.FillDown(#"Sorted Rows",{"Date", "count"}),
x=Table.AlternateRows(#"Filled Down",0,1,1),
#"Removed Other Columns" = Table.SelectColumns(x,{"Name", "Value", "Date", "count"})
in #"Removed Other Columns"
Here's another way:
Using List.Generate, create a List of Tables using each Date/Revenue Pair.
For each of the tables, ensure the Revenue Column is named Revenue (and not Revenue2, Revenu3, etc) and then Unpivot the table.
Then expand the column that has the list of tables
The rest is "housekeeping"
Code Edited to provide for varying numbers of "First Columns" to be retained before the sets of Date and Revenue columns
*Change #"Retained Column Count" to reflect that number of Columns
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
colNames = List.Buffer(Table.ColumnNames(Source)),
//How many columns at the beginning are non data pairs
#"Retained Column Count" = 4,
#"First Columns" = List.FirstN(colNames,#"Retained Column Count"),
#"Date Columns" = List.Range(colNames,#"Retained Column Count",(List.Count(colNames)-#"Retained Column Count")/2),
#"Revenue Columns" = List.LastN(colNames,List.Count(#"Date Columns")),
//set data types
types = List.Transform(#"First Columns", each {_, type text}) &
List.Transform(#"Date Columns", each {_, Int64.Type}) &
List.Transform(#"Revenue Columns", each {_, Currency.Type}),
#"Changed Type" = Table.TransformColumnTypes(Source, types, "en-GB"),
//create a list of tables consisting of each date/revenue pair
// then unpivot each table
// ensure Revenue column has the same name throughout
#"Data Pairs" = List.Generate(
()=>[t=Table.SelectColumns(#"Changed Type",#"First Columns" & {#"Date Columns"{0}} & {#"Revenue Columns"{0}}), idx=0],
each [idx] < List.Count(#"Date Columns"),
each [t=Table.SelectColumns(#"Changed Type",#"First Columns" & {#"Date Columns"{[idx]+1}} & {#"Revenue Columns"{[idx]+1}}), idx=[idx]+1],
each Table.Unpivot(
Table.RenameColumns([t], {Table.ColumnNames([t]){#"Retained Column Count"+1},"Revenue"}),
{#"Date Columns"{[idx]}},"Date","Work Days")),
//to a table
// then combine the tables with column names in desired order
#"Converted to Table" = Table.FromList(#"Data Pairs", Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandTableColumn(#"Converted to Table", "Column1", #"First Columns" & {"Date","Work Days","Revenue"}),
#"Changed Type with Locale" = Table.TransformColumnTypes(#"Expanded Column1",
List.Transform(#"First Columns", each {_, type text}) &
{{"Date", type date},
{"Work Days", Int64.Type},
{"Revenue", Currency.Type}}, "en-GB"),
#"Sorted Rows" = Table.Sort(#"Changed Type with Locale",{{"Name", Order.Ascending}, {"Date", Order.Ascending}})
in
#"Sorted Rows"

Split text column in PowerBI

Hi all, I have a column of text like the one in the picture, how can I split this type of column in multiple column for each occurrence of " |-Starting " substring?
create a "grouper" column to group the different sets of rows
then Group
Split each subgroup into columns
Transpose the results
eg
let
Source = Excel.CurrentWorkbook(){[Name="Table16"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}}),
//create a "grouper" column
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),
#"Added Custom" = Table.AddColumn(#"Added Index", "grouper", each if [Column1] = "|-Starting" then [Index] else null),
#"Filled Down" = Table.FillDown(#"Added Custom",{"grouper"}),
//group the rows creating a delimiter separated string
// and a counter to obtain the number of columns for the "Split"
#"Grouped Rows" = Table.Group(#"Filled Down", {"grouper"}, {
{"group", each Text.Combine([Column1],";"),type text},
{"numInGroup", each Table.RowCount(_)}
}),
//maximum number of columns in the result
numCols=List.Max(#"Grouped Rows"[numInGroup]),
#"Removed Columns" = Table.RemoveColumns(#"Grouped Rows",{"grouper","numInGroup"}),
//split; then transpose
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns", "group",
Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv),numCols),
#"Transposed Table" = Table.Transpose(#"Split Column by Delimiter")
in
#"Transposed Table"

POWERBI, DAX : concatenate strings, split, and keep substrings only once

I try to do the following:
I have a column with strings, each can have several substrings separated by a delimiter ":"
I need to Concatenate the column strings (I do a Filter here to keep only interresting lines)
Then split according to the delimiter ":"
keep the substrings only once, if they are repeated.
Example:
ColumnHeader
AA:BB:CC
BB:DD
DD:AA:EE
EE:AA:DD:BB
BB:EE
...
Expected result would be a unique string:
"AA:BB:CC:DD:EE"
How would you do this in DAX to fill a new column ?
I expected to find for/while loops in DAX like in Python ... but failed.
I Tried this:
List =
VAR SIn = ""
VAR SOut = ""
VAR Cursor = 0
VAR SList =
CONCATENATEX(
FILTER(ATable, ATable[Name] = CTable[Name]),
[ColumnHeader],
":")
VAR pos1 = FIND(":", SList, Cursor, len(SList))
VAR pos2 = FIND(":", SList, pos1, len(SList))
VAR elem = TRIM(MID(SList, pos1+1, pos2-pos1))
// following is not good but is what I would like to do:
VAR SOut = CONCATENATE(SOut, elem)
VAR SList = MID(SList, pos2, len(SList)-pos2)
VAR Cursor = pos2
// I need to loop ... but how ? ... as no for/while loops are possibles ?
Thanks for your help.
=====================================
I manage to tackle this thanks to the answers below.
I will still give a bigger data set for a better understanding of the global problem:
I have 2 tables:
TABLE_BY_ELEMENT
KEY GROUP LIST KEY_DATA
1 G1 AA:BB:FF 11
2 G1 CC:AA 22
3 G1 FF:DD:AA 33
4 G1 CC:DD:AA 44
5 G2 CC:FF:GG 55
6 G2 BB:AA 66
TABLE_BY_GROUP
GROUP GROUP_DATA
G1 1111
G2 2222
And I want to view the data like this:
RESULT_BY_GROUP
GROUP GROUP_DATA NewList
G1 111 AA:BB:FF:CC:DD
G2 222 CC:FF:GG:BB:AA
and also:
RESULT_ELEMENT
KEY LIST KEY_DATA
1 AA:BB:FF 11
2 CC:AA 22
3 FF:DD:AA 33
4 CC:DD:AA 44
5 CC:FF:GG 55
6 BB:AA 66
I hope is is easier to understand with this.
This isn't something DAX is suited for well. If you need to use DAX to make it into a dynamic measure, then you'll probably need to reshape your data to be more usable. For example,
ID ColumnHeader
1 AA
1 BB
1 CC
2 BB
2 DD
3 DD
3 AA
3 EE
...
You can do this split in the query editor using the Split Column > By Delimiter tool and choosing to split on the colon and expand into rows.
Once it's in this more usable format, you can work with it in DAX like this:
List = CONCATENATEX( VALUES('Table'[ColumnHeader]), 'Table'[ColumnHeader], ":" )
Borrowing logic from here, it's possible to do this purely in DAX, but I don't recommend this route.
List =
VAR LongString =
CONCATENATEX ( VALUES ( 'Table1'[ColumnHeader] ), Table1[ColumnHeader], ":" )
VAR StringToPath =
SUBSTITUTE ( LongString, ":", "|" )
VAR PathToTable =
ADDCOLUMNS (
GENERATESERIES ( 1, LEN ( StringToPath ) ),
"Item", PATHITEM ( StringToPath, [Value] )
)
VAR GroupItems =
FILTER (
SUMMARIZE ( PathToTable, [Item] ),
NOT ISBLANK ( [Item] )
)
RETURN
CONCATENATEX ( GroupItems, [Item], ":" )
Let your table looks like below-
Now try this below Advance Editor code in the Power Query Editor-
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcnS0cnKycnZWitWJVgKyXFzALBcXK6CMqyuY4+oK4gCFnJxgykAysQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ColumnHeader = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ColumnHeader", type text}}),
//--NEW STEPS STARTS FROM HERE
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1, Int64.Type),
#"Reordered Columns" = Table.ReorderColumns(#"Added Index",{"Index", "ColumnHeader"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Reordered Columns", "ColumnHeader", Splitter.SplitTextByDelimiter(":", QuoteStyle.Csv), {"ColumnHeader.1", "ColumnHeader.2", "ColumnHeader.3", "ColumnHeader.4"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"ColumnHeader.1", type text}, {"ColumnHeader.2", type text}, {"ColumnHeader.3", type text}, {"ColumnHeader.4", type text}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type1", {"Index"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute", "Index"}),
#"Removed Duplicates" = Table.Distinct(#"Removed Columns"),
#"Sorted Rows" = Table.Sort(#"Removed Duplicates",{{"Value", Order.Ascending}}),
#"Added Index1" = Table.AddIndexColumn(#"Sorted Rows", "Index", 1, 1, Int64.Type),
#"Reordered Columns1" = Table.ReorderColumns(#"Added Index1",{"Index", "Value"}),
#"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Reordered Columns1", {{"Index", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Reordered Columns1", {{"Index", type text}}, "en-US")[Index]), "Index", "Value", List.Max),
#"Merged Columns" = Table.CombineColumns(#"Pivoted Column",{"1", "2", "3", "4", "5"},Combiner.CombineTextByDelimiter(":", QuoteStyle.None),"Merged")
in
#"Merged Columns"
Here is the final output-
Here is code from Power Query Editor considering GROUP BY-
Create a new table RESULT_BY_GROUP with this below code-
let
Source = TABLE_BY_ELEMENT,
#"Removed Columns" = Table.RemoveColumns(Source,{"KEY", "KEY_DATA"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns", "LIST", Splitter.SplitTextByDelimiter(":", QuoteStyle.Csv), {"LIST.1", "LIST.2", "LIST.3"}),
#"Changed Type" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"LIST.1", type text}, {"LIST.2", type text}, {"LIST.3", type text}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"GROUP"}, "Attribute", "Value"),
#"Removed Columns1" = Table.RemoveColumns(#"Unpivoted Other Columns",{"Attribute"}),
#"Removed Duplicates" = Table.Distinct(#"Removed Columns1"),
#"Sorted Rows" = Table.Sort(#"Removed Duplicates",{{"GROUP", Order.Ascending}, {"Value", Order.Ascending}}),
#"Grouped Rows" = Table.Group(#"Sorted Rows", {"GROUP"}, {{"all", each _, type table [GROUP=nullable text, Value=text]}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "NewList", each [all][Value]),
#"Extracted Values" = Table.TransformColumns(#"Added Custom", {"NewList", each Text.Combine(List.Transform(List.Sort(_), Text.From), ":"), type text}),
#"Removed Columns2" = Table.RemoveColumns(#"Extracted Values",{"all"}),
#"Merged Queries" = Table.NestedJoin(#"Removed Columns2", {"GROUP"}, TABLE_BY_GROUP, {"GROUP"}, "TABLE_BY_GROUP", JoinKind.LeftOuter),
#"Expanded TABLE_BY_GROUP" = Table.ExpandTableColumn(#"Merged Queries", "TABLE_BY_GROUP", {"GROUP_DATA "}, {"TABLE_BY_GROUP.GROUP_DATA "}),
#"Renamed Columns" = Table.RenameColumns(#"Expanded TABLE_BY_GROUP",{{"TABLE_BY_GROUP.GROUP_DATA ", "GROUP_DATA"}}),
#"Changed Type1" = Table.TransformColumnTypes(#"Renamed Columns",{{"GROUP", type text}, {"NewList", type text}, {"GROUP_DATA", Int64.Type}})
in
#"Changed Type1"
Here is the final output-
You can easily visualize your second requirement for table RESULT_ELEMENT using your base table TABLE_BY_ELEMENT

How do I filter for the concentrate of all set filters in PowerBI?

I have data in this form:
In PowerBI, I added another column where I keep only code combinations that consist of one single code. I did this with something like IF(LEN(Code > 1), "", Code). Result:
This enables me to create a slicer that contains only single codes. I also added a table that shows Codes.
Now, when I select codes in the slicer, I want the table to show these codes, plus the exact combination of it.
For example, when I select A and B, the table should show me A and B and A, B. I don't want it to show A, B, C although it contains A and B.
If I filter for A and B and C, however, I want it to show A and B and C and A, B, C - but not A, B.
How can I achieve that?
All entries in Codes are saved as strings.
You need a disconnected (not connected to the base table) table for your slicer. Now, if I consider your base table name is - your_table_name, you can create the new slicer table with this below code-
slicer =
SELECTCOLUMNS(
FILTER(
your_table_name_8,
LEN(your_table_name_8[codes]) = 1
),
"code",your_table_name_8[codes]
)
After creating the new slicer table, check in the model is there any auto relation detected between 2 tables or not. If you find any relation, just Remove the relation.
Now, create your slicer from the newly created table and create this below measure in your base table your_table_name-
show_or_hide =
VAR current_code = MIN(your_table_name_8[codes])
VAR comma_separated_list =
CALCULATE (
CONCATENATEX (
VALUES(slicer[code]),
slicer[code],
","
)
)
RETURN
IF(
current_code = comma_separated_list || (LEN(current_code) = 1 && CONTAINSSTRING(comma_separated_list,current_code)),
1,
0
)
lets see the outcome-
Finally, you can apply a visual level filter using the new measure show_or_hide and apply a filter so that value with True only shown in the visual.
Reorder Combination
Let we have this following table-
Now this following code from Advanced Query Editor will give the the expected output-
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WctRx0nFWitUBsZx1nJRiYwE=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}}),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1, Int64.Type),
#"Reordered Columns" = Table.ReorderColumns(#"Added Index",{"Index", "Column1"}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Reordered Columns", "Column1", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"Column1.1", "Column1.2", "Column1.3"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Column1.1", type text}, {"Column1.2", type text}, {"Column1.3", type text}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type1", {"Index"}, "Attribute", "Value"),
#"Added Custom" = Table.AddColumn(#"Unpivoted Other Columns", "column_name", each "Column-" & [Value]),
#"Changed Type2" = Table.TransformColumnTypes(#"Added Custom",{{"column_name", type text}}),
#"Removed Columns" = Table.RemoveColumns(#"Changed Type2",{"Attribute"}),
#"Reordered Columns1" = Table.ReorderColumns(#"Removed Columns",{"Index", "column_name", "Value"}),
#"Sorted Rows" = Table.Sort(#"Reordered Columns1",{{"Index", Order.Ascending}, {"column_name", Order.Ascending}}),
#"Pivoted Column" = Table.Pivot(#"Sorted Rows", List.Distinct(#"Sorted Rows"[column_name]), "column_name", "Value", List.Min),
#"Merged Columns" = Table.CombineColumns(#"Pivoted Column",{"Column-A", "Column-B", "Column-C"},Combiner.CombineTextByDelimiter(",", QuoteStyle.None),"Merged")
in
#"Merged Columns"
Please check what applied in steps one by one for better understanding. Here is the output with ascending order in the combination-
Index column added for keep tracking the row from start to end. If you have already a similar column, you can use that column as well.

Splitting multiple multi-valued cells in excel into rows

I'm looking to split rows of multiple multi-valued cells into separate rows so that each of the row has one value from each of the multi-valued cells.
For instance if I have the following rows:
> Column1 Column2 Column3
> 1 A:B:C A1:B1:C1
> 2 D:E:F D1:E1:F1
I would want the result as following:
Column1 Column2 Column3
1 A A1
1 B B1
1 C C1
2 D D1
2 E E1
2 F F1
Is there a way in Power Query or VBA to split the data in the specificed format
Assuming you are starting off with source data in range Table1 that has three columns, and no column headers, this code will work in powerquery (paste into Home ... Advanced Editor...)
It creates two custom columns using the split function to split on : into a list
Then combines the two lists into a table, before we expand it
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source, "Custom", each Text.Split([Column2],":")),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom.1", each Text.Split([Column3],":")),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Custom.2", each Table.FromColumns({[Custom],[Custom.1]})),
#"Expanded Custom.2" = Table.ExpandTableColumn(#"Added Custom2", "Custom.2", {"Column1", "Column2"}, {"Column1.1", "Column2.1"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Custom.2",{"Column2", "Column3", "Custom", "Custom.1"})
in #"Removed Columns"
alternately, below works on any number of columns, all at once
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes (Source,List.Transform(Table.ColumnNames(Source), each {_, type text})),
TableTransform = Table.Combine(List.Transform(List.Transform(Table.ToRecords(#"Changed Type"), (x) => List.Transform(Record.ToList(x), each Text.Split(_,":"))), each Table.FromColumns(_, Table.ColumnNames(#"Changed Type")))),
#"Filled Down" = Table.FillDown(TableTransform,{"Column1"})
in #"Filled Down"

Resources