Forum Discussion
NEtwork Days M language
- 6 years ago
Hello
I tried to speed up my version. so if you have no performance issue with this solution, I would go for it.
This solution is slower af the other proposed Anonymous . But if we come to include holiday it's faster
// fnNetWorkDays (DateStart as date, DateEnd as date, optional Holidays as list) => let Switch = DateStart > DateEnd, StartDate = if Switch then DateEnd else DateStart, EndDate = if Switch then DateStart else DateEnd, WeekDaysInRange= ( Duration.TotalDays ( ( EndDate- ( StartDate +Duration.From ( Date.DayOfWeek ( EndDate ) -Date.DayOfWeek ( StartDate ) ) ) ) ) /7*5 ) +Date.DayOfWeek ( EndDate ) -Date.DayOfWeek ( StartDate ) +1 + ( if Date.DayOfWeek ( StartDate )=0 then -1 else 0 ) + ( if Date.DayOfWeek ( EndDate )=6 then -1 else 0 ), HolidaysInRange = if Holidays = null then {} else List.Select(Holidays, each StartDate <= _ and _ <= EndDate and Date.DayOfWeek(_, Day.Monday) <5 ), Result = (if Switch then -1 else 1) * ((WeekDaysInRange) - List.Count(HolidaysInRange)) in Result // fnNetWorkDays2 (DateStart as date, DateEnd as date, optional Holidays as list) => let Switch = DateStart > DateEnd, StartDate = if Switch then DateEnd else DateStart, EndDate = if Switch then DateStart else DateEnd, HolidayIntern = if Holidays = null then List.Buffer({}) else List.Buffer(Holidays), CreateListDates =List.Buffer( List.Dates ( StartDate, Duration.TotalDays ( EndDate - StartDate ) +1, #duration(1,0,0,0) )), ExcludeWeekend = List.Select ( CreateListDates, each Date.DayOfWeek ( _, Day.Monday ) <5 ), ExcludeHoliday = if Holidays = null then ExcludeWeekend else List.Difference ( ExcludeWeekend, HolidayIntern ), Result = List.Count ( ExcludeHoliday ), FinalResult = try (if Switch then -1 else 1) * (Result) otherwise null in FinalResultIf this post helps or solves your problem, please mark it as solution.
Kudos are nice to - thanks
Have fun
Jimmy - 6 years ago
Hey
I was just now that i posted both version.. and this confused you 🙂 sorry 🙂
// fnNetWorkDays2 (DateStart as date, DateEnd as date, optional Holidays as list) => let Switch = DateStart > DateEnd, StartDate = if Switch then DateEnd else DateStart, EndDate = if Switch then DateStart else DateEnd, HolidayIntern = if Holidays = null then List.Buffer({}) else List.Buffer(Holidays), CreateListDates =List.Buffer( List.Dates ( StartDate, Duration.TotalDays ( EndDate - StartDate ) +1, #duration(1,0,0,0) )), ExcludeWeekend = List.Select ( CreateListDates, each Date.DayOfWeek ( _, Day.Monday ) <5 ), ExcludeHoliday = if Holidays = null then ExcludeWeekend else List.Difference ( ExcludeWeekend, HolidayIntern ), Result = List.Count ( ExcludeHoliday ), FinalResult = try (if Switch then -1 else 1) * (Result) otherwise null in FinalResultinvoke it like this
=try fn([Start],[End]) otherwise null
If this post helps or solves your problem, please mark it as solution.
Kudos are nice to - thanks
Have fun
Jimmy - 6 years ago
😪ğŸ˜
oooh. .how sad
Hi again,
i played with this and saw that i have sum null values in startDate, i replace it with 01/01/01 01:00:00 it seems worked but now i think i have some problem with holidays, i see that this calculion takes a lot of time and see strange message (attached) and this gigabytes is continue to growing up
The function below takes a different approach to the issue. It should be fast and small because it does not generate dates.
(DateStart as date, DateEnd as date, optional Holidays as list) =>
let
Switch = DateStart > DateEnd,
StartDate = if Switch then DateEnd else DateStart,
EndDate = if Switch then DateStart else DateEnd,
WeekDaysInRange=
(Duration.TotalDays((EndDate-(StartDate+Duration.From(Date.DayOfWeek(EndDate)-Date.DayOfWeek(StartDate)))))/7*5)
+Date.DayOfWeek(EndDate)-Date.DayOfWeek(StartDate)+1
+(if Date.DayOfWeek(StartDate)=0 then -1 else 0)+(if Date.DayOfWeek(EndDate)=6 then -1 else 0),
HolidaysInRange = if Holidays = null then {} else
List.Select(Holidays, each StartDate <= _ and _ <= EndDate and Date.DayOfWeek(_, Day.Monday) <5 ),
Result = (if Switch then -1 else 1) * ((WeekDaysInRange) - List.Count(HolidaysInRange))
in
Result
- Jimmy8016 years agoCommunity Champion
Hey
I was just now that i posted both version.. and this confused you 🙂 sorry 🙂
// fnNetWorkDays2 (DateStart as date, DateEnd as date, optional Holidays as list) => let Switch = DateStart > DateEnd, StartDate = if Switch then DateEnd else DateStart, EndDate = if Switch then DateStart else DateEnd, HolidayIntern = if Holidays = null then List.Buffer({}) else List.Buffer(Holidays), CreateListDates =List.Buffer( List.Dates ( StartDate, Duration.TotalDays ( EndDate - StartDate ) +1, #duration(1,0,0,0) )), ExcludeWeekend = List.Select ( CreateListDates, each Date.DayOfWeek ( _, Day.Monday ) <5 ), ExcludeHoliday = if Holidays = null then ExcludeWeekend else List.Difference ( ExcludeWeekend, HolidayIntern ), Result = List.Count ( ExcludeHoliday ), FinalResult = try (if Switch then -1 else 1) * (Result) otherwise null in FinalResultinvoke it like this
=try fn([Start],[End]) otherwise null
If this post helps or solves your problem, please mark it as solution.
Kudos are nice to - thanks
Have fun
Jimmy - Anonymous6 years agoNot applicable
I like how you changed the duration to handle days only and reduce the number of list dates generated. Also like the buffering of the createlist to reduce recalculations plus the use of List.Select. Along with your use of List.Difference, I think your function is a great demonstration on how to use PQ's powerful list functions.
- Ritaf6 years agoResponsive Resident
Hi,
Thank you very much for your responding.
Unfortunately it isn't working, ,may be because of some blank cells in my start day columns (I cant remove this rows because of orher measures from this data)ğŸ˜
- Jimmy8016 years agoCommunity Champion
Hello
this is for sure the better approach as i hasn't to create any list that will slow down for sure.
I've gave it a test and it seems that something is not quite ok. Check out this table
Have a nice day
Jimmy
- Jimmy8016 years agoCommunity Champion
Hello
invoke the function like this
try fnNetWorkDays(Date.From([Start]),Date.From([End])) otherwise nullbut be carefull as the code proposed by Anonymous seems to have some problems
If this post helps or solves your problem, please mark it as solution.
Kudos are nice to - thanks
Have fun
Jimmy - Ritaf6 years agoResponsive Resident
May i need to edit the holidays list some way? Now is look like this
- Jimmy8016 years agoCommunity Champion
Hello
seems to be fine
just add the column of this table as third parameter like TableName[ColumnName]
Jimmy
- Jimmy8016 years agoCommunity Champion
Hello
I tried to speed up my version. so if you have no performance issue with this solution, I would go for it.
This solution is slower af the other proposed Anonymous . But if we come to include holiday it's faster
// fnNetWorkDays (DateStart as date, DateEnd as date, optional Holidays as list) => let Switch = DateStart > DateEnd, StartDate = if Switch then DateEnd else DateStart, EndDate = if Switch then DateStart else DateEnd, WeekDaysInRange= ( Duration.TotalDays ( ( EndDate- ( StartDate +Duration.From ( Date.DayOfWeek ( EndDate ) -Date.DayOfWeek ( StartDate ) ) ) ) ) /7*5 ) +Date.DayOfWeek ( EndDate ) -Date.DayOfWeek ( StartDate ) +1 + ( if Date.DayOfWeek ( StartDate )=0 then -1 else 0 ) + ( if Date.DayOfWeek ( EndDate )=6 then -1 else 0 ), HolidaysInRange = if Holidays = null then {} else List.Select(Holidays, each StartDate <= _ and _ <= EndDate and Date.DayOfWeek(_, Day.Monday) <5 ), Result = (if Switch then -1 else 1) * ((WeekDaysInRange) - List.Count(HolidaysInRange)) in Result // fnNetWorkDays2 (DateStart as date, DateEnd as date, optional Holidays as list) => let Switch = DateStart > DateEnd, StartDate = if Switch then DateEnd else DateStart, EndDate = if Switch then DateStart else DateEnd, HolidayIntern = if Holidays = null then List.Buffer({}) else List.Buffer(Holidays), CreateListDates =List.Buffer( List.Dates ( StartDate, Duration.TotalDays ( EndDate - StartDate ) +1, #duration(1,0,0,0) )), ExcludeWeekend = List.Select ( CreateListDates, each Date.DayOfWeek ( _, Day.Monday ) <5 ), ExcludeHoliday = if Holidays = null then ExcludeWeekend else List.Difference ( ExcludeWeekend, HolidayIntern ), Result = List.Count ( ExcludeHoliday ), FinalResult = try (if Switch then -1 else 1) * (Result) otherwise null in FinalResultIf this post helps or solves your problem, please mark it as solution.
Kudos are nice to - thanks
Have fun
Jimmy - Ritaf6 years agoResponsive Resident
Hi,
i tried to use a code an now is a syntax errorğŸ˜
- Jimmy8016 years agoCommunity ChampionHey
You have to create a new query with only my code in it. Then rename query and invoke it from your table in a new column - Ritaf6 years agoResponsive Resident
This is exacly what i did...i am not so bad🤣
And i have an error in synatax...
- Jimmy8016 years agoCommunity ChampionHello
But I can see another query above.
Delete it and paste my query.
Good luck
Jimmy - Ritaf6 years agoResponsive Resident
Where do you see onother query?
- Ritaf6 years agoResponsive Resident
Hi jimmy,
Thank you very much for your attempts to help,
The code is realy isn't working.
and error indicator just sendinf me to the with red pen.
- Jimmy8016 years agoCommunity Champion
hey
but now you can see the other quiry above
delete the upper part and it will work
Jimmy
- Ritaf6 years agoResponsive Resident
ooooooooh this code is for more the 1 options to solution?😳
- Ritaf6 years agoResponsive Resident
Syntex now sees ok, but i still have a probelem becuase of empty cells at start tame. Maybe there is some trick to pass them?
- Anonymous6 years agoNot applicable
Hi Jimmy,
Sorry to take so long to respond, but I am on vacation with limited network access.
The function is working for me. Would you mind posting the code that you called it with so I can see differences?
Thank you,
Mike
- Jimmy8016 years agoCommunity Champion
Hello Anonymous
thank you. I did also like how you used the switch-variable to enable the functionality also to handle differences in -.
yes, when you totaly understand the logic of lists, they are the most powerful object in M.
Have a nice day
Jimmy
- Ritaf6 years agoResponsive Resident
Hi Jimmi.
Thank you so much , finally i fell that i have a hope to solve it 🙂
where do ia need to put the code condition "=try fn([Start],[End]) otherwise null"?
- Ritaf6 years agoResponsive ResidentHi jimmy , unfortunately no. I just gave up and did it with dax ğŸ˜
- Jimmy8016 years agoCommunity Champion
😪ğŸ˜
oooh. .how sad
- Ritaf6 years agoResponsive Resident
I just have to give some time to learn this code, and i will do it.