▲用WorkDays函数计算两个日期值之间的工作日数 Function WorkDays(start_date As Date, end_date As Date, holidays As Range, nonholidays As Range) Dim cur_date As Date, date1 As Date, date2 As Date, day_count As Integer, day As Variant date1 = IIf(start_date <= end_date, start_date, end_date) date2 = IIf(start_date <= end_date, end_date, start_date)
cur_date = date1 day_count = 0 Do While cur_date <= date2 If Weekday(cur_date, 2) >= 1 And Weekday(cur_date, 2) <= 5 Then day_count = day_count + 1 End If cur_date = cur_date + 1 Loop For Each day In holidays If day >= date1 And day <= date2 Then If Weekday(day, 2) >= 1 And Weekday(day, 2) <= 5 Then day_count = day_count - 1 End If End If Next For Each day In nonholidays If day >= date1 And day <= date2 Then If Weekday(day, 2) = 6 Or Weekday(day, 2) = 7 Then day_count = day_count + 1 End If End If Next WorkDays = IIf(start_date <= end_date, day_count, -day_count) End Function
说明:在以上代码中,首先计算开始日期start_date和终止日期end_date之间非周末的天数,然后通过检查holidays减去非周末的节假日天数,再通过检查nonholidays加上作为工作日的周末的天数,最后即可得到两个日期相隔的工作日数。值得注意的是,如果日期start_date大于end_date,结果将为负值。
▲用NextWorkDay函数计算相隔指定工作日数之前或之后的日期
Function NextWorkDay(start_date As Date, days As Integer, holidays As Range, nonholidays As Range) Dim cur_date As Date, day_count As Integer, flag As Boolean, day As Variant cur_date = start_date day_count = 0 Do While day_count < Abs(days) cur_date = cur_date + Sgn(days) Select Case Weekday(cur_date, 2) Case 1 To 5 flag = True For Each day In holidays If day = cur_date Then flag = False Next If flag Then day_count = day_count + 1 Case 6, 7 flag = True For Each day In nonholidays If day = cur_date Then flag = False Next If Not flag Then day_count = day_count + 1 End Select Loop NextWorkDay = cur_date
End Function
说明:在以上代码中,通过日期逐次递增或递减的方法检查所得日期是否为工作日,如果是非周末则检查holidays,如果是周末则检查nonholidays,直至累计到指定的天数为止。
应用举例 根据2006年春节的放假规定,1月29日-2月4日(农历大年初一至初七)放假,共7天。其中,29日、30日、31日为法定假日,将1月28日(星期六)、29日(星期日)、2月5日(星期日)三个公休日调至2月1日(星期三)、2日(星期四)、3日(星期五),2月4日(星期六)照常公休,1月28日、2月5日上班。因此在本例中,首先把2006年春节期间非周末的节假日存入到区域A2:A6中。由于1月29日、2月4日本来就是周末,所以该区域只需存放1月30日、31日、2月1日、2日和3日。接着再把作为工作日的周末存入到区域B2:B3中,该区域有1月28日和2月5日两天。然后据此在F2单元格中输入公式“=WorkDays(D2,E2,A2:A6,B2:B3)”,计算2006年1月6日至2006年3月1日之间的工作日数;并在F6单元格中输入公式“=NextWorkDay(D6,E6,A2:A6,B2:B3)”,以2006年1月6日为起始日期计算30个工作日后的日期。结果如下图所示。

输入起止日期工作日立即自动算出
|