PowerQuery Application: Dynamic Column Sorting

I received a question in the Power BI Community today. The requirement is to automatically sort the columns according to different values ​​​​of the product column (illustration is provided below). I quickly thought that it can be solved by just defining a PowerQuery function, and here I will put this small Share your skills with everyone.

need

As shown in the figure below, the NUMBER column is divided according to the ID column (product number). As can be seen from the figure, this is not a perspective, and it requires that whenever a new product number is added to the ID column, a new column can be automatically added, and so on.

Insert image description here

data

Open the PowerQuery editor and simulate a sample data:

let
DATA = 
    Table.FromRecords(
        {
            [ID = "A", Number = 12],
            [ID = "A", Number = 5],
            [ID = "A", Number = 6],
            [ID = "A", Number = 8],
            [ID = "B", Number = 14],
            [ID = "B", Number = 9],
            [ID = "B", Number = 7],
            [ID = "B", Number = 7],
            [ID = "C", Number = 5],
            [ID = "C", Number = 16],
            [ID = "C", Number = 18]
        },
        type table [ID = nullable text, Number = nullable number]
    )
in
    DATA

As shown in the picture:

Insert image description here

plan

The overall idea is to use the M statement to define a function, with ID as the only parameter of the function. Whenever a parameter is passed, for example, when the ID is A, the original data can be filtered by this parameter into a data table with only A products, and then just rename the NUMBER column to a parameter. When the parameters are B, C, D, E..., and so on, so the new NUMBER column name will also be B, C, D, E..., PowerQuery recognizes that these are different columns, and will automatically create new columns when merging data, so It solved the problem perfectly.

step

define function

Here you only need to define one parameter and complete two steps. Filter and rename as mentioned above:

(ID_Code as text) => 
let
DATA = 
    DATA,
    DATA_Filtered = Table.SelectRows(DATA, each ([ID] = ID_Code)),
    DATA_Renamed = Table.RenameColumns(DATA_Filtered,{
   
   {"Number", ID_Code}})

in
    DATA_Renamed

Substitute any parameters and test without error:

Insert image description here

Create a new parameter table

We need to continuously pass parameters to the function in order to get a complete table, so we need to take the ID column and remove duplicates to generate a parameter table:

let
    Source = DATA,
    #"Removed Columns" = Table.RemoveColumns(Source,{"Number"}),
    #"Removed Duplicates" = Table.Distinct(#"Removed Columns"),
    #"Invoked Custom Function" = Table.AddColumn(#"Removed Duplicates", "demo", each demo([ID])),
    #"Removed Columns1" = Table.RemoveColumns(#"Invoked Custom Function",{"ID"}),
    #"Expanded demo" = Table.ExpandTableColumn(#"Removed Columns1", "demo", {"ID", "A", "B", "C"}, {"ID", "A", "B", "C"})
in
    #"Expanded demo"

as follows:

Insert image description here

Call function to complete column sorting

Select the parameter table, then operate as shown below to call the function we created previously and expand the resulting columns:

Insert image description here

You can also run the following code directly:

let
    Source = DATA,
    #"Removed Columns" = Table.RemoveColumns(Source,{"Number"}),
    #"Removed Duplicates" = Table.Distinct(#"Removed Columns"),
    #"Invoked Custom Function" = Table.AddColumn(#"Removed Duplicates", "demo", each demo([ID])),
    #"Removed Columns1" = Table.RemoveColumns(#"Invoked Custom Function",{"ID"}),
    #"Expanded demo" = Table.ExpandTableColumn(#"Removed Columns1", "demo", {"ID", "A", "B", "C"})
in
    #"Expanded demo"

The results are as follows, in line with expectations:

Insert image description here

test

Now we append new data [D] to the data source:

Insert image description here

Running the query, we find that the latest column [column D] has not been created. This is because when expanding the NUMBER column, its parameters are fixed. We need to let the Table.ExpandTableColumn function dynamically obtain the complete ID list. This step is not difficult. We only need to convert the parameter table into a list and assign it to the new variable [ID]:

ID = #"Removed Duplicates"[ID]

Then replace the following part of the original code:

= Table.ExpandTableColumn(#"Removed Columns1", "demo", {"ID", "A", "B", "C"})

Just change it to the following statement.

= Table.ExpandTableColumn(#"Removed Columns1", "demo", ID)

Running the query again, all columns are generated dynamically as expected and the problem is perfectly resolved.

Insert image description here

Guess you like

Origin blog.csdn.net/qq_44794714/article/details/109156738