Net Work Days
Recreates the NETWORKDAYS function from Excel with some bonus measures and one that needs fixed or demonstrates a bug/documentation glitch.
NetWorkDays calculates the number of days between two dates sans weekends.
NetWorkDays = VAR Calendar1 = CALENDAR(MAX(NetWorkDays[created date]),MAX(NetWorkDays[review date])) VAR Calendar2 = ADDCOLUMNS(Calendar1,"WeekDay",WEEKDAY([Date],2)) RETURN COUNTX(FILTER(Calendar2,[WeekDay]<6),[Date])
DaysHoursMinutes provides a nice display format for the number of days, hours and minutes between two dates
DaysHoursMinutes = DATEDIFF(MAX(NetWorkDays[created date]),MAX(NetWorkDays[review date]),DAY)
& " Days " & HOUR(MOD(MAX(NetWorkDays[review date]) - MAX(NetWorkDays[created date]),1))
& " Hours " & MINUTE(MOD(MAX(NetWorkDays[review date]) - MAX(NetWorkDays[created date]),1)) & " Minutes"
NetWorkDaysHoursMinutes displays net work days in a nice display format
NetWorkDaysHoursMinutes =
VAR Calendar1 = CALENDAR(MAX(NetWorkDays[created date]),MAX(NetWorkDays[review date]))
VAR Calendar2 = ADDCOLUMNS(Calendar1,"WeekDay",WEEKDAY([Date],2))
RETURN COUNTX(FILTER(Calendar2,[WeekDay]<6),[Date]) & " Days " &
HOUR(MOD(MAX(NetWorkDays[review date]) - MAX(NetWorkDays[created date]),1)) & " Hours "
& MINUTE(MOD(MAX(NetWorkDays[review date]) - MAX(NetWorkDays[created date]),1)) & " Minutes"
Finally, this one tries incorporates holidays. While the documentation indicates that you can use DATE, you cannot. But the following code does work to remove December 25th as a work day.
NetWorkDaysHolidays =
VAR Calendar1 = CALENDAR(MAX(NetWorkDays[created date]),MAX(NetWorkDays[review date]))
//VAR Holidays = DATATABLE("Date",DATETIME,{{}})
VAR Holidays1 = DATATABLE("Date",DATETIME,
{
{"12/25/2017 12:00:00 AM"}
})
VAR Calendar2 = EXCEPT(Calendar1,Holidays1)
VAR Calendar3 = ADDCOLUMNS(Calendar2,"WeekDay",WEEKDAY([Date],2))
RETURN COUNTX(FILTER(Calendar3,[WeekDay]<6),[Date])
Finally, finally, this one is Holidays with days, hours and mintues:
NetWorkDaysHolidaysDaysHoursMinutes =
VAR Calendar1 = CALENDAR(MAX(NetWorkDays[created date]),MAX(NetWorkDays[review date]))
//VAR Holidays = DATATABLE("Date",DATETIME,{{}})
VAR Holidays1 = DATATABLE("Date",DATETIME,
{
{"12/25/2017 12:00:00 AM"}
})
VAR Calendar2 = EXCEPT(Calendar1,Holidays1)
VAR Calendar3 = ADDCOLUMNS(Calendar2,"WeekDay",WEEKDAY([Date],2))
RETURN COUNTX(FILTER(Calendar3,[WeekDay]<6),[Date]) & " Days " &
HOUR(MOD(MAX(NetWorkDays[review date]) - MAX(NetWorkDays[created date]),1)) & " Hours "
& MINUTE(MOD(MAX(NetWorkDays[review date]) - MAX(NetWorkDays[created date]),1)) & " Minutes"
eyJrIjoiYjFhNWIwMmMtMTlhOC00YjNkLTlmNmMtMGYxMjcwOWQzZWRkIiwidCI6IjRhMDQyNzQzLTM3M2EtNDNkMi04MjdiLTAwM2Y0YzdiYTFlNSIsImMiOjN9
34 Replies
- GonzaloSNew Member
What if I have some empty fields?
In my query the "review date" for ongoing item is blank. and this measure provide gives me an error.
I don't wan't to filther them out. I still want to show all row in my dashboard.
Thank you in advance.
Regards
- EmanuelHelper I
Greg_Deckler I am trying to add x number of working days to the create date in order to get the review date. Any ideas how can I do that?
The specific requirement is:
for priority 1 add 5 working days, for P2 add 10 working days for P3&4 add 20 working days.
Thank you
- Greg_DecklerCommunity Champion
Emanuel Hmm, maybe something like:
Measure = VAR __AddDays = SWITCH(MAX('Table'[Priority]), "P1",5, "P2",10, 20 ) VAR __CreatedDate = MAX('Table'[created date]) VAR __Calendar1 = CALENDAR(MAX(__CreatedDate+1,__CreatedDate+30) VAR __Calendar2 = ADDCOLUMNS(__Calendar1,"WeekDay",WEEKDAY([Date],2)) VAR __Calendar3 = FILTER(__Calendar2,[WeekDay]<6),[Date]) VAR __Set = TOPN(__AddDays,__Calendar3,[Date],1) RETURN MAXX(__Set,[Date])- AnonymousNot applicable
Hi Greg_Deckler , opening this thread. I have this same scenario, however, I need to exclude weekends. May I ask for your inputs/help on this? Thank you.
- BachFelHelper II
Thanks for your help,
NetWorkDays =
VAR Calendar1 = CALENDAR(MAX(KontElemente[Datum der Besichtigung]);MAX(today())I didn´d understand the part.
VAR Calendar2 = ADDCOLUMNS(Calendar1,"WeekDay",WEEKDAY([Date],2))
RETURN COUNTX(FILTER(Calendar2,[WeekDay]<6),[Date])Can u help me out?
- Greg_DecklerCommunity Champion
If you are referring to the VAR Calendar2 part, what that does is adds a column to the temp calendar table using the WEEKDAY function with the parameter 2, which essentially codes things M=1, T=2, W=3, Th=4, F=5, Sa=6, Su=7. So, the next step, the RETRUN filters out anything 6 or 7 to exclude Saturdays and Sundays.
- BachFelHelper II
It´s not working. Guess I´m the problem and not the formula
- AnonymousNot applicable
Very nice scripts, but what if I want to aggregate the network days by another column from the NetWorkDays table?
Eg. if I add a "Name" column to the NetWorkDays table and add John and Jane Doe and one more row:
When using the NetWorkDays measure it works on a row by row level, but if I try to aggregate by the 'Name' column the measure seems to be incorrect:
Any idea why and how to fix it?
I have included the modified PBIX file.
- AnonymousNot applicable
Hi Greg, i am using a direct query and it throws up an error saying countx is not allowed as part of calculated columns dax expressions on Direct Query Mode.. Please Help!!!!
- Greg_DecklerCommunity Champion
Are you sure you are using the formula in a measure and not in a Column? According to this article, COUNTX should work in a measure:
- AnonymousNot applicable
Hi Greg,
I am definatly using a measure!
Below is the Error Message:
MdxScript(Model) (189, 17) Calculation error in measure 'fact_CRM_Incident'[Business Days Active]: The start date in Calendar function can not be later than the end date.
I would like to also reference my holiday flag column which is a Yes/No field in my dim_date table.On another note the Closed on date column contains blanks if a ticket is in an "active" or Open state in which case the business days calc should continue to count till current day until a closed date is added in the dataset.
Appreciate the help mate.
- AnonymousNot applicable
Is there a way to calculate difference between Today() and a given date?
- Greg_DecklerCommunity Champion
Anonymous - Sure, you could do something like this:
NetWorkDays = VAR Calendar1 = CALENDAR(TODAY(),[Any Given Date]) VAR Calendar2 = ADDCOLUMNS(Calendar1,"WeekDay",WEEKDAY([Date],2)) RETURN COUNTX(FILTER(Calendar2,[WeekDay]<6),[Date])
If necessary, reverse the parameters for the CALENDAR function.
- AnonymousNot applicable
Thanks Greg_Deckler this works like a charm.
- JadnerbFrequent Visitor
Based on your "NetWorkDaysHoursMinutes"
I tried using MAX(TODAY()) but it didn't work, I used MIN and MAX. However, I am getting text (Days Hours Minutes) and cannot change the format to whole number.
- AnonymousNot applicable
Greg_Deckler I tried using your formula early on, but it would not allow me since I have some Ship Dates that start before Due Date. The error message said the formula could not allow for that.
- Greg_DecklerCommunity Champion
Oh, that would be the CALENDAR function. You would just have to create an IF statement to check which date is larger or smaller and then create your CALENDAR appropriately. Like this:
NetWorkDays = VAR __CreatedDate = MAX(NetWorkDays[created date]) VAR __ReviewDate= MAX(NetworkDays[review date]) VAR Calendar1 = IF( __CreatedDate < __ReviewDate, CALENDAR(__CreatedDate,__ReviewDate), CALENDAR(__ReviewDate,__CreatedDate), ) VAR Calendar2 = ADDCOLUMNS(Calendar1,"WeekDay",WEEKDAY([Date],2)) RETURN COUNTX(FILTER(Calendar2,[WeekDay]<6),[Date])
- AnonymousNot applicable
This is a great solution.
just wondering if it is possible to pull this detail from a separate table where we can enter public holidays by year?VAR Holidays1 = DATATABLE("Date",DATETIME, { {"12/25/2017 12:00:00 AM"} })for e.g. a table will hold Public holidays like this:
Holidays date
01/01/2020 25/12/2020 01/01/2021 25/12/2021 26/12/2021 - AnonymousNot applicable
Anonymous Greg_Deckler Any luck on how to you use a list of holiday list please...
- Greg_DecklerCommunity Champion
Anonymous - I have an updated version of this in my book DAX Cookbook from Packt. If you just want the code, check out Chapter 7, Recipe 10 - https://github.com/gdeckler/DAXCookbook
- AnonymousNot applicable
Hi, This is really an amazing post. I need help in ignoring a list of dates in my holiday table. I can see that you have ignored 25th Dec for calculating the network days. But if I have a list of dates in my holiday table how to use that in your code. Please help.
And I just need the count in days only.
- juncco888Advocate I
Thanks for these measures... They have been bery useful. I have a Holiday Table that has a date column for all of the holidays. Is there a way to reference that column and have it add the dates to the Holidays1 variable in this holiday measure:
NetWorkDaysHolidaysDaysHoursMinutes = VAR Calendar1 = CALENDAR(MAX(NetWorkDays[created date]),MAX(NetWorkDays[review date])) //VAR Holidays = DATATABLE("Date",DATETIME,{{}}) VAR Holidays1 = DATATABLE("Date",DATETIME, { {"12/25/2017 12:00:00 AM"} }) VAR Calendar2 = EXCEPT(Calendar1,Holidays1) VAR Calendar3 = ADDCOLUMNS(Calendar2,"WeekDay",WEEKDAY([Date],2)) RETURN COUNTX(FILTER(Calendar3,[WeekDay]<6),[Date]) & " Days " &
HOUR(MOD(MAX(NetWorkDays[review date]) - MAX(NetWorkDays[created date]),1)) & " Hours "
& MINUTE(MOD(MAX(NetWorkDays[review date]) - MAX(NetWorkDays[created date]),1)) & " Minutes"