Forum Discussion
Excel data table - showing all dates between Start and End
- Apr 22, 2020
RobKelleher this can be done fairly easily with Power Query. You specified this was tagged with Power BI, so I'm assuming you at least know what it is and will detail how to do this below.
Create a query from your data (Data > From Table/Range). From there, just manipulate the data how you want. The key is going to be in the first step, which is to expand the table of data to include all dates from the start to the end date(s). An example of how this is done can be found https://www.poweredsolutions.co/2019/07/23/fill-dates-between-dates-with-power-bi-power-query/. Once you have that done, add additional columns so you can use them in pivot fields of a PivotTable. The M code would look something like the below code. This assumes your data (original table you posted at the top of your post) is named "tLeave". Column names were kept the same. It also assumes, for the 'Hours' column, that each day would be worth a value of 8 - a standard work day in the US. This is arbitrary at this point.
let Source = Excel.CurrentWorkbook(){[Name="tLeave"]}[Content], #"Changed Type" = Table.TransformColumnTypes(Source,{{"Start Date", Int64.Type}, {"End Date", Int64.Type}}), #"AddCartesian" = Table.AddColumn(#"Changed Type", "Dates", each {[Start Date]..[End Date]}), #"ExpandCartesian" = Table.ExpandListColumn(#"AddCartesian", "Dates"), #"TypeDate" = Table.TransformColumnTypes(#"ExpandCartesian",{{"Dates", type date}, {"End Date", type date}, {"Start Date", type date}}), #"AddDayOfWeek" = Table.AddColumn(#"TypeDate", "Weekday", each Date.DayOfWeek([Dates])), #"FilterWeekends" = Table.SelectRows(#"AddDayOfWeek", each ([Weekday] <> 5 and [Weekday] <> 6)), #"AddHours" = Table.AddColumn(#"FilterWeekends", "Hours", each 8), #"AddMonths" = Table.AddColumn(#"AddHours", "Month", each Date.Month([Dates])), #"AddMonthNames" = Table.AddColumn(#"AddMonths", "MonthName", each Date.MonthName([Dates])), #"AddYears" = Table.AddColumn(#"AddMonthNames", "Year", each Date.Year([Dates])) in #"AddYears"
Close and load to a PivotTable. In it, drag the 'Leave Type' to the Rows area, 'Dates' to the Values area, 'MonthName' to the Columns area, and 'Years' to the Columns area just above 'MonthName'. This output should look like what you're requesting. Clean up the PivotTable as desired.
I've made the adjustments in the sample file attached.
For your second stage, it gets a bit trickier. I'd have a look at these resources...
https://datachant.com/2017/04/13/calendar-with-working-days-power-bi/
https://wessexbi.wordpress.com/2016/02/26/uk-bank-holidays-in-power-query-easter/
https://www.mrexcel.com/board/threads/power-query-lookup-to-see-if-a-holiday-falls-within-a-work-week.1061454/
https://exceleratorbi.com.au/build-reusable-calendar-table-power-query/ (related ish)
http://www.cpearson.com/Excel/holidays.htm (for reference)
HTH
RobKelleher this can be done fairly easily with Power Query. You specified this was tagged with Power BI, so I'm assuming you at least know what it is and will detail how to do this below.
Create a query from your data (Data > From Table/Range). From there, just manipulate the data how you want. The key is going to be in the first step, which is to expand the table of data to include all dates from the start to the end date(s). An example of how this is done can be found https://www.poweredsolutions.co/2019/07/23/fill-dates-between-dates-with-power-bi-power-query/. Once you have that done, add additional columns so you can use them in pivot fields of a PivotTable. The M code would look something like the below code. This assumes your data (original table you posted at the top of your post) is named "tLeave". Column names were kept the same. It also assumes, for the 'Hours' column, that each day would be worth a value of 8 - a standard work day in the US. This is arbitrary at this point.
let
Source = Excel.CurrentWorkbook(){[Name="tLeave"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Start Date", Int64.Type}, {"End Date", Int64.Type}}),
#"AddCartesian" = Table.AddColumn(#"Changed Type", "Dates", each {[Start Date]..[End Date]}),
#"ExpandCartesian" = Table.ExpandListColumn(#"AddCartesian", "Dates"),
#"TypeDate" = Table.TransformColumnTypes(#"ExpandCartesian",{{"Dates", type date}, {"End Date", type date}, {"Start Date", type date}}),
#"AddDayOfWeek" = Table.AddColumn(#"TypeDate", "Weekday", each Date.DayOfWeek([Dates])),
#"FilterWeekends" = Table.SelectRows(#"AddDayOfWeek", each ([Weekday] <> 5 and [Weekday] <> 6)),
#"AddHours" = Table.AddColumn(#"FilterWeekends", "Hours", each 8),
#"AddMonths" = Table.AddColumn(#"AddHours", "Month", each Date.Month([Dates])),
#"AddMonthNames" = Table.AddColumn(#"AddMonths", "MonthName", each Date.MonthName([Dates])),
#"AddYears" = Table.AddColumn(#"AddMonthNames", "Year", each Date.Year([Dates]))
in
#"AddYears"
Close and load to a PivotTable. In it, drag the 'Leave Type' to the Rows area, 'Dates' to the Values area, 'MonthName' to the Columns area, and 'Years' to the Columns area just above 'MonthName'. This output should look like what you're requesting. Clean up the PivotTable as desired.
I've made the adjustments in the sample file attached.
For your second stage, it gets a bit trickier. I'd have a look at these resources...
https://datachant.com/2017/04/13/calendar-with-working-days-power-bi/
https://wessexbi.wordpress.com/2016/02/26/uk-bank-holidays-in-power-query-easter/
https://www.mrexcel.com/board/threads/power-query-lookup-to-see-if-a-holiday-falls-within-a-work-week.1061454/
https://exceleratorbi.com.au/build-reusable-calendar-table-power-query/ (related ish)
http://www.cpearson.com/Excel/holidays.htm (for reference)
HTH
Thanks for this. Very elegant and logical solution.
This defo meets the expectations I had in my head for what must be a common date problem.
Very much appreciated