I aim to tally the number of agents working during a specific hour and day using their regular schedules. However, my method doesn't accurately represent agents who work past midnight. For instance, if an agent works until 2 AM, they are incorrectly counted for the day they started rather than the following day.
Here is the link to the schedule file: https://docs.google.com/spreadsheets/d/1pan9psx_fIu5TD3RxKxO0l3I3usVjiwxHqWMRIwoCOE/edit?usp=sharing
To illustrate, the data displays the schedules of sales agents on the left side, showcasing their starting and ending times and the days they work each week.
Team schedule from Monday to Friday 5AM to 1PM
My goal is to determine the exact count of agents working on every day of the week. Based on the provided data (imagine a sample), here's a possible outcome:
Tried a few formulas but neither of them worked as intended
=ARRAYFORMULA(
SUM(
IF(
($M2 >= $A$2:$A$100) * ($M2 < $B$2:$B$100),
IF(
OFFSET(D$2, 0, MATCH(N$1, D$1:J$1, 0)-1, COUNTA(D$2:D$100), 1) = "ON",
1,
0
),
0
)
)
+
SUM(
IF(
($M2 < $B$2:$B$100) * ($A$2:$A$100 > $B$2:$B$100),
IF(N$1="Monday",
IF(J$2:J$100 = "ON", 1, 0),
IF(
OFFSET(D$2, 0, IF(MATCH(N$1, D$1:J$1, 0)-1=0, 6, MATCH(N$1, D$1:J$1, 0)-2), COUNTA(D$2:D$100), 1) = "ON",
1,
0
)
),
0
)
)
)
OR
=ARRAYFORMULA(
SUM(
IF(
($M2 >= $A$2:$A$100) * ($M2 < $B$2:$B$100) +
(($M2 < $B$2:$B$100) * ($A$2:$A$100 > $B$2:$B$100)),
IF(
OFFSET(D$2, 0, MATCH(N$1, D$1:J$1, 0)-1, COUNTA(D$2:D$100), 1) = "ON",
1,
0
),
0
)
)
)
OR
=ARRAYFORMULA(SUM( ( (($M2 >= $A$2:$A$100) * ($M2 < $B$2:$B$100) + ($M2 >= $A$2:$A$100) * ($A$2:$A$100 > $B$2:$B$100) + ($M2 < $B$2:$B$100) * ($A$2:$A$100 > $B$2:$B$100)) * (OFFSET(D$1,0,MATCH(N$1, $D$1:$J$1, 0)-1, COUNTA(D$2:D$100), 1) = "ON") ), 1, 0))-1 " with "=ARRAYFORMULA(SUM( ( (($M2 >= $A$2:$A$100) * ($M2 < $B$2:$B$100) + ($M2 >= $A$2:$A$100) * ($A$2:$A$100 > $B$2:$B$100) + ($M2 < $B$2:$B$100) * ($A$2:$A$100 > $B$2:$B$100)) * (OFFSET(D$2,0,MATCH(N$1, D$1:J$1, 0)-1, COUNTA(D$2:D$100), 1) = "ON") ), 1, 0))-1
You have a table of shifts for staff(agents) showing their shift start and end time, and whether they are rostered to work on each of seven days (Mon-Sun).
You want to calculate the number of agents who are working by day and by hour.
This answer describes a method for generating that count. It involves a number of "helper" columns. Please note that it is almost certain that there are other ways to generate the same results.
Agent Count: by hour by day
Shift table by agent: times and days
Comma separated hour values
Shift hours can be used to develop strings of comma separated hour values. One can test if a shift hour can be found in the string and use the result in a count formula.
For example:
Agent "Anthony" (Row#2) works a shift that starts at 5:00am and is completed before midnight.
Agent "Ceasar" (Row#72) works a shift that starts at 7:00pm; part of the shift is completed before midnight, and part of the shift is completed after midnight.
Helper Columns#1: Comma separated hour by shift
Range: AE1:AO5
The purpose of these helpers is to develop the comma separated strings that apply to each hour of the day (0-24)
=arrayformula(TEXT(V2:V25, "hh:mm")*24)
=arrayformula(if(AG2:AG25>=16,((AG2:AG25)+8)-24,AG2:AG25+8))
=MAP(AH2:AH25, LAMBDA(a,ARRAYFORMULA(isbetween(a,$AF$2,$AF$3,true,true))))
=arrayformula(if(AH2:AH25=0,true,false))
=arrayformula(if(AI2:AI25=true,AG2:AG25+8,if(AJ2=true,AG2:AG25+8,24)))
=MAP(AG2:AG25,AK2:AK25, LAMBDA(a,b,ARRAYFORMULA(join(",",SEQUENCE(1,b-a,a)))))
=MAP(AI2:AI25,AJ2:AJ25, LAMBDA(a,b,ARRAYFORMULA(if(and(a=false, b=false), 0,))))
=MAP(AI2:AI25,AJ2:AJ25,AH2:AH25, LAMBDA(a,b,c,ARRAYFORMULA(if(and(a=false, b=false), c,))))
=MAP(AM2:AM25,AN2:AN25, LAMBDA(a,b,ARRAYFORMULA(iferror(join(",",SEQUENCE(1,b-a,a)),))))
Helper Columns#2: Basic comma separated shift hour values by agent
Range: K2:L100
The purpose of these helpers is to identify the basic comma separated value for each agent shift.
=arrayformula(vlookup(A2:A100,$W$2:$AP$25,17,0))
=arrayformula(vlookup(A2:A100,$W$2:$AP$25,20,0))
Helper Columns#3: Comma separated shift hours by agent by Day by roster="ON"
Range: N1:T101
The purpose of these helpers is to calculate the daily comma separated shift hours (including post midnight hors for the previous day) and subject to having been rostered "ON" on the given day and previous day.
=arrayformula({if(D2:D100="ON",$K$2:$K$100,)&","&if(J2:J100="ON",$L$2:$L$100,)})
=arrayformula({if(E2:E100="ON",$K$2:$K$100,)&","&if(D2:D100="ON",$L$2:$L$100,)})
=arrayformula({if(F2:F100="ON",$K$2:$K$100,)&","&if(E2:E100="ON",$L$2:$L$100,)})
=arrayformula({if(G2:G100="ON",$K$2:$K$100,)&","&if(F2:F100="ON",$L$2:$L$100,)})
=arrayformula({if(H2:H100="ON",$K$2:$K$100,)&","&if(G2:G100="ON",$L$2:$L$100,)})
=arrayformula({if(I2:I100="ON",$K$2:$K$100,)&","&if(H2:H100="ON",$L$2:$L$100,)})
=arrayformula({if(J2:J100="ON",$K$2:$K$100,)&","&if(I2:I100="ON",$L$2:$L$100,)})
Agent Count Formula: by hour by day
Range: V1:AC25
Formula:
=iferror(query({N$2:N$100},"select count(Col1) where Col1 matches '.*\b"&$AG2&"\b.*' label count(Col1) '' ",1),)
=iferror(query({N$2:N$100},"select count(Col1) where Col1 matches '.\b"&$AG2&"\b.' label count(Col1) '' ",1),)
Logic: