Forum Discussion
How to calculate dates using start and end date distribute per month
- 3 years ago
OK, here is a method using Power Query M Code (which I just happened to develop earlier for a similar problem).
Home =>Trnasform data=>Advanced Editor and paste the code into the window that opens (deleting whatever might be there)
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUTLUN9I3MjAyAjONYUy/1HKFyPyibKVYHZgyU5hcXmlODroSkDjQHLhRQIY5jB2Sn52ZD1dljKTKBImNqgooA7fPXB9dUSwA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [IncidentID = _t, #"Lost work start" = _t, #"lost work end" = _t, Location = _t]), #"Changed Type" = Table.TransformColumnTypes(Source,{{"IncidentID", Int64.Type}, {"Lost work start", type date}, {"lost work end", type date}, {"Location", type text}}), //Create all months list #"Last Day" = Date.From(DateTime.FixedLocalNow()), #"all Dates" = List.Dates( List.Min(#"Changed Type"[Lost work start]), Duration.Days(#"Last Day"-List.Min(#"Changed Type"[Lost work start])) + 1, #duration(1,0,0,0)), #"all MnthYr" = List.Distinct(List.Transform(#"all Dates", each Date.ToText(_,"yyyy-MM"))), //List of Dates for each row #"Days per Month" = Table.AddColumn(#"Changed Type", "Dates List", each let LWD = List.Dates( [Lost work start], Duration.Days(List.Min({[lost work end], #"Last Day"}) - [Lost work start]) + 1, #duration(1,0,0,0)), MnthYr = List.Transform(LWD, each Date.ToText(_,"yyyy-MM")), //Group by MnthYr and count Group = Table.Group(Table.FromColumns({MnthYr} & {LWD}),{"Column1"},{ {"Days in Month", each Table.RowCount(_), Int64.Type}}), Pivot = Table.Pivot(Group,List.Sort(Group[Column1]),"Column1","Days in Month") in Pivot), #"Expanded Dates List" = Table.ExpandTableColumn(#"Days per Month", "Dates List", #"all MnthYr"), #"Sort Month/Year Columns" = let colsToSort = List.RemoveFirstN(Table.ColumnNames(#"Expanded Dates List"),4), #"Sorted Order" = List.Sort(colsToSort), #"Reorder Columns" = Table.ReorderColumns(#"Expanded Dates List",#"Sorted Order") in #"Reorder Columns", #"Month To Name" = Table.RenameColumns(#"Sort Month/Year Columns", List.Transform(List.RemoveFirstN(Table.ColumnNames(#"Sort Month/Year Columns"),4), each{_, Date.ToText(Date.From(_),"MMM-yy")})), #"Grouped Rows1" = Table.Group(#"Month To Name", {"Location"}, { //Sum each month {"Sum Each Month", (t)=> Record.FromList( List.Accumulate(List.RemoveFirstN(Table.ColumnNames(t),4),{}, (a,b)=> a & {List.Sum(Table.Column(t,b))}), List.RemoveFirstN(Table.ColumnNames(t),4)) }}), #"Expanded Sum Each Month" = Table.ExpandRecordColumn(#"Grouped Rows1", "Sum Each Month", List.RemoveFirstN(Table.ColumnNames(#"Month To Name"),4)), #"Typed" = Table.TransformColumnTypes(#"Expanded Sum Each Month", List.Transform(List.RemoveFirstN(Table.ColumnNames(#"Expanded Sum Each Month")), each {_, Int64.Type})) in #"Typed"Results:
My bad. You are right. It should be 29 days fir incident 2. End date should be calculated based on current month - 1 calendar months for last 12 months.
OK, here is a method using Power Query M Code (which I just happened to develop earlier for a similar problem).
Home =>Trnasform data=>Advanced Editor and paste the code into the window that opens (deleting whatever might be there)
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUTLUN9I3MjAyAjONYUy/1HKFyPyibKVYHZgyU5hcXmlODroSkDjQHLhRQIY5jB2Sn52ZD1dljKTKBImNqgooA7fPXB9dUSwA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [IncidentID = _t, #"Lost work start" = _t, #"lost work end" = _t, Location = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"IncidentID", Int64.Type}, {"Lost work start", type date}, {"lost work end", type date}, {"Location", type text}}),
//Create all months list
#"Last Day" = Date.From(DateTime.FixedLocalNow()),
#"all Dates" =
List.Dates(
List.Min(#"Changed Type"[Lost work start]),
Duration.Days(#"Last Day"-List.Min(#"Changed Type"[Lost work start])) + 1,
#duration(1,0,0,0)),
#"all MnthYr" = List.Distinct(List.Transform(#"all Dates", each Date.ToText(_,"yyyy-MM"))),
//List of Dates for each row
#"Days per Month" = Table.AddColumn(#"Changed Type", "Dates List", each
let
LWD =
List.Dates(
[Lost work start],
Duration.Days(List.Min({[lost work end], #"Last Day"}) - [Lost work start]) + 1,
#duration(1,0,0,0)),
MnthYr = List.Transform(LWD, each Date.ToText(_,"yyyy-MM")),
//Group by MnthYr and count
Group = Table.Group(Table.FromColumns({MnthYr} & {LWD}),{"Column1"},{
{"Days in Month", each Table.RowCount(_), Int64.Type}}),
Pivot = Table.Pivot(Group,List.Sort(Group[Column1]),"Column1","Days in Month")
in
Pivot),
#"Expanded Dates List" = Table.ExpandTableColumn(#"Days per Month", "Dates List", #"all MnthYr"),
#"Sort Month/Year Columns" =
let
colsToSort = List.RemoveFirstN(Table.ColumnNames(#"Expanded Dates List"),4),
#"Sorted Order" = List.Sort(colsToSort),
#"Reorder Columns" = Table.ReorderColumns(#"Expanded Dates List",#"Sorted Order")
in
#"Reorder Columns",
#"Month To Name" = Table.RenameColumns(#"Sort Month/Year Columns",
List.Transform(List.RemoveFirstN(Table.ColumnNames(#"Sort Month/Year Columns"),4), each{_, Date.ToText(Date.From(_),"MMM-yy")})),
#"Grouped Rows1" = Table.Group(#"Month To Name", {"Location"}, {
//Sum each month
{"Sum Each Month", (t)=> Record.FromList(
List.Accumulate(List.RemoveFirstN(Table.ColumnNames(t),4),{}, (a,b)=>
a & {List.Sum(Table.Column(t,b))}), List.RemoveFirstN(Table.ColumnNames(t),4))
}}),
#"Expanded Sum Each Month" = Table.ExpandRecordColumn(#"Grouped Rows1", "Sum Each Month",
List.RemoveFirstN(Table.ColumnNames(#"Month To Name"),4)),
#"Typed" = Table.TransformColumnTypes(#"Expanded Sum Each Month",
List.Transform(List.RemoveFirstN(Table.ColumnNames(#"Expanded Sum Each Month")), each {_, Int64.Type}))
in
#"Typed"Results:
- beginner3 years ago
Helper I
Thank very much for your reply. I would like to understand what to put here if I am using sharepoint as data source. I am not familiar with this syntax.
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUTLUN9I3MjAyAjONYUy/1HKFyPyibKVYHZgyU5hcXmlODroSkDjQHLhRQIY5jB2Sn52ZD1dljKTKBImNqgooA7fPXB9dUSwA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [IncidentID = _t,- ronrsnfld3 years ago
Super User
Source refers to data that I pasted into a Power BI table.
You would replace it with the appropriate sharepoint connection line.
- beginner3 years ago
Helper I
This is lifesaver. Thanks a lot! Your rock.
- ronrsnfld3 years ago
Super User
You are welcome. Please note that I assumed Today would be the last day to be considered, thinking that tomorrow would not be counted as a lost work day. If you really want to count the last day this month as the last day to be considered, then change the line
#"Last Day" = Date.From(DateTime.FixedLocalNow()),to reflect the end of the month
#"Last Day" = Date.EndOfMonth(Date.From(DateTime.FixedLocalNow())), - ronrsnfld3 years ago
Super User
Another undefined scenario is what to happen if there are overlapping dates for different rows of the same incident. As written, a single date will be counted as multiple lost work days if it occurs on separate rows of the same location.
- beginner3 years ago
Helper I
ronrsnfld @You mean below will not work? There will be one incident per mm/dd/yyyy. I was not sure what you meant by overlapping days. Do you mind explaining with a simple example? I am always counting previous month so I think today's date will be always fine. Thanks
1 1/2/2022 1/3/2022 New York 2 1/2/2022 1/4/2022 New York