Forum Discussion

CNENFRNL's avatar
CNENFRNL
Community Champion
5 years ago
Solved

Request for advice on PQ formula

Dear PQ gurus,   I'm looking to make such substitutions in PQ but all formulae failed. value "foo" in columns are substituted by values in corresponding columns, eg. "foo" in ColA are re...
  • AlexisOlson's avatar
    5 years ago

    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"