Advertisement
jalih

Excel's NetworkDays() function replacement written in PL/I

May 2nd, 2012
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.30 KB | None | 0 0
  1. *PROCESS MARGINS(1, 140);
  2.  
  3. t1: proc options (main);
  4. dcl from char (8) date ('DDMMYYYY');
  5. dcl to char (8) date ('DDMMYYYY');
  6. dcl holidays (7) char (8) date ('DDMMYYYY')
  7. init ('01012012', '06012012', '01052012', '06122012', '24122012', '25122012', '26122012');
  8.  
  9. from = '01122012';
  10. to = '31122012';
  11.  
  12. put skip list ('Number of working days in december 2012: ' || trim(workdays(from, to, holidays)));
  13.  
  14.  
  15. (STRINGRANGE, SUBSCRIPTRANGE):
  16. workdays: proc (from, to, holiday_list) returns (fixed bin (31));
  17. dcl (from, to) char (8) date ('DDMMYYYY');
  18. dcl holiday_list (*) char (8) date ('DDMMYYYY') optional;
  19.  
  20. dcl (days_from, days_to, day) fixed bin (31);
  21. dcl total_days fixed bin (31);
  22. dcl week_index fixed bin (31);
  23. dcl nworkdays fixed bin (31);
  24. dcl i fixed bin (31);
  25. dcl (result, holiday) bit (*) controlled;
  26. dcl weeks (7) bit (7) nonasgn init ('1000001'b, '0000011'b, '0000110'b, '0001100'b, '0011000'b, '0110000'b, '1100000'b);
  27.  
  28. dcl (days, weekday, tally, substr, lbound, hbound, copy, omitted) builtin;
  29.  
  30.  
  31. days_from = days(from, 'DDMMYYYY');
  32. days_to = days(to, 'DDMMYYYY');
  33.  
  34. total_days = days_to - days_from + 1;
  35. if total_days <= 0 then return (0);
  36.  
  37. allocate result bit (total_days);
  38.  
  39. week_index = weekday(days_from);
  40. result = copy(weeks(week_index), total_days / 7) || substr(weeks(week_index), 1, mod(total_days, 7));
  41.  
  42. if ^omitted(holiday_list) then
  43. do;
  44. allocate holiday bit (total_days);
  45. do i = lbound(holiday_list) to hbound(holiday_list);
  46. day = days(holiday_list(i), 'DDMMYYYY');
  47. if (day >= days_from) & (day <= days_to) then
  48. do;
  49. holiday = copy('0'b, day - days_from ) || '1'b || copy('0'b, days_to - day);
  50. result = result | holiday;
  51. end;
  52. end;
  53. free holiday;
  54. end;
  55.  
  56. nworkdays = tally(result, '0'b);
  57. free result;
  58.  
  59. return (nworkdays);
  60.  
  61. end workdays;
  62.  
  63. end t1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement