You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正跨午夜工时拆分的VBA函数?按指定三时段分组

修正跨午夜班次的工时拆分VBA函数

原函数未处理跨午夜的班次场景,导致当结束时间在次日时,会错误计算早11点前的工时为负数。以下是修正后的函数,确保跨午夜的工时全部计入19点后时段:

Function SplitHours(startTime As Date, endTime As Date) As Variant
    Dim pre11am As Double
    Dim elevenToSeven As Double
    Dim post7pm As Double
    
    ' 验证输入有效性
    If Not IsDate(startTime) Or Not IsDate(endTime) Then
        SplitHours = "无效输入:开始和结束时间必须是有效的日期格式。"
        Exit Function
    End If
    
    ' 判断是否跨午夜班次
    Dim isCrossMidnight As Boolean
    isCrossMidnight = (endTime < startTime)
    
    If isCrossMidnight Then
        ' 处理当天时段:从开始时间到当天午夜
        Dim sameDayStartHour As Double, sameDayEndHour As Double
        sameDayStartHour = Hour(startTime) + Minute(startTime) / 60
        sameDayEndHour = 24 ' 将午夜视为24点便于计算
        
        ' 分配当天的各时段工时
        If sameDayStartHour < 11 Then
            pre11am = 11 - sameDayStartHour
        End If
        If sameDayStartHour < 19 Then
            elevenToSeven = 19 - WorksheetFunction.Max(sameDayStartHour, 11)
        End If
        post7pm = post7pm + sameDayEndHour - WorksheetFunction.Max(sameDayStartHour, 19)
        
        ' 处理次日时段:从0点到结束时间,全部计入19点后
        Dim nextDayEndHour As Double
        nextDayEndHour = Hour(endTime) + Minute(endTime) / 60
        post7pm = post7pm + nextDayEndHour
    Else
        ' 同一天班次,沿用优化后的原逻辑
        Dim startHour As Double, endHour As Double
        startHour = Hour(startTime) + Minute(startTime) / 60
        endHour = Hour(endTime) + Minute(endTime) / 60
        
        If endHour <= 11 Then
            pre11am = endHour - startHour
        ElseIf startHour >= 19 Then
            post7pm = endHour - startHour
        Else
            If startHour < 11 Then
                pre11am = 11 - startHour
            End If
            If endHour > 19 Then
                post7pm = endHour - 19
            End If
            elevenToSeven = WorksheetFunction.Max(WorksheetFunction.Min(endHour, 19) - WorksheetFunction.Max(startHour, 11), 0)
        End If
    End If
    
    ' 返回结果数组:[早11点前时长, 11:00-19:00时长, 19点后时长]
    SplitHours = Array(pre11am, elevenToSeven, post7pm)
End Function

关键修改说明

  1. 跨天判断:通过endTime < startTime识别跨午夜班次,这是Excel日期处理中判断跨天的标准方式
  2. 跨天时段拆分:
    • 当天时段:正常分配11点前、11-19点的工时,19点到午夜的部分计入19点后
    • 次日时段:所有工时直接计入19点后,符合需求
  3. 保留原逻辑:非跨天班次的计算逻辑保持优化后的版本,确保原有场景的正确性

测试案例

  • 案例1:班次20:00到次日02:00
    • 结果:Array(0, 0, 6)(全部6小时计入19点后)
  • 案例2:班次09:00到次日10:00
    • 结果:Array(2, 8, 15)(2小时早11点前、8小时11-19点、15小时19点后)

内容的提问来源于stack exchange,提问作者Freddie Rainbow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:57:09