How to use "if contains"? - google-sheets

I'm trying to make a scheduler for work and I have a dropdown list of the hours that the employees work in one column and I want it to display how many hours it is next to that. I.e.:
Column B (Selected from a drop down menu) Column C
6:00 - 14:30 to display 8 as it is an 8 hour shift
10:00 - 15:00 to display 5 as it is an 5 hour shift
Is there a way to do this?

So for the sake of clarity, I am going to develop this step by step, in several columns. These could be combined into one impenetrable formula, but that will not help you follow. You can do what I suggest here and then hide the columns with the calculation.
Suppose your time is in column A. You can do the following in the first row (mine assumes row 1, if you have headers, probably row 2) and then copy the formulas on down. In column B, I placed, =search("-",A1), which tells where the - sign is. In column C, I find the first time as a string with =left(A1,B1-2), which takes the first characters up to 2 before the dash. In column D I have =mid(A1,B1+2,5) which takes from 2 characters after the dash to the end (if it is only 4 characters long, it copies 4 not 5),and finally in column E we find the desired result, with =HOUR(timevalue(D1)-timevalue(C1)).
That does what you asked. If you wanted to add minutes you could use =MINUTE(timevalue(D1)-timevalue(C1)). Finally if a 22:00 - 6:00 graveyard shift existed, you would need to add logic for it.
You could also simplify the string calculation by in column B using the formula =split(A1,"-") and then putting =HOUR(timevalue(C1)-timevalue(B1))
And so if you really want a single formula, it could be =hour(INDEX((split(A1,"-")),2)-INDEX((split(A1,"-")),1)), which subtracts the first part from the second and converts to hours.
If in the course of time you want to handle the wrap around midnight, =iferror(hour(INDEX((split(A1,"-")),2)-INDEX((split(A1,"-")),1)),24-hour(INDEX((split(A1,"-")),1)-INDEX((split(A1,"-")),2))) should do the trick.
UPDATE: Sheets recognizes the times that resulted from the split as times. So if in B1 you place =split(A1,"-"), D1 can contain =C1-B1 if you are willing to keep the minutes. It even gives the right answer for 22:00 - 2:00.

Make a table with a column for the shifts (this could be the list used for the Validation, if you chose that method) and a column immediately to its right of the respective shift durations. I named that table Larry. Then in C2 (assuming your first dropdown is in B2):
=ArrayFormula(vlookup(B1:B,Larry,2,0))

Related

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?

Lookup a value in Column B or C and return key in Column A

I am trying to write a formula that will look for a value in a column, and return the first cell in the row in which it finds the value. So a little like VLOOKUP, but I don't want to search the the first column.
Here is an example dataset:
Room
Monday
Tuesday
DWG 1
S01
S02
DWG 2
S02
S04
DWG 3
S03
S06
DWG 4
S04
S07
Here is what I would like to generate using a formula.
So for the value at B2, I would like it to look up A2 ("S01") in the B column ("Monday") of the top table, and return the value of the cell in the 1st column ("DWG 1").
Ideally it would return nothing or a blank if it doesn't find the exact string in the top table.
Section
Monday
Tuesday
S01
DWG 1
S02
DWG 2
DWG 1
S03
DWG 3
S04
DWG 4
DWG 2
S05
S06
DWG 3
s07
DWG 4
After seeing your in-sheet data and layout, and meeting up with you there live, this is the formula I left for you in the newly added sheet "Erik Help":
=ArrayFormula({"S"&TEXT(SEQUENCE(24,1),"00"),IFERROR(VLOOKUP(FILTER(B1:1,B1:1<>"")&"S"&TEXT(SEQUENCE(24,1),"00"),SPLIT(FLATTEN(FILTER(Sheet1!B1:1,Sheet1!B1:1<>"")&FILTER(INDIRECT("Sheet1!B3:"&ROWS(Sheet1!A:A)),Sheet1!B1:1<>"")&"|"&FILTER(Sheet1!$A3:$A,Sheet1!$A3:$A<>"")),"|"),2,FALSE))})
For the understanding of others, the days of the week (i.e., Monday, Tuesday...) are entered manually as top headers in B1:F1. The header "Section" is entered in A2 with B2:F2 blank. (This is just how the OP wanted it set up.) And the formula is in A3, processing data for A3:F.
The first part of the virtual array just generates the SEQUENCE of section names (S01 - S24) in A3:A26.
The next part looks up every element of one array within another array. The first array is a concatenation of every weekday with every section number from Column A. The second array didn't technically need to be as long as it is in the formula, because we already know exactly how many weekdays, classrooms and sections there are. But it is written to accommodate flexibility, perhaps for future use where four or six days are required, with more or fewer sections.
That second array concatenates every weekday with every section from Sheet1 followed by a pipe symbol and the room for each row from Sheet1. That grid is FLATTENed to one column, and then SPLIT to two columns at the pipe symbol.
Found elements, then, return the class name (which was SPLIT to Column 2 of the virtual VLOOKUP array). If there is no match, IFERROR returns null.
The shorter version possible since we know exactly how many days, sections and rooms we have (and which I left in a new sheet called "Erik Help 2") is this:
=ArrayFormula({"S"&TEXT(SEQUENCE(24,1),"00"),IFERROR(VLOOKUP(Sheet1!B1:F1&"S"&TEXT(SEQUENCE(24,1),"00"),SPLIT(FLATTEN(Sheet1!B1:F1&Sheet1!B3:F17&"|"&Sheet1!A3:A17),"|"),2,FALSE))})
The function you're looking for doesn't exist in Sheets as Vlookup match is performed horizontally from left to right. However, a workaround is to rearrange the columns within the function QUERY and perform a Vlookup to it
Here's an example formula you can use =iferror((vlookup("S01",QUERY(A2:C, "Select B,A",0),2)),"")
This will also leave the cell blank if there are no matching results.
Here's an example of what the end result would look like when I the string "S01" is Vlooked up:

A formula to add one hour to the cell above in Google Sheets

Often I want to quick fill of a list of time similar to how I put a 1 in A1 and then in A2 I place A1 + 1 to get two and then I copy that down the next 100 cells to get from 1 to 100. I want to do the same thing with time. It also gives me the advantage of change the first cell and updating all the times. I asked this partly because the other answers are more complex and never get to a simple solution for this kind of process that is so often used.
to populate rows with numbers from 1 to 100 use:
=SEQUENCE(100)
to get time intervals use:
=INDEX(TEXT(SEQUENCE(12, 1, 0, 2)*"1:00:00", "hh:mm:ss"))
=INDEX(TEXT(SEQUENCE(
12 +N("number of rows"),
1 +N("number of columns"),
0 +N("start from midnight"),
2 +N("interval of increase"))
*"1:00:00" +N("period of increase"),
"hh:mm:s" &N("time format")))
Working through https://spreadsheetpoint.com/add-time-in-google-sheets/ I came up with:
Make sure the cells you are working with are in the time format you desire.
Place the time you want to start with in the first cell, let's say A1
To add an hour to the time in A1, use =A1+60/(24*60), let's say in A2
Now you can copy A2 down as far in column A you desire to get the time.
Notice, the 60 in the formula =A1+60/(24*60) is the number of minutes. Hence, if you want to do a half-hour, you can use 30.

Google Sheets - IF Statement Formula

I need to write a formula that enters 'Y' if the patient is up to date with their immunizations based on their record and age, and 'N' if they are not. Age (D$) is in months and I have a column for every immunization (8 weeks(E$), 12 weeks(F$), 16 weeks(G$), 1 year(H$), 3 years and 4 months(I$)) which is marked as either ("Y" or colored Grey) as well as a final column which the formula is being entered into(J$). Any ideas what formula I need to use?
So far I have been thinking to use an IFS statement { =IFS(D$>=2, AND(E$="Y"),"Y")}. Although I can see the limitations to using this.
For every immunization, the patient is not up to date if the corresponding cell is blank and their age is older than the immunization date. You want to check this for multiple immunizations. You can use COUNTIFS to evaluate two (or more) conditions.
=IF(COUNTIFS(E3:I3,"",E$1:I$1,"<="&D3)>0,"N","Y")
Explanation:
COUNTIFS returns the number of shots for which the patient is not up to date.
IF returns N if the previous value is greater than 0, Y otherwise.
Note that I'm assuming the information on the number of months corresponding to each immunization (E$1:I$1 in the formula above) is present somewhere in the sheet or that you can add it. If this is not the case, you would indeed need to use IFS or something similar.

Repeat row wise a string number of times in corresponding column

Here is a screen shot of some data:
I would like to build a new column that is the the string in column A the total number of times it occurs.
So entry "Too expensive" would be on 26 rows then under that would start "Don't want it" taking up 6 rows, then "too expensive" (different since lower case) would take up another 6 + 5 from row 14.
So just a new column that is each string the number of times it appears. Inverse pivot tabling, if you will.
How would I do that? I tried playing with rept() but that put everything in one cell.
It looks like most likely you first need a helper column to basically unique the values so in column C you would put :
=UNIQUE(A:A)
and for the sake of explanation, if you want to see how it breaks down, in column D you can put
=sum(FILTER(B2:B,exact(C2,A2:A)))
The reason for using exact , is that otherwise it wont be case sensitive.
Once you have your final number for the REPT function you consutruct your repeatable value with a delimiter:
=rept(C2&";",D2)
This helps out split them out properly later into a column, if you rept the value with out the semicolon you will see the same result your describing up top where they are all mashed together.
Currently at this point this is what you would see:
To save some space I nest the sum filter into the rept function so I can remove column D:
=REPT(C2&";",sum(FILTER(B2:B,exact(C2,A2:A))))
I then join all those and split them out one last time using the ; as a delimiter:
=TRANSPOSE(SPLIT(JOIN(";",D2:D4),";"))
Alternatively, see if this works ?
=ArrayFormula(trim(transpose(split(query(rept(A2:A&char(10),B2:B),,50000), char(10)))))

Resources