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
CNENFRNL
Community Champion
Community Champion

Request for advice on PQ formula

Dear PQ gurus,

 

I'm looking to make such substitutions in PQ but all formulae failed.

Untitled.png

value "foo" in columns are substituted by values in corresponding columns, eg. "foo" in ColA are replaced by values in x.ColA, "foo" in ColB by values in x.ColB, etc.

 

Any hint or advice is highly appreciated!


Thanks to the great efforts by MS engineers to simplify syntax of DAX! Most beginners are SUCCESSFULLY MISLED to think that they could easily master DAX; but it turns out that the intricacy of the most frequently used RANKX() is still way beyond their comprehension!

DAX is simple, but NOT EASY!

2 ACCEPTED SOLUTIONS
AlexisOlson
Super User
Super User

You could do this with some fancy row transformations similar to the syntax I used here but, as mentioned there, it's probably easier to unpivot, replace values, pivot back.

 

Edit: Since you aren't replacing with a fixed value, it's a bit more involved but the unpivoting and pivoting is still a good trick. Try this:

 

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"ColA", type any}, {"xx", Int64.Type}, {"ColB", type any}, {"ColC", type any}, {"yy", Int64.Type}, {"ColD", type any}, {"x.ColA", Int64.Type}, {"x.ColB", Int64.Type}, {"x.ColC", Int64.Type}, {"x.ColD", Int64.Type}}),
    #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Added Index", {"xx", "yy", "Index"}, "ColName", "Value"),
    #"Added Custom" = Table.AddColumn(#"Unpivoted Other Columns", "ColPair", each Text.Replace([ColName],"x.",""), type text),
    #"Grouped Rows" = Table.Group(#"Added Custom", {"xx", "yy", "ColPair"}, {{"Value", each List.Min([Value]), type any}}),
    #"Merged Queries" = Table.NestedJoin(#"Added Custom", {"xx", "yy", "ColPair"}, #"Grouped Rows", {"xx", "yy", "ColPair"}, "Grouped Rows", JoinKind.LeftOuter),
    #"Removed Columns" = Table.RemoveColumns(#"Merged Queries",{"Value", "ColPair"}),
    #"Expanded Grouped Rows" = Table.ExpandTableColumn(#"Removed Columns", "Grouped Rows", {"Value"}, {"Value"}),
    #"Pivoted Column" = Table.Pivot(#"Expanded Grouped Rows", List.Distinct(#"Expanded Grouped Rows"[ColName]), "ColName", "Value"),
    #"Sorted Rows" = Table.Sort(#"Pivoted Column",{{"Index", Order.Ascending}}),
    #"Reordered Columns" = Table.ReorderColumns(#"Sorted Rows",{"Index", "ColA", "xx", "ColB", "ColD", "ColC", "yy", "x.ColA", "x.ColB", "x.ColC", "x.ColD"}),
    #"Removed Columns1" = Table.RemoveColumns(#"Reordered Columns",{"Index"})
in
    #"Removed Columns1"

 

There are some extra steps to make sure the rows and columns are sorted correctly.

 

If you're OK with three levels of expression context, then you can use the row and record transformation method with fewer steps:

 

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    Transformed = Table.FromRecords(
        Table.TransformRows(
            Source,
            (row) => 
            Record.TransformFields(
                row,
                List.Transform(
                    {"ColA", "ColB", "ColC", "ColD"},
                    (col) => {col, each if _ = "foo" then Record.Field(row, "x." & col) else _}
                )
            )
        ),
        Value.Type(Source)
    ),
    #"Reordered Columns" =
        Table.ReorderColumns(
            Transformed,
            {"ColA", "xx", "ColB", "ColC", "yy", "ColD", "x.ColA", "x.ColB", "x.ColC", "x.ColD"}
        )
in
    #"Reordered Columns"

 

View solution in original post

Anonymous
Not applicable

5 REPLIES 5
Anonymous
Not applicable

a draft ...

Thank you so much for your kind help! Your idea is inspiring. I tweak your code and get an idealest solution so far.

 

let
    Origine = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("TY6xDsAgCET/hdmhRNH6LYS1q/+/FeFsmvDwLhxEVWpUaILb6Q5f3gYI08mK0rOWF4Jh8sVaqn1QkOGz5rpilo4/NeBa6J0/35g/Ki4KZkJmLw==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ColA = _t, xx = _t, ColB = _t, ColC = _t, yy = _t, ColD = _t, x.ColA = _t, x.ColB = _t, x.ColC = _t, x.ColD = _t]),

    namesX=List.Select(Table.ColumnNames(Origine), each Text.StartsWith(_, "Col")),
    tac=List.Accumulate(
        namesX,
        Origine,
        (s,c) => Table.ReplaceValue(s, each if Text.Contains(Record.Field(_, c), "foo") then Record.Field(_, c) else null, each Record.Field(_,"x."&c), Replacer.ReplaceValue, {c})
    )
in
    tac

 


Thanks to the great efforts by MS engineers to simplify syntax of DAX! Most beginners are SUCCESSFULLY MISLED to think that they could easily master DAX; but it turns out that the intricacy of the most frequently used RANKX() is still way beyond their comprehension!

DAX is simple, but NOT EASY!

Une autre solution améliorée,

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("TY6xDsAgCET/hdmhRNH6LYS1q/+/FeFsmvDwLhxEVWpUaILb6Q5f3gYI08mK0rOWF4Jh8sVaqn1QkOGz5rpilo4/NeBa6J0/35g/Ki4KZkJmLw==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ColA = _t, xx = _t, ColB = _t, ColC = _t, yy = _t, ColD = _t, x.ColA = _t, x.ColB = _t, x.ColC = _t, x.ColD = _t]),

    namesX=List.Select(Table.ColumnNames(Source), each Text.StartsWith(_, "Col")),
    #"Merged Columns" = List.Accumulate(
        namesX,
        Source,
        (s,c) => Table.CombineColumns(s, {c, "x."&c}, each if Text.Contains(_{0}, "foo") then _{1} else _{0}, c)
    )
in
    #"Merged Columns"

 


Thanks to the great efforts by MS engineers to simplify syntax of DAX! Most beginners are SUCCESSFULLY MISLED to think that they could easily master DAX; but it turns out that the intricacy of the most frequently used RANKX() is still way beyond their comprehension!

DAX is simple, but NOT EASY!

AlexisOlson
Super User
Super User

You could do this with some fancy row transformations similar to the syntax I used here but, as mentioned there, it's probably easier to unpivot, replace values, pivot back.

 

Edit: Since you aren't replacing with a fixed value, it's a bit more involved but the unpivoting and pivoting is still a good trick. Try this:

 

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"ColA", type any}, {"xx", Int64.Type}, {"ColB", type any}, {"ColC", type any}, {"yy", Int64.Type}, {"ColD", type any}, {"x.ColA", Int64.Type}, {"x.ColB", Int64.Type}, {"x.ColC", Int64.Type}, {"x.ColD", Int64.Type}}),
    #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Added Index", {"xx", "yy", "Index"}, "ColName", "Value"),
    #"Added Custom" = Table.AddColumn(#"Unpivoted Other Columns", "ColPair", each Text.Replace([ColName],"x.",""), type text),
    #"Grouped Rows" = Table.Group(#"Added Custom", {"xx", "yy", "ColPair"}, {{"Value", each List.Min([Value]), type any}}),
    #"Merged Queries" = Table.NestedJoin(#"Added Custom", {"xx", "yy", "ColPair"}, #"Grouped Rows", {"xx", "yy", "ColPair"}, "Grouped Rows", JoinKind.LeftOuter),
    #"Removed Columns" = Table.RemoveColumns(#"Merged Queries",{"Value", "ColPair"}),
    #"Expanded Grouped Rows" = Table.ExpandTableColumn(#"Removed Columns", "Grouped Rows", {"Value"}, {"Value"}),
    #"Pivoted Column" = Table.Pivot(#"Expanded Grouped Rows", List.Distinct(#"Expanded Grouped Rows"[ColName]), "ColName", "Value"),
    #"Sorted Rows" = Table.Sort(#"Pivoted Column",{{"Index", Order.Ascending}}),
    #"Reordered Columns" = Table.ReorderColumns(#"Sorted Rows",{"Index", "ColA", "xx", "ColB", "ColD", "ColC", "yy", "x.ColA", "x.ColB", "x.ColC", "x.ColD"}),
    #"Removed Columns1" = Table.RemoveColumns(#"Reordered Columns",{"Index"})
in
    #"Removed Columns1"

 

There are some extra steps to make sure the rows and columns are sorted correctly.

 

If you're OK with three levels of expression context, then you can use the row and record transformation method with fewer steps:

 

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    Transformed = Table.FromRecords(
        Table.TransformRows(
            Source,
            (row) => 
            Record.TransformFields(
                row,
                List.Transform(
                    {"ColA", "ColB", "ColC", "ColD"},
                    (col) => {col, each if _ = "foo" then Record.Field(row, "x." & col) else _}
                )
            )
        ),
        Value.Type(Source)
    ),
    #"Reordered Columns" =
        Table.ReorderColumns(
            Transformed,
            {"ColA", "xx", "ColB", "ColC", "yy", "ColD", "x.ColA", "x.ColB", "x.ColC", "x.ColD"}
        )
in
    #"Reordered Columns"

 

Thank you so much for your kind help! Your idea is inspiring; I'm trying to incorporate your proposal into my solution.


Thanks to the great efforts by MS engineers to simplify syntax of DAX! Most beginners are SUCCESSFULLY MISLED to think that they could easily master DAX; but it turns out that the intricacy of the most frequently used RANKX() is still way beyond their comprehension!

DAX is simple, but NOT EASY!

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.

Top Solution Authors
Top Kudoed Authors