Forum Discussion

TerriAki's avatar
TerriAki
Frequent Visitor
4 years ago
Solved

Consecutive streak into a date range

Hi,  

 

Kinda new here and would really appreciate some help ðŸ™‚

 

I have a time and attendance table and trying to work out the continues period of sick absence with a value of S, SC or SB for each employee.  Start and End added below as an example of what the output should be (could be summarised into a seperate table if needed.  In order to work out continous periods of absence the calculation will need to take into account two tables of codes. One contains a list of codes that would break a continuous period and another list which does not.  

 

The streak must start and end S, SB or SC.

 

T&A table 

Employee IDDate            Status    Start             End
12302-Feb-22RD  
12303-Feb-221  
12304-Feb-22S04/02/202204/02/2022
12305-Feb-22RD  
12306-Feb-22RD  
12307-Feb-221  
12308-Feb-22S  
12309-Feb-22SC  
12310-Feb-22SB08/02/202210/02/2022

123

11-Feb-221  
12312-Feb-22RD  
12313-Feb-22RD  
12314-Feb-22AL  
12315-Feb-22S  
12316-Feb-22RD  
12317-Feb-22S  
12318-Feb-22S  
12319-Feb-22ME  
12320-Feb-22RD  
12321-Feb-22S  
12322-Feb-22S15/02/202222/02/2022
12323-Feb-22RD  

 

Break codes Continuous codes
01 AW
ET BH
L HA
NW ME
RW OD
RX RD
TC RB
TW BL
WB HR
WS PL
XX S
ZL SB
AB SC
AL  
AS  
CL  
EL  
FL  
HD  
HL  
LC  
MB  
ML  
TA  
UL  
  • tamerj1's avatar
    tamerj1
    4 years ago

    Hi TerriAki 
    I was able to double the speed by creating relationships as per below screenshot. I tried on 2.7M rows table and still takes around 50-55 sec. on my machine which is not super-fast. Still too slow and also you have to know that the time increases exponentially with the number of rows and I have no idea how many columns you have. If you have too many columns we need to select only the relevant ones

    Start - End = 
    IF (
        'T&A table 2'[Status] IN 'Sick Absence Code',
        VAR CurrentDate = 
            'T&A table 2'[Date]
        VAR EmployeeTable =
            CALCULATETABLE ( 'T&A table 2',  ALLEXCEPT ( 'T&A table 2', 'T&A table 2'[Employee ID] ) )
        VAR OffDaysTable =
            CALCULATETABLE ( 'T&A table 2', ALLEXCEPT ( 'T&A table 2','T&A table 2'[Employee ID] ), 'Sick Absence Code' )
        VAR BreakDaysTable = 
            CALCULATETABLE ( 'T&A table 2', ALLEXCEPT ( 'T&A table 2','T&A table 2'[Employee ID] ), 'Break codes' )
        -- Calculating last day off 
        VAR NexBreaksTable = 
            FILTER ( BreakDaysTable, 'T&A table 2'[Date] >= CurrentDate )
        VAR NextBreakDate =
            MINX ( NexBreaksTable, 'T&A table 2'[Date] )
        VAR NextOffDaysTable =
            FILTER ( OffDaysTable, 'T&A table 2'[Date] < NextBreakDate )
        VAR LastDayOff =
            MAXX ( NextOffDaysTable, 'T&A table 2'[Date] )
        RETURN
            IF (
                CurrentDate = LastDayOff,
                -- Calculating first day off 
                VAR PreviousBreaksTable = 
                    FILTER ( BreakDaysTable, 'T&A table 2'[Date] <= CurrentDate )
                VAR PreviousBreakDate =
                    MAXX ( PreviousBreaksTable, 'T&A table 2'[Date] )
                VAR PreviousOffDaysTable =
                    FILTER ( OffDaysTable, 'T&A table 2'[Date] > PreviousBreakDate )
                VAR FirstDayOff = 
                    MINX ( PreviousOffDaysTable, 'T&A table 2'[Date] )
                VAR Result =
                        FirstDayOff & " - " & LastDayOff
                RETURN
                    Result
            )
    )

11 Replies

  • tamerj1's avatar
    tamerj1
    Community Champion

    Hi TerriAki 
    Please find attached sample file with the solution https://www.dropbox.com/t/WHjQ0GfVCTQ62ua7
    It is not the optimum performance code but it should work and do the job.

    At the end of the sample data I have added a break as otherwise the sick leave is considred open. I hope this shall not be a problem to you.
    I will let you know If I was able to optimize it further

    Start - End = 
    IF (
        'T&A table'[Status] IN { "S", "SB", "SC" },
        VAR CurrentDate = 
            'T&A table'[Date]
        VAR EmployeeTable =
            CALCULATETABLE ( 'T&A table', ALLEXCEPT ( 'T&A table', 'T&A table'[Employee ID] ) )
        VAR OffTable =
            FILTER ( EmployeeTable, 'T&A table'[Status] IN { "S", "SB", "SC" } )
        VAR BreakTable = 
            FILTER ( EmployeeTable,'T&A table'[Status] IN 'Break codes' )
        -- Calculating last day off 
        VAR NextDaysTable = 
            FILTER ( EmployeeTable, 'T&A table'[Date] >= CurrentDate )
        VAR NexBreaksTable =
            FILTER ( NextDaysTable, 'T&A table'[Status] IN 'Break codes' )
        VAR NextBreakDate =
            MINX ( NexBreaksTable, 'T&A table'[Date] )
        VAR NextOffDaysTable =
            FILTER ( OffTable, 'T&A table'[Date] < NextBreakDate )
        VAR LastDayOff =
            MAXX ( NextOffDaysTable, 'T&A table'[Date] )
        -- Calculating first day off 
        VAR PreviousDaysTable = 
            FILTER ( EmployeeTable, 'T&A table'[Date] <= CurrentDate )
        VAR PreviousBreaksTable =
            FILTER ( PreviousDaysTable, 'T&A table'[Status] IN 'Break codes' )
        VAR PreviousBreakDate =
            MAXX ( PreviousBreaksTable, 'T&A table'[Date] )
        VAR PreviousOffDaysTable =
            FILTER ( OffTable, 'T&A table'[Date] > PreviousBreakDate )
        VAR FirstDayOff = 
            MINX ( PreviousOffDaysTable, 'T&A table'[Date] )
        VAR Result =
            IF (
                CurrentDate = LastDayOff,
                FirstDayOff & " - " & LastDayOff
            )
        RETURN
            Result
    )
    • TerriAki's avatar
      TerriAki
      Frequent Visitor

      tamerj1 Amazing!  This is very close and is reliably producing the result, is there any way to adapt the code to give the open ended absence a date too?   Also the optimisation would be really appreciated as will be running this on very large dataset.  

      • tamerj1's avatar
        tamerj1
        Community Champion

        TerriAki 

        The problem is that most probably addapting open end absence would affect the preformance but I wIll gove a try. Meanwhile, plea

         try on your full set of data and let me know how the performance is. 

  • TerriAki's avatar
    TerriAki
    Frequent Visitor

    amitchandak Thank you.  You are right, it is a continuous streak problem.  I will retitle the post so its more clearer.