Advance your Data & AI career with 50 days of live learning, dataviz contests, hands-on challenges, study groups & certifications and more!
Get registeredGet Fabric Certified for FREE during Fabric Data Days. Don't miss your chance! Request now
I have these tables:
Groups:
| GroupID | Name |
| 1 | Group1 |
| 2 | Group2 |
Users:
| UserID | User |
| 1 | Bob |
| 2 | Shelly |
I'm trying to create this:
RecursiveMerge:
| UserID | User | Group1 | Group2 |
| 1 | Bob | ||
| 2 | Shelly | Y |
With these requirements:
So far, I can create the table, but if I rename a Group, the relationships disappear. I assume this is because of the way the query is matching columns to add and remove them as the query is refreshed.
This is the code I have:
let
Source = Excel.CurrentWorkbook(){[Name="RecursiveMerge"]}[Content],
Source2 = Excel.CurrentWorkbook(){[Name="Users"]}[Content],
#"Merged Queries" = Table.NestedJoin(Source2,{"ID", "User"},Source,{"ID", "User"},"Removed Columns",JoinKind.LeftOuter),
#"Expanded Removed Columns" = Table.ExpandTableColumn(#"Merged Queries", "Removed Columns", List.Skip(Table.ColumnNames(Source),2)),
#"Removed Other Columns" = Table.SelectColumns(#"Expanded Removed Columns",{"ID", "User"}&Groups[Name], MissingField.UseNull)
in
#"Removed Other Columns"
How can I modify this to preseve relationships when I change Group or User names? Thank you.
Solved! Go to Solution.
Hello @Anonymous
now this requires some advanced coding. It includes to include the Group-id in your column names, foresee a renmaing process as well as deleting and adding process. I've tried this and found a solution. You have to change 2 queries. Here the code for it
//Groups
let
Source = Excel.CurrentWorkbook(){[Name="Groups"]}[Content],
AddKey = Table.AddColumn(Source, "Key", each Text.From([ID])&"-"&Text.From([Name]))
in
AddKey
//RecursiveMerge
let
Source = Excel.CurrentWorkbook
(
)
{[Name="RecursiveMerge"]}[Content
],
Source2 = Excel.CurrentWorkbook
(
)
{[Name="Users"]}[Content
],
#"Merged Queries" = Table.NestedJoin
(
Source2,
{"ID"},
Source,
{"ID"},
"Removed Columns",
JoinKind.LeftOuter
),
#"Expanded Removed Columns" = Table.ExpandTableColumn
(
#"Merged Queries",
"Removed Columns",
List.Skip
(
Table.ColumnNames
(
Source
),
2
)
),
SelectGroups = Table.FromRecords
(
Table.TransformRows
(
Table.AddColumn
(
Table.AddColumn
(
Table.ExpandTableColumn
(
Table.NestedJoin
(
Table.TransformColumnTypes
(
Table.SplitColumn
(
Table.FromList
(
List.Select
(
Table.ColumnNames
(
#"Expanded Removed Columns"
),
each Text.Contains
(
_,
"-"
)
),
Splitter.SplitByNothing
(
)
),
"Column1",
Splitter.SplitTextByDelimiter
(
"-"
)
),
{{"Column1.1", type number}}
),
"Column1.1",
Groups,
"ID",
"Groups"
),
"Groups",
{"Name"},
{"Name"}
),
"OldName",
each Text.From
(
[Column1.1]
)
&"-"&[Column1.2]
),
"NewName",
each Text.From
(
[Column1.1]
)
&"-"&[Name]
),
(
row
)
=> if row[NewName]=null then Record.TransformFields
(
row,
{"NewName", each row[OldName]&" / to be deleted"}
)
else row
)
),
RenameColumns = Table.RenameColumns
(
#"Expanded Removed Columns",
List.Zip
(
{SelectGroups[OldName],SelectGroups[NewName]}
)
),
ColumnsToAdd = List.Difference
(
Groups[Key
],
Table.ColumnNames
(
RenameColumns
)
),
AddColumns = Table.SelectColumns
(
RenameColumns,
Table.ColumnNames
(
RenameColumns
)
&ColumnsToAdd,
MissingField.UseNull
)
in
AddColumns
Try it out
I'm looking forward to your feedback
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
Thank you for that attempt. I apologize, I wasn't clear about what I was asking.
The Y values will be arbitrary entered and changed after the matrix is generated. They must be retained even when the matrix changes, provided the ID for the relevant Group and User continue to exist in those tables. (The Groups table should have an ID; I've updated the original post to reflect this.)
Hello @Anonymous
where do you maintain this values? Are you using Excel?
Jimmy
Yes, Excel. I've been translating the queries provided to account for that data source.
Hello @Anonymous
I've tried to build up your scenario, but was not able to.
could you please share the Excel-file
Thanks
Jimmy
Hello @Anonymous
why is there a connection needed between the Groups-table and your recursive-query? I don't see any benefits of having this connection. Whats the goal of having this?
BR
Jimmy
Apologies for the delay-- the groups table is the source for the column names in the recursive query. It's using them to determine what column layout should be after the query is refreshed.
Hello @Anonymous
now this requires some advanced coding. It includes to include the Group-id in your column names, foresee a renmaing process as well as deleting and adding process. I've tried this and found a solution. You have to change 2 queries. Here the code for it
//Groups
let
Source = Excel.CurrentWorkbook(){[Name="Groups"]}[Content],
AddKey = Table.AddColumn(Source, "Key", each Text.From([ID])&"-"&Text.From([Name]))
in
AddKey
//RecursiveMerge
let
Source = Excel.CurrentWorkbook
(
)
{[Name="RecursiveMerge"]}[Content
],
Source2 = Excel.CurrentWorkbook
(
)
{[Name="Users"]}[Content
],
#"Merged Queries" = Table.NestedJoin
(
Source2,
{"ID"},
Source,
{"ID"},
"Removed Columns",
JoinKind.LeftOuter
),
#"Expanded Removed Columns" = Table.ExpandTableColumn
(
#"Merged Queries",
"Removed Columns",
List.Skip
(
Table.ColumnNames
(
Source
),
2
)
),
SelectGroups = Table.FromRecords
(
Table.TransformRows
(
Table.AddColumn
(
Table.AddColumn
(
Table.ExpandTableColumn
(
Table.NestedJoin
(
Table.TransformColumnTypes
(
Table.SplitColumn
(
Table.FromList
(
List.Select
(
Table.ColumnNames
(
#"Expanded Removed Columns"
),
each Text.Contains
(
_,
"-"
)
),
Splitter.SplitByNothing
(
)
),
"Column1",
Splitter.SplitTextByDelimiter
(
"-"
)
),
{{"Column1.1", type number}}
),
"Column1.1",
Groups,
"ID",
"Groups"
),
"Groups",
{"Name"},
{"Name"}
),
"OldName",
each Text.From
(
[Column1.1]
)
&"-"&[Column1.2]
),
"NewName",
each Text.From
(
[Column1.1]
)
&"-"&[Name]
),
(
row
)
=> if row[NewName]=null then Record.TransformFields
(
row,
{"NewName", each row[OldName]&" / to be deleted"}
)
else row
)
),
RenameColumns = Table.RenameColumns
(
#"Expanded Removed Columns",
List.Zip
(
{SelectGroups[OldName],SelectGroups[NewName]}
)
),
ColumnsToAdd = List.Difference
(
Groups[Key
],
Table.ColumnNames
(
RenameColumns
)
),
AddColumns = Table.SelectColumns
(
RenameColumns,
Table.ColumnNames
(
RenameColumns
)
&ColumnsToAdd,
MissingField.UseNull
)
in
AddColumns
Try it out
I'm looking forward to your feedback
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
Thanks @Jimmy801! I can see what you're trying to do it, it's very clever. Unfortunately I'm hitting an error on the SelectGroups step: "Expression.Error: The field 'Column1' of the record wasn't found." To test the solution, I downloaded my sample sheet, updated the Group connection, and then attempted to update the RecursiveMerge query.
Can you link to a copy of a sheet where this worked for you?
Hello @Anonymous
sorry, i forgot to mention that you have to rename your column header according to the specification.. .meaning combining ID and Group with "-" like this
another specificaiton is also that no other column can contain a "-" because this identifies your groupings
Hope its working out now
Jimmy
@Jimmy801, renaming the columns in the recursive table as described allowed me to add new columns and change column names in the Group table. However, removing entries in that table does not remove from the the recursive table, though the column names do have "to be deleted" appended (sometimes multiple times) to them. Is the intent to delete them manually?
Hello @Anonymous
exactly, this is the idea behind. So you can relly steer your process well. You think it's a godd idea too?
Jimmy
I think there are benefits to that approach, but for this audience, I'm telling them not to change anything at all on the matrix sheets except the associations. Ideally the matrix layout would be solely dictated by the data sheets with no manual column culling. Definitely a good thought though.
Hello @Anonymous
this tasks in Excel are easy as you block ranges etc. So setup the process as you need it and my programm will do the rest 🙂
All the best
Jimmy
Hi all,
an alternative can use the column position as an index, instead of adding it to the name (which to an extent goes against the idea of free-text renaming). This obviously means that columns can not be deleted or re-arranged, only renamed or added to the right.
Kind regards,
JB
Advance your Data & AI career with 50 days of live learning, contests, hands-on challenges, study groups & certifications and more!
Check out the October 2025 Power BI update to learn about new features.
| User | Count |
|---|---|
| 8 | |
| 7 | |
| 7 | |
| 4 | |
| 3 |