power query - find nearest time from multiple columns - powerbi

Time in
A
B
C
Custom
10.15am
7am
8am
11am
7.45am
7am
8am
11am
Using power query, how to find which columns (A, B or C) is the closest to column "Time in"? Expected output:
Time in
A
B
C
Custom
10.15am
7am
8am
11am
column C
7.45am
7am
8am
11am
column B
edit: what i have worked till now
List.Min({ Number.Abs ( Duration.TotalMinutes ( [Time in] - [A])), ..........})
but this only returns the smallest difference not the column

What came to mind, dynamic number of columns, was
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
ConvertToNumbers = List.Accumulate(Table.ColumnNames(Source),Source, (s,c)=>Table.TransformColumnTypes( s, {c,type number}, "en-US")),
#"Added Custom" = Table.AddColumn(ConvertToNumbers , "Custom", each let z= [Time in] in List.Min(List.Transform(List.Skip(Record.ToList(_),1), each Number.Abs(_ - z)))),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Column", each Table.ColumnNames(Source){1+List.PositionOfAny(List.Skip(Record.ToList(_),1),{[Custom]+[Time in],[Time in]-[Custom]})}),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"Custom"}),
ConvertToTime = List.Accumulate(Table.ColumnNames(Source),#"Removed Columns", (s,c)=>Table.TransformColumnTypes( s, {c,type time}, "en-US"))
in ConvertToTime

Related

Create duplicate rows in Power BI table using Power Query using date columns

I have a Power BI table sourced from blob storage. It has below structure
Here, I am constructing a composite column called "CustomKey" so that I can establish a relationship with another table.
MID
SIP
ValidFrom
ValidTo
CustomKey
1
c2
08/01/2022
11/30/2022
1_c2_08_2022
2
c3
12/24/2022
12/31/2022
2_c3_12_2022
Since the source has validFrom & ValidTo that can span across multiple months, I would like to have my table to like this so that mappings are possible from other table which has this customKey for 09/10/11 months of 2022.
MID
SIP
ValidFrom
ValidTo
CustomKey
1
c2
08/01/2022
11/30/2022
1_c2_08_2022
1
c2
08/01/2022
11/30/2022
1_c2_09_2022
1
c2
08/01/2022
11/30/2022
1_c2_10_2022
1
c2
08/01/2022
11/30/2022
1_c2_11_2022
2
c3
12/24/2022
12/31/2022
2_c3_12_2022
Can anyone guide me on how to accomplish this in Power Query?
I did try List.Generate() by passing in the ValidFrom & ValidTo & then tried to expand the list but it fails stating "Expression.Error: We cannot apply field access to the type Date."
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"MID", Int64.Type}, {"SIP", type text}, {"ValidFrom", type date}, {"ValidTo", type date}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each List.Generate(() => Date.Year([ValidFrom])*12 + Date.Month([ValidFrom]), let End_Month = Date.Year([ValidTo])*12 + Date.Month([ValidTo]) in each _ <= End_Month, each _ + 1)),
#"Expanded Custom" = Table.ExpandListColumn(#"Added Custom", "Custom"),
#"Added Custom1" = Table.AddColumn(#"Expanded Custom", "Month", each if Number.Mod([Custom],12) = 0 then 12 else Number.Mod([Custom],12)),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Year", each if Number.Mod([Custom],12) = 0 then Number.IntegerDivide([Custom],12) - 1 else Number.IntegerDivide([Custom],12)),
#"Added Custom3" = Table.AddColumn(#"Added Custom2", "CustomKey", each Number.ToText([MID])&"_"&[SIP]&"_"&Number.ToText([Month])&"_"&Number.ToText([Year]))
in
#"Added Custom3"
The Power Query formulas will help you get the correct output/result.

In Dax, how can i count values in one column that equal the value of another column?

I have two columns, i want a table that shows the number of "Assign Date" in "Week Start" so for "Week Start" of 1/1/2022 it should be 0, for "Week Start" of 1/7/2022, it should be 2, and it should be 1 for 1/14/2022 and 1/21/2022.
I have two date column
Week Start
Assign Date
1/1/2022
1/8/2022
1/8/2022
1/8/2022
1/15/2022
1/15/2022
1/22/2022
1/22/2022
I want one date column and one count column
Week Start
Assign Count
1/1/2022
0
1/8/2022
2
1/15/2022
1
1/22/2022
1
I am very new to DAX and i assume that i am over complicating the solution but i can't figure out where to start. Because i am learning DAX, i would like to get this in a DAX measure.
Or this measure:
Assign Count :=
VAR ThisWeekStart =
MIN( Table1[Week Start] )
RETURN
0
+ COUNTROWS(
FILTER(
ALL( Table1 ),
Table1[Assign Date] = ThisWeekStart
)
)
which you can place in a visual together with the Week Start field.
There may be more efficient M-Code, but what I did here was
to use List.Accumulate to count the number of entries that were in the correct range: >=Week Start and <Week Start + 7 days
M Code
let
Source = Excel.CurrentWorkbook(){[Name="Table3"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Week Start", type date}, {"Assign Date", type date}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Assign Count",
each List.Accumulate(
#"Changed Type"[Assign Date],
0,
(state, current)=>
if current >=[Week Start] and current < Date.AddDays([Week Start],7) then state +1 else state)),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Assign Date"})
in
#"Removed Columns"

QoQ Calculation Power BI

I'm calculating QoQ Imp and QoQ %Eng in the below data table which is grouped by with the help of power query by adding "Index starting from 0" and "Index.1 starting from 1".
I have a "filter" column in the Filters pane this visual. Please help me in calculating QoQ Imp and QoQ %Eng in the above Table A. The expected result/output should look like this below table:-
In Power Query (M Code), assuming your data is representative, you can compute the QoQ values before filtering/grouping etc.
Add your Index column as you show
Then add a Modulo column (value = 4, since you have four quarters)
Then add custom columns for your two calculations:
Then filter as needed
Here is the M Code assuming the data source is an Excel Table. Modify the Source line as needed
let
Source = Excel.CurrentWorkbook(){[Name="Table7"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Qtr", type text}, {"Filter", type text}, {"Imp", Int64.Type}, {"Eng", Int64.Type}}),
//Compute % Eng column
#"Added Custom" = Table.AddColumn(#"Changed Type", "% Eng", each [Eng]/[Imp], Percentage.Type),
//Add Index and Modulo columns
#"Added Index" = Table.AddIndexColumn(#"Added Custom", "Index", 0, 1, Int64.Type),
#"Inserted Modulo" = Table.AddColumn(#"Added Index", "Modulo", each Number.Mod([Index], 4), type number),
//Compute QOQs -- (current row - previous row)/previous row (unless first row in the group in which case => null
#"Added Custom1" = Table.AddColumn(#"Inserted Modulo", "QoQ Imp", each if [Modulo]=0 then null
else ([Imp] - #"Inserted Modulo"[Imp]{[Index]-1}) / #"Inserted Modulo"[Imp]{[Index]-1}),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "QoQ %Eng", each if [Modulo]=0 then null
else ([#"% Eng"] - #"Inserted Modulo"[#"% Eng"]{[Index]-1}) / #"Inserted Modulo"[#"% Eng"]{[Index]-1}),
//remove now superfluous Index and Modulo columns and re-order the others
#"Removed Columns" = Table.RemoveColumns(#"Added Custom2",{"Index", "Modulo"}),
#"Reordered Columns" = Table.ReorderColumns(#"Removed Columns",{"Qtr", "Filter", "Imp", "QoQ Imp", "Eng", "% Eng", "QoQ %Eng"})
in
#"Reordered Columns"

Group by a SUM function in M power BI

In PowerQuery I try to sum the quantité livréeby BL 2 (i have several rows with the same BL2 number but i can't delete doublons, regarding of details of the data)
The data looks like:
I tried:
=Table.Group(#"Somme quantité livrée", {"BL 2"},{{"quantité livrée", each List.Sum([#"quantitée livrée"]), type number}}
but the function doesnt work, have the same error message "RightParen token excepted" but i don't see what should i do here (or even if its the right function to do what i except)
Basically i want to obtain the sum of the quantité livrée, quantité retournée, quantité facturée by distinct BL 2
Any idea?
I tried the Group By table proposed in answers but using it i lost others columns:
before:
And after:
Why not use the group interface to create the code for you?
#"Grouped Rows" = Table.Group(#"previous_step_name", {"BL 2"}, {{"quantité livrée", each List.Sum([quantité livrée]), type number}, {"quantité retournée", each List.Sum([quantité retournée]), type number}, {"quantité facturée", each List.Sum([quantité facturé]), type number}})
== == ==
If you want to retain other columns then in the group use an All Rows operation.
then after, expand desired columns back into table using arrows on top and slightly to right of the new column
== == ==
a totally different way to do this is just adding in three custom columns to sum ql, qr and qf based on BL2 of each row. It does NOT do any grouping, so for each BL combination you'd see the same total on each row
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source,"sum_ql",(i)=>List.Sum(Table.SelectRows(Source, each [bl 2]=i[bl 2]) [ql]), type number ),
#"Added Custom2"= Table.AddColumn(#"Added Custom" ,"sum_qr",(i)=>List.Sum(Table.SelectRows(#"Added Custom" , each [bl 2]=i[bl 2]) [qr]), type number ),
#"Added Custom3"= Table.AddColumn(#"Added Custom2" ,"sum_qf",(i)=>List.Sum(Table.SelectRows(#"Added Custom" , each [bl 2]=i[bl 2]) [qf]), type number )
in #"Added Custom3"

Calculated columns bases on the past 3 months in Power query

First time trying to use M in power query... what I have is this table
I need to create two columns that per each row (combination of CD_Loja x CD_Produto )returns me the sum of QT_VENDA for that combination divided by the # of days in the past 3 months. The other column is pretty much the same but with the sum of  VL_VENDA_LIQ  Instead.
I.e: For the first row I want to sum up all QT_VENDA that matches CD_PRODUTO =1001930 AND CD_LOJA = 151 in the past 3 months (the DATE column has daily data) and divide it by the number of days in those 3 months.
Is there a way to do so ? And how do I go about this ?
Thanks in advance.
In powerquery, M, something along these lines
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.Buffer(Table.TransformColumnTypes(Source,{{"DATA", type date}, {"CD_PRODUCTO", type text}, {"CD_LOIA", type text}, {"QT_VENDA", Int64.Type}, {"VL_VENDA_LIQ", Int64.Type}})),
#"Added Custom" = Table.AddColumn(#"Changed Type" ,"QT_VENDA_90",(i)=>List.Average(Table.SelectRows(#"Changed Type" , each [CD_PRODUCTO]=i[CD_PRODUCTO] and [CD_LOIA]=i[CD_LOIA] and [DATA] <= i[DATA] and [DATA] >= Date.AddDays(i[DATA] ,-90)) [QT_VENDA]), type number),
#"Added Custom2" = Table.AddColumn(#"Added Custom" ,"VL_VENDA_LIQ_90",(i)=>List.Average(Table.SelectRows(#"Changed Type" , each [CD_PRODUCTO]=i[CD_PRODUCTO] and [CD_LOIA]=i[CD_LOIA] and [DATA] <= i[DATA] and [DATA] >= Date.AddDays(i[DATA] ,-90)) [VL_VENDA_LIQ]), type number)
in #"Added Custom2"
You can try a Measure like below-
your_expected_value =
var current_row_data = MIN(your_table_name[DATA])
--I Guess the column name should be Date instead
var current_row_data_minus_90_day = MIN(your_table_name[DATA]) - 90
var current_row_cd_produto = MIN(your_table_name[CD_PRODUTO])
var current_row_cd_loja = MIN(your_table_name[CD_LOJA])
RETURN
CALCULATE(
SUM(your_table_name[QT_VENDA]),
FILTER(
ALL(your_table_name),
your_table_name[DATA] >= current_row_data_minus_90_day
&& your_table_name[DATA] <= current_row_data
&& your_table_name[CD_PRODUTO] = current_row_cd_produto
&& your_table_name[CD_LOJA] = current_row_cd_loja
)
)/90
--Here 90 used for static 3 month consideration