Search code examples
overloadingpowerquery

Overlapping issue in employee task schedule Using Power Query


I have a schedule for employees' tasks, every employee starts his work shift from 7:00 to 15:00, I have an issue with an employee who has 3 tasks with start/end times of 7 am-11 am, 10 am-1 pm, and 11 am-3 pm then 10 am-1 pm overlaps with both task times 7 am-11 am and 11 am-3 pm, how could I ignore the overlapped task time

|Employee ID|Tasks    |Task Start      |Task End        |
|-----------+---------+----------------+----------------|
|123456     |Break    |2/12/23 7:00 AM |2/12/23 11:00 AM|
|123456     |Job Order|2/12/23 10:00 AM|2/12/23 1:00 PM |
|123456     |Waiting  |2/12/23 12:00 PM|2/12/23 3:00 PM |
|123654     |Job Order|2/12/23 7:00 AM |2/12/23 3:00 PM |

I've tried applying the below solution, but it produces an error

#"Grouped Rows" = Table.Group(Source, {"Employee ID", "Task Start"}, {{"Tasks", each _, type table [Employee ID=text, Task Start=datetime, Task End=datetime]}}),
#"Expanded Tasks" = Table.ExpandTableColumn(#"Grouped Rows", "Tasks", {"Employee ID", "Task Start", "Task End"}, {"Employee ID", "Task Start", "Task End"}),
#"Sorted Rows" = Table.Sort(#"Expanded Tasks",{{"Employee ID", Order.Ascending}, {"Task Start", Order.Ascending}}),
#"Added Index" = Table.AddIndexColumn(#"Sorted Rows", "Index", 1, 1),
#"Added Custom" = Table.AddColumn(#"Added Index", "Overlap", each if [Index] = 1 then "No Overlap" 
                                            else if [Task Start] >= List.Min(Table.SelectRows(#"Added Index", each [Employee ID]=[Employee ID] and [Index]<=[Index]-1 and [Task End]>=[Task Start])[Task End]) 
                                                and [Task End] <= List.Max(Table.SelectRows(#"Added Index", each [Employee ID]=[Employee ID] and [Index]<=[Index]-1 and [Task Start]<=[Task End])[Task Start]) then "Overlap" 
                                            else "No Overlap"),
#"Filtered Rows" = Table.SelectRows(#"Added Custom", each [Overlap] = "No Overlap") in "Filtered Rows"`

error: Expression.Error: We cannot convert the value null to type Logical. Details: Value= Type=[Type]

the expected output is to set a flag by adding a custom column "Overlapped" beside the middle one that overlapped with the 1st task that has the start time of the work shift 7 am and the last task that has the end time 3 pm

result e.g.

|Employee ID|Tasks    |Task Start      |Task End        |Flag       |
|-----------+---------+----------------+----------------+-----------|
|123456     |Break    |2/12/23 7:00 AM |2/12/23 11:00 AM|Not Overlap|
|123456     |Job Order|2/12/23 10:00 AM|2/12/23 1:00 PM |Overlap    |
|123456     |Waiting  |2/12/23 12:00 PM|2/12/23 3:00 PM |Not Overlap|
|123654     |Job Order|2/12/23 7:00 AM |2/12/23 3:00 PM |Not Overlap|

Solution

  • Try this:

    • We label Not Overlap if the Task either starts at 7 AM or ends at 3 PM.
    • For other tasks, we label Overlap if the Task ends after the previous task begins

    It works for the scenario you provided, and you can modify it for scenarios that you have not provided

    let
    
    //change next two lines to reflect actual data source and format
        Source = Excel.CurrentWorkbook(){[Name="Table19"]}[Content],
        #"Trim Headers" = Table.RenameColumns(Source, List.Transform(Table.ColumnNames(Source), each {_, Text.Trim(_)})),
        
        #"Changed Type" = Table.TransformColumnTypes(#"Trim Headers",{
            {"Employee ID", Int64.Type}, {"Tasks", type text}, {"Task Start", type datetime}, {"Task End", type datetime}}),
    
    //The "magic" happens here
        #"Grouped Rows" = Table.Group(#"Changed Type", {"Employee ID"}, {
            {"Overlap Test", (t)=>
                let 
                    #"Start Shift" = Date.From(t[Task Start]{0}) & #time(7,0,0),
                    #"End Shift" = Date.From(t[Task Start]{0}) & #time(15,0,0),
                    #"Offset End Time" = Table.FromColumns(
                        Table.ToColumns(t) & {{null} & List.RemoveLastN(t[Task End],1)},
                        type table[Employee ID=Int64.Type, Tasks=text, Task Start=datetime, Task End=datetime,Shifted Task End=datetime]),
                    #"Overlap Time" = Table.AddColumn(#"Offset End Time","Overlap", each 
                        if [Shifted Task End] > [Task Start] 
                            and 
                                ([Task Start] > #"Start Shift" and [Task End] < #"End Shift")
                            then "Overlap"
                            else "Not Overlap"
                        
                        ),
                    #"Remove Shifted Task" = Table.RemoveColumns(#"Overlap Time",{"Shifted Task End"})
                in 
                    #"Remove Shifted Task", type table[Employee ID=Int64.Type, Tasks=text, Task Start=datetime, Task End=datetime, Overlap=text]}    
            }),
    
    //expand the grouped tables
        #"Expanded Overlap" = Table.ExpandTableColumn(#"Grouped Rows", "Overlap Test", {"Tasks", "Task Start", "Task End", "Overlap"})
    in
        #"Expanded Overlap"
    

    enter image description here