Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

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.

Reply
ChrisMendoza
Resident Rockstar
Resident Rockstar

Transpose/Transform Multiple Rows into Single Row

Hello, 

 

First thank you all for the work you do. This is my first time posting to the community however, I've been using your posts as guides for awhile. Most recently how to merge multiple rows into one row with different column based on row values.

 

Project Background

Every year I help another department produce an Email Merge using a .xlsx file. This year, I got tired of 

CTRL C ->  Up Arrow (x times) -> Right Arrow (y times) -> CTRL V -> CTRL -> T

 so I decided to search for a Power Query solution, again thanks to your community.

 

You may ask, "Why doesn't your data warehouse write the query", and simply put, we work for the state. The request has been submitted for a number of years.

 

Using v-yulgu-msft's example:

I was able to take the 2-column example and make my data "fit". However I think there may be a better solution than what I've done.

 

let
    // Referencing an existing query called 'InvList'
// This removed columns that were not necessary for the merge Source = #"InvList", // Splitting [Manager] into two fields; originally 'LastName,First' #"Split Column by Delimiter" = Table.SplitColumn(Source, "Manager", Splitter.SplitTextByEachDelimiter({","}, QuoteStyle.Csv, false), {"Manager.1", "Manager.2"}), // Rename the two newly created fields [LastName] & [FirstName] #"Renamed Columns" = Table.RenameColumns(#"Split Column by Delimiter",{{"Manager.1", "LastName"}, {"Manager.2", "FirstName"}}), // Merge the [FirstName]&" "&[LastName] into [Manager] #"Merged Manager Name" = Table.CombineColumns(#"Renamed Columns",{"FirstName", "LastName"},Combiner.CombineTextByDelimiter(" ", QuoteStyle.None),"Manager"), #"Merged Columns" = Table.CombineColumns(#"Merged Manager Name",{"Manager", "EmailAddress"},Combiner.CombineTextByDelimiter(";", QuoteStyle.None),"Manager.1"), // Merge [DeptID]&" = "&[Department Description] to be a new field called [Merged] #"Merged DeptInfo" = Table.CombineColumns(#"Merged Columns",{"DeptID", "Department Description"},Combiner.CombineTextByDelimiter(" - ", QuoteStyle.None),"Merged"), // Function that adds an incrementing index number AddRanking = (table, column, newColumn) => Table.AddIndexColumn(Table.Sort(table, {{column, Order.Ascending}}), newColumn, 1, 1), // Group the fields by [Manager] #"Grouped Rows" = Table.Group(#"Merged DeptInfo", {"Manager.1"}, {{"Data", each _, type table}}), // Function calling 'AddRanking' to insert the incrementing index number Transformed = Table.TransformColumns(#"Grouped Rows", {{"Data", each AddRanking(_, "Merged", "Rank")}}), // Expands the table that was created by #"Grouped Rows" #"Expand Data" = Table.ExpandTableColumn(Transformed, "Data", {"Merged", "Rank"}, {"Merged", "Rank"}), // This is the copy -> paste -> transpose magic that I wanted to automate; #"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Expand Data", {{"Rank", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Expand Data", {{"Rank", type text}}, "en-US")[Rank]), "Rank", "Merged"),
// Extra step to get two columns back - leaves 'Manager' 'Email' 'ColumnIndex x'...
#"Split Column by Delimiter1" = Table.SplitColumn(#"Pivoted Column", "Manager.1", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Manager", "Email"}), #"Changed Type" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"Manager", type text}, {"Email", type text}}) in #"Changed Type"

 

The real question of my post

How can the code be improved next time without the extra step of merging [Manager] & [Email] then splitting them? Let's say that the next project requires [Phone] [Address] to be in the output, is there a way to clean up the code?

 

The final output looks like the below image. Each record will get one email with some IF MERGEFIELD code in MSWord listing each department that they manage.

7.png






Did I answer your question? Mark my post as a solution!
Did my answers help arrive at a solution? Give it a kudos by clicking the Thumbs Up!

Proud to be a Super User!



1 ACCEPTED SOLUTION

@v-yulgu-msft

 

Well it took a short 2 hour Saturday road trip for me to come up with the realization/solution.

 

You're absolutely correct, Why do you need to "merge [Manager] & [Email] then splitting them"?. This is exactly what I was thinking too.

 

Basically, I did not think to Table.Group( ) by more than one field.

 

To bring closure to the question, sample data provided below:

 

ManagerNameEmailDeptIDDeptDesc
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10002Daffy2Acct
Duck,Daffydaffy@duck.comD10002Daffy2Acct
Duck,Daffydaffy@duck.comD10002Daffy2Acct
Mouse,Minnieminnie@mouse.comD90001Minnie1Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Mickeymickey@mouse.comD30001Mickey1Acct
Mouse,Mickeymickey@mouse.comD30001Mickey1Acct
Mouse,Mickeymickey@mouse.comD30001Mickey1Acct
Mouse,Mickeymickey@mouse.comD30001Mickey1Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30003Mickey3Acct
McDuck,Scroogescrouge@mcduck.comD60001Scrouge1Acct

 

 

let

    Source = Excel.CurrentWorkbook(){[Name="MergeTable"]}[Content],
    #"Removed Duplicates" = Table.Distinct(Source),
    #"Changed Type" = Table.TransformColumnTypes(#"Removed Duplicates",{{"ManagerName", type text}, {"Email", type text}, {"DeptID", type text}, {"DeptDesc", type text}}),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "ManagerName", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"LastName", "FirstName"}),
    #"Merged Columns" = Table.CombineColumns(#"Split Column by Delimiter",{"FirstName", "LastName"},Combiner.CombineTextByDelimiter(" ", QuoteStyle.None),"ManagerName"),
    #"Merged Columns1" = Table.CombineColumns(#"Merged Columns",{"DeptID", "DeptDesc"},Combiner.CombineTextByDelimiter(" - ", QuoteStyle.None),"DeptInfo"),
    // Function that adds an incrementing index number
    AddRanking = (table, column, newColumn) =>
        Table.AddIndexColumn(Table.Sort(table, {{column, Order.Ascending}}), newColumn, 1, 1),
    #"Grouped Rows" = Table.Group(#"Merged Columns1", {"ManagerName", "Email"}, {{"Data", each _, type table}}),
    Transformed = Table.TransformColumns(#"Grouped Rows", {{"Data", each AddRanking(_, "DeptInfo", "Rank")}}),
    #"Expand Data" = Table.ExpandTableColumn(Transformed, "Data", {"DeptInfo", "Rank"}, {"DeptInfo", "Rank"}),
    #"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Expand Data", {{"Rank", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Expand Data", {{"Rank", type text}}, "en-US")[Rank]), "Rank", "DeptInfo")

in
    #"Pivoted Column"

 

 

Expected Table results for an MSWord Email Merge where each manager gets one email with a list of their department's.

 

ManagerNameEmail123
Daffy Duckdaffy@duck.comD10001 - Daffy1AcctD10002 - Daffy2Acct 
Mickey Mousemickey@mouse.comD30001 - Mickey1AcctD30002 - Mickey2AcctD30003 - Mickey3Acct
Minnie Mouseminnie@mouse.comD90001 - Minnie1AcctD90002 - Minnie2Acct 
Scrooge McDuckscrouge@mcduck.comD60001 - Scrouge1Acct  





Did I answer your question? Mark my post as a solution!
Did my answers help arrive at a solution? Give it a kudos by clicking the Thumbs Up!

Proud to be a Super User!



View solution in original post

2 REPLIES 2
v-yulgu-msft
Employee
Employee

Hi @ChrisMendoza,

 

Why do you need to "merge [Manager] & [Email] then splitting them"? Please show us the original table data.

 

Regards,

Yuliana Gu

Community Support Team _ Yuliana Gu
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

@v-yulgu-msft

 

Well it took a short 2 hour Saturday road trip for me to come up with the realization/solution.

 

You're absolutely correct, Why do you need to "merge [Manager] & [Email] then splitting them"?. This is exactly what I was thinking too.

 

Basically, I did not think to Table.Group( ) by more than one field.

 

To bring closure to the question, sample data provided below:

 

ManagerNameEmailDeptIDDeptDesc
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10001Daffy1Acct
Duck,Daffydaffy@duck.comD10002Daffy2Acct
Duck,Daffydaffy@duck.comD10002Daffy2Acct
Duck,Daffydaffy@duck.comD10002Daffy2Acct
Mouse,Minnieminnie@mouse.comD90001Minnie1Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Minnieminnie@mouse.comD90002Minnie2Acct
Mouse,Mickeymickey@mouse.comD30001Mickey1Acct
Mouse,Mickeymickey@mouse.comD30001Mickey1Acct
Mouse,Mickeymickey@mouse.comD30001Mickey1Acct
Mouse,Mickeymickey@mouse.comD30001Mickey1Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30002Mickey2Acct
Mouse,Mickeymickey@mouse.comD30003Mickey3Acct
McDuck,Scroogescrouge@mcduck.comD60001Scrouge1Acct

 

 

let

    Source = Excel.CurrentWorkbook(){[Name="MergeTable"]}[Content],
    #"Removed Duplicates" = Table.Distinct(Source),
    #"Changed Type" = Table.TransformColumnTypes(#"Removed Duplicates",{{"ManagerName", type text}, {"Email", type text}, {"DeptID", type text}, {"DeptDesc", type text}}),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "ManagerName", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"LastName", "FirstName"}),
    #"Merged Columns" = Table.CombineColumns(#"Split Column by Delimiter",{"FirstName", "LastName"},Combiner.CombineTextByDelimiter(" ", QuoteStyle.None),"ManagerName"),
    #"Merged Columns1" = Table.CombineColumns(#"Merged Columns",{"DeptID", "DeptDesc"},Combiner.CombineTextByDelimiter(" - ", QuoteStyle.None),"DeptInfo"),
    // Function that adds an incrementing index number
    AddRanking = (table, column, newColumn) =>
        Table.AddIndexColumn(Table.Sort(table, {{column, Order.Ascending}}), newColumn, 1, 1),
    #"Grouped Rows" = Table.Group(#"Merged Columns1", {"ManagerName", "Email"}, {{"Data", each _, type table}}),
    Transformed = Table.TransformColumns(#"Grouped Rows", {{"Data", each AddRanking(_, "DeptInfo", "Rank")}}),
    #"Expand Data" = Table.ExpandTableColumn(Transformed, "Data", {"DeptInfo", "Rank"}, {"DeptInfo", "Rank"}),
    #"Pivoted Column" = Table.Pivot(Table.TransformColumnTypes(#"Expand Data", {{"Rank", type text}}, "en-US"), List.Distinct(Table.TransformColumnTypes(#"Expand Data", {{"Rank", type text}}, "en-US")[Rank]), "Rank", "DeptInfo")

in
    #"Pivoted Column"

 

 

Expected Table results for an MSWord Email Merge where each manager gets one email with a list of their department's.

 

ManagerNameEmail123
Daffy Duckdaffy@duck.comD10001 - Daffy1AcctD10002 - Daffy2Acct 
Mickey Mousemickey@mouse.comD30001 - Mickey1AcctD30002 - Mickey2AcctD30003 - Mickey3Acct
Minnie Mouseminnie@mouse.comD90001 - Minnie1AcctD90002 - Minnie2Acct 
Scrooge McDuckscrouge@mcduck.comD60001 - Scrouge1Acct  





Did I answer your question? Mark my post as a solution!
Did my answers help arrive at a solution? Give it a kudos by clicking the Thumbs Up!

Proud to be a Super User!



Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.