Access数据库DateAddWorkdays函数计算工作日结果不一致问题问询
根因定位
- 日期参数顺序错误:倒推场景下
lngNumber为负数,计算得到的datDate1早于传入的datDate,调用GetHolidays时直接传入datDate, datDate1会导致生成的SQL语句为HolidayDate Between 大日期 And 小日期,SQL中Between要求前值小于等于后值,否则返回空结果,直接导致节假日判断失效。 - 缓存逻辑缺陷:
GetHolidays使用静态Recordset做调用缓存,仅判断两次调用的起止日期是否完全相等,未校验新的查询范围是否被缓存范围覆盖,出现范围超出时仍复用旧缓存,导致节假日漏判。 - 范围计算不足:原
lngDiffMax计算系数预留缓冲不足,若某周存在多个节假日,会出现预查询的日期范围覆盖不全,导致后续循环中遇到的节假日不在预查数组内,无法正确识别。
修复方案
1. 修正DateAddWorkdays中GetHolidays调用参数顺序
调用前先判断两个日期的大小,保证小日期在前、大日期在后:
' 替换原代码中 aHolidays = GetHolidays(datDate, datDate1) 部分 If datDate < datDate1 Then aHolidays = GetHolidays(datDate, datDate1) Else aHolidays = GetHolidays(datDate1, datDate) End If
2. 优化GetHolidays缓存判断逻辑
修改缓存校验条件,只要新查询范围超出缓存范围就重新拉取数据:
' 替换原代码中日期变更判断条件 If DateDiff("d", datDate1, datDate1Last) <> 0 Or DateDiff("d", datDate2, datDate2Last) <> 0 _ Or datDate1 < datDate1Last Or datDate2 > datDate2Last Then
若业务调用量不大,可直接删除所有静态变量定义,每次调用都重新查询,彻底避免缓存导致的异常。
3. 放大预查范围系数,避免覆盖不足
' 替换原lngDiffMax计算逻辑,放大1.5倍预留足够缓冲 lngDiffMax = lngNumber * clngWeekdayCount / (clngWeekWorkdays - clngWeekHolidays) * 1.5 lngDiffMax = lngDiffMax + Sgn(lngDiffMax) * clngWeekdayCount
验证效果
修复后测试所有异常场景:
- Lag=6倒推2021年10月25日,会正确跳过周末和节假日,返回预期结果2021年10月15日
- 2022年1月11日Lag取值9-14区间时,不再忽略节假日规则,计算结果符合预期
内容的提问来源于stack exchange,提问作者Mel Forsyth
相关产品推荐
相关产品推荐

