Query data based on time interval/frequency - google-sheets

I'm trying to have a calendar display a series of activities based on their type, time and frequency for an easier visualization of data.
So far, I have managed to create a formula that correctly fetches the data that I have on a repository and displays it on the calendar. However, I'm not sure how I can have it account for entries that have a frequency (happening every x days).
For an easier understanding here are screenshots of both the table and the schedule
And here's the current formula I'm using to display the event/activity title in each day/hour at C12 for example:
=IFERROR(
INDEX(Repository!$K:$K,
MATCH(
C$10,
IF(
(Repository!$G:$G=$G$8)*
(Repository!$H:$H=$K$8)*
(Repository!$N:$N>=$B12)*
(Repository!$N:$N<$B12+TIME(2,0,0)),
Repository!$D:$D),
0)
),
"")
What I'm currently missing on the formula is a way to correctly account for the start/end date as well as frequency and understand if each day falls under the specified criteria. In case the frequency is 0 then I'd like to have it discard the end date at all (in case for some reason I end up forgetting to set the end date).
I have tried to work with the formula provided to account for the frequency but nothing that I tried seemed to work.
Minimal example requested by #GabrielCarballo
Entry on the table with a 2 days frequency:
Expected result on the schedule:
So basically, the formula on each cell should check for the start date, end date and frequency of the activity and identify if the specific date on the schedule falls under the specified timeframe.
In this minimal example, the activity starts on the 7th December and repeats every 2 days until the 14th of December.

use in C6:
=INDEX(IFNA(VLOOKUP(TEXT(C4:P4+B6:B14, "e-m-d-h-m")&G$2&K$2, SPLIT(FLATTEN(MAP(
Repository!D$4:D, Repository!O$4:O, Repository!P$4:P, Repository!N$4:N,
Repository!G$4:G, Repository!H$4:H, Repository!K$4:K, LAMBDA(d, o, p, n, g, h, k,
IF(DAYS(o, d)>=SEQUENCE(1, MAX(DAYS(o, d)), 0, p), TEXT(d+SEQUENCE(1,
MAX(DAYS(o, d)), 0, p)+IF(ISODD(HOUR(n)), (HOUR(n)*"1:00")-"1:00", HOUR(n)*"1:00"),
"e-m-d-h-m")&g&h&"×"&k, )))), "×"), 2, )))

Related

Google Sheets formula that queries recurring data based on time interval/frequency

I'm trying to have a calendar display a series of activities based on their type, time and frequency for an easier visualization of data.
So far, I have managed to create a formula that correctly fetches the data that I have on a repository and displays it on the calendar. However, I'm not sure how I can have it account for entries that have a frequency (happening every x days).
For an easier understanding here are screenshots of both the table and the schedule
And here's the current formula I'm using to display the event/activity title in each day/hour at C12 for example:
=IFERROR(
INDEX(Repository!$K:$K,
MATCH(
C$10,
IF(
(Repository!$G:$G=$G$8)*
(Repository!$H:$H=$K$8)*
(Repository!$N:$N>=$B12)*
(Repository!$N:$N<$B12+TIME(2,0,0)),
Repository!$D:$D),
0)
),
"")
What I'm currently missing on the formula is a way to correctly account for the start/end date as well as frequency and understand if each day falls under the specified criteria. In case the frequency is 0 then I'd like to have it discard the end date at all (in case for some reason I end up forgetting to set the end date).
I have tried to work with the formula provided to account for the frequency but nothing that I tried seemed to work.
Minimal example
Entry on the table with a 2 days frequency:
Expected result on the schedule:
So basically, the formula on each cell should check for the start date, end date and frequency of the activity and identify if the specific date on the schedule falls under the specified timeframe.
In this minimal example, the activity starts on the 7th December and repeats every 2 days until the 14th of December.
Feel free to duplicate the spreadsheet here:
https://docs.google.com/spreadsheets/d/19h0v3XjDqa_DWSx-QBGBNwFGd550a_D3DVFovs5s2qo/edit?usp=sharing
I have tried to build the formula in multiple ways but I can't seem to make it count for the time frequency so that cells recognize this and display the activity in any other dates besides the initial one.
delete all your formulae and use this in C6:
=INDEX(IFNA(VLOOKUP(TEXT(C4:P4+B6:B14, "e-m-d-h-m")&G$2&K$2, SPLIT(FLATTEN(MAP(
Repository!D$4:D, Repository!O$4:O, Repository!P$4:P, Repository!N$4:N,
Repository!G$4:G, Repository!H$4:H, Repository!K$4:K, LAMBDA(d, o, p, n, g, h, k,
IF(DAYS(o, d)>=SEQUENCE(1, MAX(DAYS(o, d)), 0, p), TEXT(d+SEQUENCE(1,
MAX(DAYS(o, d)), 0, p)+IF(ISODD(HOUR(n)), (HOUR(n)*"1:00")-"1:00", HOUR(n)*"1:00"),
"e-m-d-h-m")&g&h&"×"&k, )))), "×"), 2, )))
then copy C6 and paste in C18, C30, etc.

ArrayFormula & Vlookup: exclude the current row from Vlookup range

I'm building a simple booking system using GoogleSheets.
Each entry (Row) is a "booking request".
The intervals being entered on the sheet (via a form) are fixed to 1, 2 or 3 hours (which makes this a "simple booking system"). I'm validating these "booking requests" based on "overlaps" in Start & End Time in a couple separate columns L, M, N.
Sheet Data
The Formula
IF(ROW($A:$A)=1,
"CheckEndDateTimes (1 hour after Start)",
IF(ISERROR(VLOOKUP($E1:$E+1/24,$G$2:$G,1,FALSE)),
"",
"overlaps 1 hour ahead of start"
)
)
)
I'm using ArrayFormula, such that it auto-updates Sheet data as entries are added via a form. I'm using VLOOKUP because it seems to work well with ArrayFormula (as opposed to Index/Match).
The generalized issue:
Column E contains the search_key values (i.e. $E1:$E) (Start Datetime).
Column G contains the range (i.e. $G:$G) (End Datetimes), which I am using to compare intervals (1, 2, 3 hours) ADDED to the search_key value (Column E)
SO far this works fine, EXCEPT that the Row that is being evaluated ALWAYS evaluates to an overlap; clearly, the mere existence of the End Time in the Row being evaluated is always resulting in an overlap.
My Question
Is there a way I can EXCLUDE the current row from the range being evaluated in the VLOOKUP function. (I tried adding "<>", as follows, but it results in NO matches being found:
VLOOKUP($E1:$E+1/24,$G$2:$G<>$G1:$G,1,FALSE)
Or even (to test),
VLOOKUP($E1:$E+1/24,$G$2:$G<>$G$4,1,FALSE)
Any help would be appreciated, Thank you kindly. :)
On reflection I think you need to use countifs to check for any rows with a matching overlapped time and with a row number not equal to the current row like this:
=ArrayFormula(if(A2:A="",,countifs(C2:C,A2:A+1/24,row(C2:C),"<>"&row(A2:A))))
Then you can test whether the result is non-zero and display a message:
=ArrayFormula(if(A2:A="",,if(countifs(C2:C,A2:A+1/24,row(C2:C),"<>"&row(A2:A)),"overlaps 1 hour",)))
and similarly for 2 and 3 hours.
BTW I don't think row three does overlap at one hour.

Google sheets: Is there a way to quickly/easily add a date range to ~300 cells each with different countifs formulas?

I am using the countifs function to add up a lot of different conditions - I need help to simplify the process so that it doesn't require so much manual formatting every time.
Here is a screenshot of a hypothetical spreadsheet. Here is a hypothetical scenario that will help convey my question. Let's say I am working with 3 clients, Macy's, abercrombie, and gap, to fill several open positions. We are reviewing multiple candidates. When I have reviewed them and approved, I select "yes" in the verdict column (E). When they have been processed, I selected yes in the F column. If I do not approve them, I select No in the column. So on and so forth.
So now I'd like to keep track of how many candidates I've approved and processed for each client for each open position. Here is my spreadsheet for that. I have used the countifs function from the previous spreadsheet, called "Review Document" as follows:
Column C, Row 2 - counting sales associate for abercrombie who have been approved and not yet processed:
=COUNTIFS(
'Review Document'!$B:$B,"abercrombie",
'Review Document'!$C:$C, "sales associate",
'Review Document'!$E:$E,"yes",
'Review Document'!$F:$F,"no")
I essentially do this for every single client, for every single role, for both column C and D. Imagine that there are ~300 rows with different companies and roles - The formula text changes every time to count if "position" and "company".
What I would like to do is now find an easy way to automatically apply a date range to all of these cells, without having to manually add a date criterion for every single formula. For example, in the first spreadsheet, there are dates in Feb, Mar, And April. Is there a way to apply a date range on my second spreadsheet so that it only counts the dates I specify? E.G. - apply some date range to ALL cells in that sheet so that it only counts if the date is 2/15/2022-3/31-2022? I would ultimately like to be able to change the date range quickly without having to manually add a date criterion to 300 cells, and then change it every time I want to see the numbers for a different date range. I was tinkering with conditional formatting but I haven't figured it out.
Thanks!
use:
=INDEX(QUERY(QUERY({A2:A, PROPER(B2:C),
IF((E2:E="yes")*(F2:F<>"yes"), 1, 0),
IF((E2:E="yes")*(F2:F= "yes"), 1, 0)},
"select Col2,Col3,sum(Col4),sum(Col5)
where Col1 is not null "&
IF(J1="",," and Col1 >= date '"&TEXT(J1, "yyyy-mm-dd")&"'")&
IF(J2="",," and Col1 <= date '"&TEXT(J2, "yyyy-mm-dd")&"'")&"
group by Col2,Col3"),
"offset 1", ))

Google Sheet Increment Day Count with Interruptions

I have a google sheet that gives me a dynamic day increment. The formula I am using right now is this:
=IF(ISTEXT(A1),1,IF(WEEKDAY(B2)=7,,IF(WEEKDAY(B2)=1,,INDEX(FILTER($A$1:A2,$A$1:A2<>""),COUNT(FILTER($A$1:A2,$A$1:A2<>"")))+1)))
The first part (ISTEXT) checks the cell above to see if it has text...which happens to be the column header. If it does, we start the count at 1. After that, it will increment +1 as long as the date in column B is not a weekend (Saturday or Sunday). If it is, it will leave it blank. Then once it hits Monday again, it continues the count where it left off.
This gives me a dynamic way to count out a 20 work day schedule. I can plug in the start date and it will count out a 20 day work day schedule, skipping weekends. I am trying to add an additional mechanism to incorporate other interruptions to the work day schedule, such as holidays. I have a column (F) that I place notes in. I would like to have something like this incorporated in the original formula:
=if(F2="Holiday","H",<do the other stuff>)
Problem I am having is that everything I did in this original formula is based on empty spaces. Once an H gets placed in the field, it breaks the incrementing. I am thinking maybe I am overcomplicating this or doing something wrong, but hopefully someone can help me out here.
Example: Google Sheets
I duplicated the sheet (see tab JPV_HELP) and entered in B3
=sequence(eomonth(B2, 0)-B2, 1, B2+1, 1)
and in A2
=Arrayformula(if(C2:C<>"", regexreplace(C2:C, "[^A-Z]",), if( (weekday(B2:B) = 1)+(weekday(B2:B) = 7), ,countifs (weekday(B2:B), ">1", weekday(B2:B), "<7", C2:C, "", row(B2:B), "<="&row(B2:B)))))
If anything is entered in column C, the formula will extract the capital letters to output in column A.
See if that works for you?

Automatically transform a log of check-in/check-out events into a time-sheet

UPDATE: Some context: A log that is fed automatically by a IFTTT script contains all check-in and check-outs for employees that work in a factory. I need to build a report with the first check-in for each day, and the last check-out for each day (employees might check-out for lunch, but come back and only the first check-in and last check-out should count).
My current solution is to calculate a "is first checkin or last checkout?" Boolean, and then feed this log into a pivot table for reporting purposes filtering out the repeat entries
My spreadsheet will have data inserted in columns D & E by a third party application (IFTTT or google forms), and I would like to use an arrayformula to automatically calculate one column as data come ins from those applications.
(D)Date (E)Time Calc
January 6, Friday 15:06 TRUE
January 6, Friday 15:15 TRUE
January 9, Monday 8:36 TRUE
January 9, Monday 10:04 FALSE
January 9, Monday 10:37 FALSE
January 9, Monday 15:51 TRUE
The formular for Calc is
=or(MIN(filter(E:E,D:D=D2,B:B=B2))=E2,MAX(filter(E:E,D:D=D2,B:B=B2))=E2)
How can I transform this formula into an arrayformula? From my experimentations it seems that ArrayFormula doesn't mix well with Filter. Help is appreciated!
So, the goal is to determine, for each date, whether the value in column E is the highest or lowest for that date. I think this is too much logic to pack into a single formula, but can be expressed by two array formulas. The first one creates two helper columns:
=arrayformula(vlookup(filter(D:D, len(D:D)), query(D:E, "select D, min(E), max(E) group by D", 1), {2, 3}))
This is itself a combination of two formulas: the inner query gets the minimum and maximum of E for each date in D; then vlookup aligns these min-max values with the rows of the original table. The filtering by len(D:D) is for performance reasons, to avoid looking up a huge number of empty cells.
Suppose the first formula was in G1; then it formed the columns G and H, which leads to E1 being
=arrayformula(not((E:E > G:G) * (E:E < H:H)))
Note that and and or are not arrayformula-friendly, but can be replaced by * and + which result in booleans getting implicitly converted to 0-1. The not function is array-friendly, and is used here partly to get a boolean back from an integer.
Inspired by #zaq, I solved by re-engineering the spreadsheet and got the solution by using the following formula:
=query(query(Sheet1!B:E, "select D, min(E), max(E) group by D pivot C,B ", 1),"select Col1, Col3, Col10,Col4,Col11")
This formula transforms a log of employee check-in and check-outs into a summarized "hours worked" table that contains,for each day, and for every employee, the first check-in and the last check-out.

Resources