Forum Discussion

amcooper's avatar
amcooper
Frequent Visitor
3 months ago
Solved

Events In Progress Problem - How long each day are work orders open each day

I have a set of work orders that may remain open across multiple days. I want to calculate:

  • The number of hours each work order is open per day, and
  • The total downtime per day, calculated by summing the open hours of all work orders for that date.

I plan to do this using a DAX formula. Below is a small sample of the data.

 

Work Order IDEquipment NameOpen DateClosed Date
A1Thing 14/16/2026 10:004/16/2026 12:00
B1Thing 24/16/2026 15:304/17/2026 8:48
C1Thing 24/17/2026 11:104/17/2026 15:21
D1Thing 14/17/2026 13:494/18/2026 11:27
E1Thing 34/16/2026 14:154/18/2026 9:38
F1Thing 24/18/2026 10:304/18/2026 18:23
G1Thing 54/16/2026 21:15 
H1Thing 64/17/2026 8:30 
A2Thing 54/15/2026 10:304/16/2026 5:01
B2Thing 44/16/2026 16:154/17/2026 2:10
C2Thing 44/17/2026 5:004/17/2026 21:21
D2Thing 64/17/2026 15:254/18/2026 3:33
E2Thing 74/16/2026 19:254/18/2026 2:16
F2Thing 34/18/2026 0:014/18/2026 8:12
G2Thing 84/16/2026 0:00 
H2Thing 94/17/2026 2:15 

 

Some work orders span multiple days, so the number of open hours must be split by day. For example, work order E1 is open across three days, and the hours are calculated differently for each day:
Date16-Apr17-Apr18-Apr
Hours Open9.7524.009.63
CalculationBOD 4/17 - Open Date24*(4/18 - 4/17)Closed Date - BOD 4/18

 

I’ve found examples online (often using hotel guest data) that calculate how many records are open per day or during a time range, but they don’t address calculating hours per day for records that span multiple days. I’m struggling with where to start for this scenario.
    • For this you can use the classic events in progress overlap calculation. With a disconnected Date table in the model, write a measure that, for each day in scope, intersects each work order's open interval with that day and sums the hours.

    Open Hours =

    VAR DayStart = MIN ( 'Date'[Date] )

    VAR DayEnd = DayStart + 1

    RETURN

    SUMX (

        FILTER (

            ALL ( 'Work Orders' ),

            'Work Orders'[Open Date] < DayEnd

                && ( ISBLANK ( 'Work Orders'[Closed Date] ) || 'Work Orders'[Closed Date] > DayStart )

        ),

        VAR OpenAt   = 'Work Orders'[Open Date]

        VAR CloseAt  = IF ( ISBLANK ( 'Work Orders'[Closed Date] ), NOW (), 'Work Orders'[Closed Date] )

        VAR EffStart = IF ( OpenAt > DayStart, OpenAt, DayStart )

        VAR EffEnd   = IF ( CloseAt < DayEnd, CloseAt, DayEnd )

        RETURN ( EffEnd - EffStart ) * 24

    )

     

    Drop Date[Date] on rows for the daily total. To get hours per work order per day, also add Work Order ID on rows; the same measure works because the row context narrows SUMX to that single order. Replace NOW() with TODAY() + 1 if you want still open work orders to count up to end of day rather than the current minute.

     

    If this helped, a thumbs up and accepting the solution would be appreciated.

     

    Best,

    Shai Karmani

3 Replies

    • For this you can use the classic events in progress overlap calculation. With a disconnected Date table in the model, write a measure that, for each day in scope, intersects each work order's open interval with that day and sums the hours.

    Open Hours =

    VAR DayStart = MIN ( 'Date'[Date] )

    VAR DayEnd = DayStart + 1

    RETURN

    SUMX (

        FILTER (

            ALL ( 'Work Orders' ),

            'Work Orders'[Open Date] < DayEnd

                && ( ISBLANK ( 'Work Orders'[Closed Date] ) || 'Work Orders'[Closed Date] > DayStart )

        ),

        VAR OpenAt   = 'Work Orders'[Open Date]

        VAR CloseAt  = IF ( ISBLANK ( 'Work Orders'[Closed Date] ), NOW (), 'Work Orders'[Closed Date] )

        VAR EffStart = IF ( OpenAt > DayStart, OpenAt, DayStart )

        VAR EffEnd   = IF ( CloseAt < DayEnd, CloseAt, DayEnd )

        RETURN ( EffEnd - EffStart ) * 24

    )

     

    Drop Date[Date] on rows for the daily total. To get hours per work order per day, also add Work Order ID on rows; the same measure works because the row context narrows SUMX to that single order. Replace NOW() with TODAY() + 1 if you want still open work orders to count up to end of day rather than the current minute.

     

    If this helped, a thumbs up and accepting the solution would be appreciated.

     

    Best,

    Shai Karmani