Power Query M - Custom Column for Rolling 28 Days Sales - powerquery

I'm looking for some Power Query help. I have a huge set of sales data for 40k products over one year. For each product on each day I need to add a 28 day sales column.
I essentially want to do a sumifs like the below but in M.
=SUMIFS([SALES],[Product Code],[This Product Code],[Date],<=[This Date],[Date],>=[This Date]-28))

Try this then, it should work but would likely do so at a crawl
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Sales", Int64.Type}, {"Product Code", type text}, {"Date", type date}}),
TotalAmountAdded = Table.AddColumn(Source, "Total Amount", (i) => List.Sum(Table.SelectRows(Source, each ([Product Code] = i[Product Code] and [Date]<=i[Date] and [Date]>=Date.AddDays(i[Date],-28)))[Sales]), type number )
in TotalAmountAdded

Add a custom column with date logic (based on your sample sumif formula), filter the new column to get the relevant rows, then group by product code and sum Sales. Assuming source data is in Table1 with three columns (Sales,Product Code, Date) the code would be
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Sales", Int64.Type}, {"Product Code", type text}, {"Date", type date}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "AddMe", each if [Date]<=DateTime.Date(DateTime.LocalNow()) and [Date]>=Date.AddDays(DateTime.Date(DateTime.LocalNow()),-28) then 1 else 0),
#"Filtered Rows" = Table.SelectRows(#"Added Custom", each ([AddMe] = 1)),
#"Grouped Rows" = Table.Group(#"Filtered Rows", {"Product Code"}, {{"ProductSales", each List.Sum([Sales]), type number}})
in #"Grouped Rows"

Related

Power BI calcualte the variance between two rows of table data

first time caller long time listener. I'm trying to work out the variance for each row of a table of data for my local junior tiathlon club. I need to work out the difference of time in a particular event since the previous date to know if they have improved or not. e.g. if a student only runs for two days and these are recorded as rows, how can i add a column to calculate if they are faster or slower? The data is below and the final column illustrates what i need. You'll see that the variance resets to 0 for each category. I'm trying to do this in Power BI DEsktop in the tables as an added column so i can use the data against a matrix table report.
Put simply, how can i measure the time in the current row against the time in the previous row>
Thanks in advance, Moe
Try
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
// might need to replace replace Excel.CurrentWorkbook with Excel.WorkBook for Power BI
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Name", type text}, {"Event", type text}, {"Category", type any}, {"Date", type date}, {"Time", type time}}),
#"Grouped Rows" = Table.Group(#"Changed Type", {"Name", "Event"}, {
{"data", each
let a=Table.AddIndexColumn(Table.Sort(_,{{"Date", Order.Ascending}, {"Time", Order.Ascending}}), "index", 0, 1, Int64.Type) ,
b=Table.AddColumn(a,"diff", each try Duration.ToText(a{[index]}[Time] - a{[index]-1}[Time]) otherwise 0)
in b, type table }}),
#"Expanded data" = Table.ExpandTableColumn(#"Grouped Rows", "data", {"Category", "Date", "Time", "diff"}, {"Category", "Date", "Time", "diff"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Expanded data",{{"Date", type date}, {"Time", type time}})
in #"Changed Type1"

Power Query: Duplicate Rows Based on Value

I have a column that contains the Total Stock of an item. I'd like to expand this out into 1 row per item (i.e. the item has 6 in stock and therefore appears as 6 line items).
Is this possible with power query?
The M-Code below will expand this input table
to this
let
Source = Excel.CurrentWorkbook(){[Name="tblData"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ColA", type text}, {"Stock", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Col", each List.Repeat({[ColA]},[Stock])),
#"Expanded Col" = Table.ExpandListColumn(#"Added Custom", "Col")
in
#"Expanded Col"

Power Query transform a table with date ranges into daily

I am using Power Query to solve the following problem:
need to create a daily split of data based on a range of dates.
I have a table with ad campaign results. Each line is a campaign with Index as ID. It has a start date, end date (or a duration) and some numeric fields, in this case AdRequests and Spend.
For each line, it's a total for the number days in Duration column.
What I need to do is un-summarise this into daily data. Populate a daily data out of it with values of spend etc being a daily average. N.B. number of campaigns varies from project to project, it needs to be dynamic
i.e. this is my input table
and here is what i want it to be. This is example for 1st campaign only, but the table needs to have all of them, and that varies from project to project.
I have to deliver this tomorrow, and so far my search hasn't yielded anything remotely good.
thank you for any ideas, in advance
Here's how I did it.
Add a custom column with the formula = {1..[Duration]}
Expand the custom column
Change start date to number type
Add a custom column with the formula = [Start Date] + [Custom] -1
Change start date back to a date type column
Delete unnecessary columns
Rename columns
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Index", Int64.Type}, {"Start Date", type datetime}, {"Ad Requests", Int64.Type}, {"Spend", Int64.Type}, {"Duration", Int64.Type}, {"Daily Adrequests", Int64.Type}, {"Daily Spend", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each {1..[Duration]}),
#"Expanded Custom" = Table.ExpandListColumn(#"Added Custom", "Custom"),
#"Changed Type1" = Table.TransformColumnTypes(#"Expanded Custom",{{"Start Date", Int64.Type}}),
#"Added Custom1" = Table.AddColumn(#"Changed Type1", "Custom.1", each [Start Date] + [Custom] -1),
#"Changed Type2" = Table.TransformColumnTypes(#"Added Custom1",{{"Custom.1", type date}}),
#"Reordered Columns" = Table.ReorderColumns(#"Changed Type2",{"Index", "Custom.1", "Start Date", "Ad Requests", "Spend", "Duration", "Daily Adrequests", "Daily Spend", "Custom"}),
#"Removed Columns" = Table.RemoveColumns(#"Reordered Columns",{"Start Date", "Ad Requests", "Spend", "Duration"})
in
#"Removed Columns"
Before/After

Keeping the last row in a month and year for a particular group

I have a table which contains roughly 30 columns. One of the columns is "Date" and one is "Project Code". For each project code, there could be multiple entries in the table for a given month and year. For example, for project code "ABC" there could be multiple entries for February, 2020. Each would have a different date (i.e, 20200202, 20200209, 20200216, 20200223, 20200229)
In Power Query, I'd like to perform a transformation step that includes only those rows that represent the last entry for a month and year, for each project code. Using the example above, I want a single row for project "ABC", for February, 2020, and it would be for the date of 20200229.
I immediately looked at Group By but I don't think I'm going to be able to do what I want using Group By.
You need to do something along these lines
Assuming column Date is formatted as a date then ...
Add a column to pull out the month using
= Date.Month([Date])
Add a column to pull out the year using
= Date.Year([Date])
Add a column that finds the maximum date from all the rows with matching (Group, Month, Year)
= Table.AddColumn(#"PriorStep","MaxDate",(i)=>List.Max(Table.SelectRows(#"PriorStep", each [Project Code]=i[Project Code] and [Month]=i[Month] and [Year]=i[Year]) [Date]), type date )
Add a column to compare current date to that maximum date
=if [Date]=[MaxDate] then "keep" else "remove"
Remove the rows that don't match by filtering
Remove the extra columns
Sample code below
let Source = Excel.CurrentWorkbook(){[Name="Table5"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Project Code", type text}, {"Date", type date}}),
#"Added Custom2" = Table.AddColumn(#"Changed Type", "Month", each Date.Month([Date])),
#"Added Custom3" = Table.AddColumn(#"Added Custom2", "Year", each Date.Year([Date])),
#"Added Custom" = Table.AddColumn(#"Added Custom3","MaxDate",(i)=>List.Max(Table.SelectRows(#"Added Custom3", each [Project Code]=i[Project Code] and [Month]=i[Month] and [Year]=i[Year]) [Date]), type date ),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Match", each if [Date]=[MaxDate] then "keep" else "remove"),
#"Filtered Rows" = Table.SelectRows(#"Added Custom1", each ([Match] = "keep")),
#"Removed Columns" = Table.RemoveColumns(#"Filtered Rows",{"MaxDate", "Match","Month","Year"})
in #"Removed Columns"
With Table.Group:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("TcwxCsAwDEPRu3jOIMkxScf2GiH3v0Y9uDRgLY+P1zJByJM1u3MEbLdiEsVRyAvS/Nr4U2mUej8eOEvVzzZSntz0Q8FSDtv7BQ==", BinaryEncoding.Base64), Compression.Deflate)), {"Date","Project","SomeData"}),
types = Table.TransformColumnTypes(Source,{{"Date", Int64.Type}, {"Project", type text}, {"SomeData", Int64.Type}}),
year = Table.AddColumn(types, "year", each Number.RoundDown([Date]/10000)),
month = Table.AddColumn(year, "month", each Number.RoundDown(Number.Mod([Date],10000)/100)),
day = Table.AddColumn(month, "day", each Number.Mod([Date],100)),
group = Table.Group(day, {"Project", "year", "month"}, {"temp", each Table.FirstN(Table.Sort(_,{"day",1}),1)}),
combine = Table.Combine(group[temp])
in
combine
Initial data:
Result:

Power query column editing

I have a table in power bi query with dates
01.01.2020
02.01.2020
and so on..
I need to duplicate this table and replace values 01.01.2020 into 20200101 and so on. Is there an obvious, easy way for this?
First option:
Here is the simplest option I found:
Create a custom column and apply "Text.Reverse" to your column
Create a custom column and apply to the newly created "Text.Remove" for "." which will remove the "." of your string.
Here is what you will get, with "reverse date" as your column in the reverse order, and "reverse date without point" as the second column without the point.
Here is the M code:
#"Promoted Headers" = Table.PromoteHeaders(Sheet2_Sheet, [PromoteAllScalars=true]),
#"Changed Type3" = Table.TransformColumnTypes(#"Promoted Headers",{{"Date", type text}}),
#"Added Custom3" = Table.AddColumn(#"Changed Type3", "reverse date", each Text.Reverse([Date])),
#"Added Custom4" = Table.AddColumn(#"Added Custom3", "reverse date witout point", each Text.Remove([reverse date], {"."}))
Second option:
Here is a second option, which is longer:
Break down your column in three distinct columns with "." as delimiter
Add new columns with padding zero to day and months (I called them "month with zero" and "day with zero")
Concatenate
and you get you result!
Here is my starting point:
Here is the first step, "breaking the column" in "columns":
Here is the custom column with zero padding:
Here is how you concatenate:
Here is the M code:
#"Split Column by Delimiter" = Table.SplitColumn(#"Promoted Headers", "Date", Splitter.SplitTextByDelimiter(".", QuoteStyle.Csv), {"Date.1", "Date.2", "Date.3"}),
#"Changed Type" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Date.1", Int64.Type}, {"Date.2", Int64.Type}, {"Date.3", Int64.Type}}),
#"Changed Type1" = Table.TransformColumnTypes(#"Changed Type",{{"Date.1", type text}, {"Date.2", type text}}),
#"Renamed Columns" = Table.RenameColumns(#"Changed Type1",{{"Date.1", "Day"}, {"Date.2", "Month"}, {"Date.3", "Year"}}),
#"Added Custom" = Table.AddColumn(#"Renamed Columns", "Month with zero", each Text.PadStart(Text.From([Month]),2,"0")),
#"Added Custom2" = Table.AddColumn(#"Added Custom", "Day with zero", each Text.PadStart(Text.From([Day]),2,"0")),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom2",{"Day", "Month"}),
#"Changed Type2" = Table.TransformColumnTypes(#"Removed Columns",{{"Year", type text}}),
#"Added Custom1" = Table.AddColumn(#"Changed Type2", "New Date", each [Year] & [Month with zero] & [Day with zero])
in
#"Added Custom1"

Resources