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

Join us for an expert-led overview of the tools and concepts you'll need to become a Certified Power BI Data Analyst and pass exam PL-300. Register now.

Reply
alexdi
Helper II
Helper II

Table matrix grouping and transform

I have an permissions matrix that looks like this:

 

IDitemgroup1group2group3
1string_bYNN
2string_xNYY
3string_eY Y
4string_bNYY
5string_xNYN
6string_bYYY
7string_eYNY

 

Groups associate to items. However, the items are not always uniquely-named, and I need to know when there's a permissions mismatch where the item is enabled for one row, but disabled on another. 

 

Adjacent to the table above, I have another column that looks like this:

 

IDDisabled elsewhere
1group1
2group3
3 
4group2, group3
5 
6group1, group2, group3
7 

 

It's driven by about 50 helper columns, which, because of the dynamic nature of the groups, need to use elaborate formulas with lots of indirects, which make the sheet unusable. I need to convert it to a mechanism I can run on command. DAX is definitely preferable to VBA here. 

 

Can anyone suggest how to transform the table to create the result above? I've been hacking away at it and not making much progress. Much appreciated as always, a lot of the functionality of this matrix derives from advice from this forum.

 

A few notes:

 

1500 rows
Up to 50 groups
Unique IDs, sequential
Unique group names, dynamic number of groups
Item strings are not unique
Name/group associations can be "Y", "N", or null

1 ACCEPTED SOLUTION
ImkeF
Community Champion
Community Champion

OK, so this should do then:

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUSouKcrMS49PAjIjgdgPjGN1opWMEJIVUIlIMAZJGiMkU6EScDkTVFNRNZpiNxVipRmmexA6zTGthOiOjQUA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [ID = _t, item = _t, group1 = _t, group2 = _t, group3 = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", Int64.Type}, {"item", type text}, {"group1", type text}, {"group2", type text}, {"group3", type text}}),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"ID", "item"}, "Attribute", "Value"),
    GroupOnItemAndGroup = Table.Group(#"Unpivoted Other Columns", {"item", "Attribute"}, {{"All Rows", each _, type table [ID=number, item=text, Attribute=text, Value=text]}}),
    AddIDs = Table.AddColumn(GroupOnItemAndGroup, "ID", each [All Rows][ID]),
    #"Expanded ID" = Table.ExpandListColumn(AddIDs, "ID"),
    GetTestValue = Table.AddColumn(#"Expanded ID", "Test", each [All Rows]{[ID=[ID]]}[Value]),
    GetElsewheres = Table.AddColumn(GetTestValue, "elsewhere", each Table.SelectRows([All Rows], (x) => x[ID] <> [ID])[Value]),
    CheckForMismatch = Table.AddColumn(GetElsewheres, "Mismatch", each if [Test] = "Y" and List.ContainsAny([elsewhere], {"N", ""}) then [Attribute] else null),
    #"Grouped Rows" = Table.Group(CheckForMismatch, {"ID"}, {{"All Rows", each _, type table [item=text, Attribute=text, All Rows=table, ID=number, Test=text, elsewhere=list, Mismatch=text]}}),
    ExtractMismatch = Table.AddColumn(#"Grouped Rows", "Custom", each Text.Combine([All Rows][Mismatch], ", ")),
    #"Sorted Rows" = Table.Sort(ExtractMismatch,{{"ID", Order.Ascending}})
in
    #"Sorted Rows"

 

Imke Feldmann (The BIccountant)

If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!

How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries

View solution in original post

4 REPLIES 4
ImkeF
Community Champion
Community Champion

Hi @alexdi 

please paste the following code into the advanced editor and follow the steps:

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUSouKcrMS49PAjIjgdgPjGN1opWMEJIVUIlIMAZJGiMkU6EScDkTVFNRNZpiNxVipRmmexA6zTGthOiOjQUA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [ID = _t, item = _t, group1 = _t, group2 = _t, group3 = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", Int64.Type}, {"item", type text}, {"group1", type text}, {"group2", type text}, {"group3", type text}}),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"ID", "item"}, "Attribute", "Value"),
    GroupOnItemAndGroup = Table.Group(#"Unpivoted Other Columns", {"item", "Attribute"}, {{"All Rows", each _, type table [ID=number, item=text, Attribute=text, Value=text]}}),
    CountDistinctNumberOfPermissions = Table.AddColumn(GroupOnItemAndGroup, "DistinctValues", each List.Distinct([All Rows][Value])),
    MismatchIfMoreThanOnePermission = Table.AddColumn(CountDistinctNumberOfPermissions, "Mismatch", each if List.Count([DistinctValues]) > 1 then [Attribute] else null),
    Cleanup = Table.SelectColumns(MismatchIfMoreThanOnePermission,{"All Rows", "Mismatch"}),
    ExpandIDs = Table.ExpandTableColumn(Cleanup, "All Rows", {"ID"}, {"ID"}),
    GroupOnIDs = Table.Group(ExpandIDs, {"ID"}, {{"All Rows", each _, type table [ID=number, Mismatch=text]}}),
    CombineMismatchedGroups = Table.AddColumn(GroupOnIDs, "Custom", each Text.Combine([All Rows][Mismatch], ", ")),
    #"Sorted Rows" = Table.Sort(CombineMismatchedGroups,{{"ID", Order.Ascending}})
in
    #"Sorted Rows"

 

I've named the steps according to a mismatch logic that is plausible to me.

But as that doesn't seem to match yours, I hope this gives you an idea where your explanation of the desired mismatch-logic needs more clarification.

 

Imke Feldmann (The BIccountant)

If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!

How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries

ImkeF, that's a really terrific general solution, thank for that. It's 95% there for this problem. The reason I'm not looking to return all mismatches (just those where the test value is Y, and a row with the same item is N) is because, for this system, the N's win. If the test row is N and there's a Y elsewhere, that doesn't require action because the mismatch doesn't matter. If it's Y and elsewhere is N, then you're not getting the Y you wanted, so you need to go fix the other row. 

ImkeF
Community Champion
Community Champion

OK, so this should do then:

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUSouKcrMS49PAjIjgdgPjGN1opWMEJIVUIlIMAZJGiMkU6EScDkTVFNRNZpiNxVipRmmexA6zTGthOiOjQUA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [ID = _t, item = _t, group1 = _t, group2 = _t, group3 = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", Int64.Type}, {"item", type text}, {"group1", type text}, {"group2", type text}, {"group3", type text}}),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"ID", "item"}, "Attribute", "Value"),
    GroupOnItemAndGroup = Table.Group(#"Unpivoted Other Columns", {"item", "Attribute"}, {{"All Rows", each _, type table [ID=number, item=text, Attribute=text, Value=text]}}),
    AddIDs = Table.AddColumn(GroupOnItemAndGroup, "ID", each [All Rows][ID]),
    #"Expanded ID" = Table.ExpandListColumn(AddIDs, "ID"),
    GetTestValue = Table.AddColumn(#"Expanded ID", "Test", each [All Rows]{[ID=[ID]]}[Value]),
    GetElsewheres = Table.AddColumn(GetTestValue, "elsewhere", each Table.SelectRows([All Rows], (x) => x[ID] <> [ID])[Value]),
    CheckForMismatch = Table.AddColumn(GetElsewheres, "Mismatch", each if [Test] = "Y" and List.ContainsAny([elsewhere], {"N", ""}) then [Attribute] else null),
    #"Grouped Rows" = Table.Group(CheckForMismatch, {"ID"}, {{"All Rows", each _, type table [item=text, Attribute=text, All Rows=table, ID=number, Test=text, elsewhere=list, Mismatch=text]}}),
    ExtractMismatch = Table.AddColumn(#"Grouped Rows", "Custom", each Text.Combine([All Rows][Mismatch], ", ")),
    #"Sorted Rows" = Table.Sort(ExtractMismatch,{{"ID", Order.Ascending}})
in
    #"Sorted Rows"

 

Imke Feldmann (The BIccountant)

If you liked my solution, please give it a thumbs up. And if I did answer your question, please mark this post as a solution. Thanks!

How to integrate M-code into your solution -- How to get your questions answered quickly -- How to provide sample data -- Check out more PBI- learning resources here -- Performance Tipps for M-queries

That's awesome, thanks so much! That just shaved two seconds of calculation delay from every interaction.

 

If you're game for another challenge, there's one more difficult calculated column I posted here:

 

https://community.powerbi.com/t5/Power-Query/Determining-if-a-parent-in-a-hierarchy-is-disabled-for-...

Helpful resources

Announcements
Join our Fabric User Panel

Join our Fabric User Panel

This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.

June 2025 Power BI Update Carousel

Power BI Monthly Update - June 2025

Check out the June 2025 Power BI update to learn about new features.

June 2025 community update carousel

Fabric Community Update - June 2025

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