PowerPivot轮班制下替代NETWORKDAYS的DAX方案求助
适配轮班制的病假事件DAX计算列修改方案
背景
已通过两个DAX计算列实现:将同一病假事件的所有日期关联到该事件的首次日期,且支持把周五与周一视为连续日期(无NETWORKDAYS函数的替代处理)。现需适配司机轮班制场景:
- 数据表包含员工班次标识字段
- 每个班次对应2023-2026年专属工作日历表,轮班模式每周顺延一天
- 要求跨轮班休息日的病假被识别为同一事件,逻辑对齐标准工作日跨周末的统计规则
核心修改思路
- 关联班次专属日历:通过班次字段匹配对应工作日历,获取每个日期对应该班次是否为工作日
- 自定义连续判断:基于班次日历,定位当前日期的前一个有效工作日,判断该日是否存在同员工的病假记录
- 事件分组标记:标记事件起始行后,将起始日期同步到同一事件的所有日期行
修改后的DAX计算列实现
假设现有数据表为SickRecords(字段:EmployeeID、Shift、SickDate),班次工作日历表为ShiftCalendars(字段:Shift、CalendarDate、IsWorkDay,其中IsWorkDay=1表示工作日)
计算列1:IsEventStart(标记事件起始行)
IsEventStart = VAR CurrentEmp = SickRecords[EmployeeID] VAR CurrentShift = SickRecords[Shift] VAR CurrentDt = SickRecords[SickDate] -- 获取当前班次下,当前日期的前一个工作日 VAR PrevWorkDay = CALCULATE( MAX(ShiftCalendars[CalendarDate]), ShiftCalendars[Shift] = CurrentShift, ShiftCalendars[CalendarDate] < CurrentDt, ShiftCalendars[IsWorkDay] = 1, ALL(SickRecords) ) -- 检查前一个工作日是否有同员工的病假记录 VAR HasPrevSick = CALCULATE(COUNTROWS(SickRecords), SickRecords[EmployeeID] = CurrentEmp, SickRecords[SickDate] = PrevWorkDay) > 0 RETURN IF(HasPrevSick, 0, 1)
计算列2:FirstSickDate(分配事件首次日期)
FirstSickDate = VAR CurrentEmp = SickRecords[EmployeeID] VAR CurrentDt = SickRecords[SickDate] VAR CurrentShift = SickRecords[Shift] -- 计算当前行及之前的起始标记累计数 VAR CurrentStartCount = CALCULATE( SUM(SickRecords[IsEventStart]), SickRecords[EmployeeID] = CurrentEmp, SickRecords[Shift] = CurrentShift, SickRecords[SickDate] <= CurrentDt ) RETURN CALCULATE( MIN(SickRecords[SickDate]), SickRecords[EmployeeID] = CurrentEmp, SickRecords[Shift] = CurrentShift, SickRecords[SickDate] <= CurrentDt, -- 筛选累计起始标记数与当前行相同的行(即同一事件) CALCULATE( SUM(SickRecords[IsEventStart]), SickRecords[EmployeeID] = CurrentEmp, SickRecords[Shift] = CurrentShift, SickRecords[SickDate] <= EARLIER(SickRecords[SickDate]) ) = CurrentStartCount )
逻辑说明
IsEventStart:通过班次日历精准定位当前日期的前一个工作日,若该日无同员工病假,则标记为事件起始FirstSickDate:按员工+班次分组,通过起始标记的累计数区分不同事件,将同一事件内的最小日期(首次病假日期)分配给所有行- 轮班顺延适配:由于班次日历已内置每周顺延的工作日规则,
PrevWorkDay会自动匹配对应班次的实际前一个工作日,无需额外处理顺延逻辑
效果验证示例
若某司机所属班次的休息日每周顺延一天(第一周为周三、周四,第二周为周四、周五),该司机在周二(工作日)、周五(工作日,跨轮班休息日)连续病假,则两行的FirstSickDate均会显示周二的日期,视为同一事件。
内容的提问来源于stack exchange,提问作者kcoco
相关产品推荐
相关产品推荐

