Updated Solution
Uses the sheets named blind_STATUS
, blind_IN
,and blind_OUT
blind_STATUS
sheet has:
- A single entry for each unique
Device
,
- the device's current
Status
,
- the
Timestamp
associated with the status,
- the duration a device has been
Out (hrs)
,
- the ability to do some primary and secondary
sorting
via drop-menus,
- the current sort is rendered at top of the page to avoid confusion with defaults, redundant and/or contradictory options, etc.
Sample Status Page [ Link ]
Sorting by "STATUS ▼" |
then by |
"OUT (HRS)▲" |
|
|
|
Sort [ default ▲ /▼ ] |
By |
Order |
|
|
|
|
|
|
Primary [ Timestamp ▼ ] |
Status |
Descending |
Timestamp |
Device |
Employee |
Status |
Out (hrs) |
|
Optional [ ▲ ] |
Out (hrs) |
Ascending |
Jan-10-2023 6:07 AM |
TC26-05 |
Wheeler, Lena |
OUT |
66.09 |
|
|
|
|
Jan-10-2023 5:07 AM |
TC26-21 |
Maldonado, Annabelle |
OUT |
67.09 |
|
|
|
|
Jan-09-2023 6:10 PM |
TC26-10 |
Morgan, Daphne |
OUT |
78.04 |
|
|
|
|
Jan-08-2023 6:05 PM |
TC26-23 |
Mathews, Lamont |
OUT |
102.13 |
|
|
|
|
Jan-10-2023 5:08 AM |
TC26-20 |
Villanueva, Barbara |
IN |
|
|
|
|
|
Jan-08-2023 6:20 PM |
TC26-22 |
Bishop, Saniyah |
IN |
|
|
|
|
|
Sample Status Page

Formula
=SORT(
BYROW(_MYSORT2({_MYSORT2(_out, "OUT");_MYSORT2(_in, "IN")},),
LAMBDA(_r, IF(INDEX(_r,,4)="OUT",
{_r,(NOW()-INDEX(_r,,1))*24}, _r))),
IFERROR(MATCH(_byPri,_cols,0),1),
IF(_ordPri="Ascending",1,0),
IFERROR(MATCH(_bySec,_cols,0),IFERROR(MATCH(_ordSec,_cols,0),1)),
IF(_ordSec="Descending",0,1)
)
Formula

Named Ranges
Name |
Range |
Notes |
_cols |
blind_STATUS!A3:E3 |
Column Headings |
_in |
blind_IN!A2:C1000 |
Checkin Data Columns |
_out |
blind_OUT!A2:C1000 |
Checkout Data Columns |
_byPri |
blind_STATUS!H2 |
Primary Sort Column |
_bySec |
blind_STATUS!H3 |
Secondary Sort Column |
_ordPri |
blind_STATUS!I2 |
Primary Sort Order |
_ordSec |
blind_STATUS!I3 |
Secondary Sort Order |
Named Function
Solution uses a Named Function
for the custom SORTN
to reduce the length and complexity of the parent formula.
There are two options below based on the possible source data.
_MYSORT
(v1)
Simpler and requires the source data include a field identifying if coming from check-in or check-out.
Timestamp |
Device |
Employee |
Status |
1/8/2023 18:00:00 |
TC26-23 |
Melton, Malia |
"IN" |
_MYSORT =Lambda(x,
SORTN(SORT(x,1,0),COUNTA(INDEX(x,,1)),2,2,1))
(FILTER(_in, INDEX(_in,,1)<>""))
_MYSORT2
(v2)
Longer but can be used regardless if the source data includes a field identifying if coming from check-in or check-out, or if it does not.
Timestamp |
Device |
Employee |
|
1/8/2023 18:00:00 |
TC26-23 |
Melton, Malia |
|
_MYSORT2 =BYROW(LAMBDA(x, SORTN(SORT(x,1,0),
COUNTA(INDEX(x,,1)),2,2,1))
(FILTER(_data, INDEX(_data,,1)<>"")),
LAMBDA(y, IF(_label<>"",{y, _label},y)))
Benefit in Practice
you can use this formula
=_MYSORT2({ _MYSORT2(_out, "OUT");
_MYSORT2(_in, "IN")
},)
as a replacement for this formula
=LAMBDA(x, SORTN(SORT(x,1,0),COUNTA(INDEX(x,,1)),2,2,1))
( BYROW(
{
BYROW(
LAMBDA(x, SORTN(SORT(x,1,0),COUNTA(INDEX(x,,1)),2,2,1))
(FILTER(_out, INDEX(_out,,1)<>"")),
LAMBDA(y, {y, "OUT"})
);
BYROW(
LAMBDA(x, SORTN(SORT(x,1,0),COUNTA(INDEX(x,,1)),2,2,1))
(FILTER(_in, INDEX(_in,,1)<>"")),
LAMBDA(y, {y, "IN"}))
},
Lambda(x, SORTN(SORT(x,1,0),COUNTA(INDEX(x,,1)),2,2,1)))
)

NOTE
My first approach did not use SORTN
, but rather MAXIFS
. In trying to further simplify the formula and add secondary dynamic Sort By
options, I switched from MAXIFS
to SORTN
inspired by doubleunary's approach, and he should be given credit for that answer.
My older formula that I updated:
=SORT(
BYROW(UNIQUE(FILTER(_oDev,ROW(_oDev)>1)),
LAMBDA (r, IF(r<>"",
IF(MAXIFS(_oTime, _oDev, r)>MAXIFS(_iTime, _iDev, r),
{ r, "OUT", MAXIFS(_oTime, _oDev, r),
INDEX(_oEmp, MATCH(MAXIFS(_oTime, _oDev, r),_oTime)),
(NOW()-MAXIFS(_oTime, _oDev, r))*24 },
{ r, "IN",MAXIFS(_iTime, _iDev, r),
INDEX(_iEmp, MATCH(MAXIFS(_iTime, _iDev, r),iTime)) }),))),
IFERROR(MATCH(_sortBy,_headings,0),1),
IF(_sortOrd="Descending",0,1))