I have a Google Sheet with two sheets in it.
The first sheet is a list of songs with Title, Library #, Composer, ..., Last Performance Date
The second sheet is a list of performance dates with Title, Library #, date 1, date 2, ..., date n
Sheet 1 Example:
Title, Library #, Composer, Last Performance Date
Hip Song 1007 David {formula}
Slow Song 1002 Bob {formula}
Other Song 1004 David {formula}
Sheet 2 Example:
Title, Library #, Dates ->
Slow Song 1002 2021-01-12 2021-02-15
Other Song 1004
Hip Song 1007 2021-01-05
How can I automatically fill in the "Last Performance Date" column on the first sheet by looking up the song on the second sheet by the "Library #" and getting the last value in that row (with a variable number of dates per song on the second sheet).
With the example above, the Last Performance Date for "Hip Song" would be "2021-01-05", "Slow Song" would be "2021-02-15", and "Other Song" would be "" (an empty string or nothing).
For any given song, there could be no dates on the second sheet or a 100+ dates on that song's row.
I'd add a helper column to Sheet2 that contains the formula that calculates the "latest" date for a given song:
Sheet2
A
B
C
D
E
1
Title
Library #
Latest Date
Dates
2
Slow Song
1002
=IF(MAX(D2:E2)=0,"",MAX(D2:E2))
2021-01-12
2021-02-15
3
Other Song
1004
=IF(MAX(D3:E3)=0,"",MAX(D3:E3))
4
Hip Song
1007
=IF(MAX(D4:E4)=0,"",MAX(D4:E4))
2021-01-05
The IF(X=0,"",X) part of the formula is so that songs that don't have any dates show up as blank instead of 0 (which will get formatted as 1899-12-30).
Then, in Sheet1, use the VLOOKUP function to find the matching "latest date":
Sheet1
A
B
C
D
1
Title
Library #
Composer
Last Performance Date
2
Hip Song
1007
David
=VLOOKUP(B2,Sheet2!$B$2:$C$4,2,FALSE)
3
Slow Song
1002
Bob
=VLOOKUP(B3,Sheet2!$B$2:$C$4,2,FALSE)
4
Other Song
1004
David
=VLOOKUP(B4,Sheet2!$B$2:$C$4,2,FALSE)
Note the FALSE as the last parameter to VLOOKUP, which makes sure it will still return correct results, even if the data in Sheet2 is not sorted by Library #.
See this example spreadsheet.
if your dates (if present) are increasing with each next column try:
=INDEX(IF(B2:B="",,IFERROR(1*SPLIT(FLATTEN(QUERY(TRANSPOSE(IFNA(VLOOKUP(B2:B, Sheet2!B1:1000,
TRANSPOSE(SORT(SEQUENCE(COLUMNS(Sheet2!C1:1))+1, 1, 0))), 0)),,9^9)), " "))),,1)
demo spreadsheet
fx transcript: count columns from column with 1st date and create a sequence of number with +1 offset for each number. then sort the sequence in descending order and transpose it into row - this will be the 3rd parameter of vlookup which will return date columns in reverse order eg.: ..., Col5, Col4, Col3, Col2. so in vlookup we look for B2:B values in range Sheet2:B1:1000 and return multiple columns on each match. next, we transpose all results of vlookup and with query parameter ,,9^9 we collapse all rows of each column into a single row. next, we flatten the results and split by empty space (which was inserted after each date via query). in this stage, column with the latest date became our 1st column. next, dates are numeric values so we multiply them by 1 to catch errors of those cells that have no date only empty spaces. at last, we use simple if statement to check if B2:B range is empty. if so we return no value, otherwise we return date. and to limit the output only to 1 single column we use index to return all rows but only the first column
Related
We have two tables in Google Sheets.
First:
Date
Amount
Currency
Worth
01.01.2021
100
USD
373
02.01.2021
100
EUR
451
03.01.2021
100
PLN
100
04.01.2021
100
USD
373
05.01.2021
100
USD
372
Second:
Date
PLN
EUR
USD
01.01.2021
1
4,50
3,73
02.01.2021
1
4,51
3,75
03.01.2021
1
4,50
3,74
04.01.2021
1
4,48
3,73
05.01.2021
1
4,49
3,72
I tried find array formula for first table, column Worth. Formula should take proper value from second table (based on two columns from table one - Date and Currency) and multiply that values by worth in column Amount. I really want to use array formula. Is it possible?
Use VLOOKUP to find the correct date row and MATCH to find which column the value is in:
=ARRAYFORMULA(IFERROR(VLOOKUP(A2:A,I2:L,MATCH(C2:C,I1:L1,0))*B2:B))
Option 01: Getting the result with one cell one formula.
Paste this in B3 "Amount" column in the first table, take a look at this Sheet.
=ArrayFormula(IF(ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))="",,ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))*E3:E))
Explanation ...
1 - MATCH(D3:D,$H$2:$J$2,0) To get the index you want to VLOOKUP the "Currency" column from the second table with, we need that in the next step.
2 - VLOOKUP the "date" found in First table A3:A from Range in the second table G3:J, with Index set to MATCH(D3:D,$H$2:$J$2,0), and [is_sorted] set to 0
3 - till now we have the value of the exchange rate if we can call it that for each Currency chosen in the first Table, we need to multiply it by Worth to get Amount
ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))*E3:E is structured like this Exchange rate * Amount note that E3:E is the Amount, and this IF(A3:A="",, to calculate only when A3:A range is not blank.
4 - ArrayFormula and a IF is needed to be wrapped around like this ArrayFormula(IF(Range=Empty,Do nothing,formula)
Range:
ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))
Empty
""
Do nothing :
,,
Formula:
ArrayFormula(IF(A3:A="",,VLOOKUP(A3:A,G3:J,ArrayFormula(IF(D3:D="",,MATCH(D3:D,$H$2:$J$2,0)+1)),0)))*E3:E
Option 02: Getting the result with intermediate steps.
Same as option 01 but in seprate columns take a look at this Sheet.
I am trying to find a way to see which employees are not working between 2 dates.
Should I use vlookup, index & match, filter, query, or something else?
Sheet 1 contains employee details & start/end dates.
Sheet 2 accepts user input to select 2 dates, and it will automatically display a list of available employees who are not working.
Sheet 1 - Database/Log of all employees and days worked.
#
A
B
C
D
1
ID
Name
Start Date
End Date
2
12345
John
01/01/2021
01/08/2021
3
54321
Sarah
01/24/2021
01/29/2021
4
00731
James
02/05/2021
02/15/2021
5
00731
John
02/10/2021
02/30/2021
Sheet 2 (Row 1-2)- Manually enter in two dates.
#
A
B
1
Start Date (Manual input)
End Date (Manual input)
2
01/01/2021
01/30/2021
Sheet 2 (Row 3+)- List of all employees that are not working between the two dates entered in Sheet 2!A2:B2 (Expected Results)
#
A
B
3
ID
Name
4
00731
James
try:
=INDEX(SUBSTITUTE(UNIQUE(QUERY(""&SPLIT(FLATTEN(IF(SEQUENCE(1, MAX(D2:D-C2:C))<=D2:D-C2:C,
"♥"&A2:A&"♦"&B2:B&"♦"&C2:C+SEQUENCE(1, MAX(D2:D-C2:C), 0), )), "♦"),
"select Col1,Col2 where not Col3 matches '"&JOIN("|", "^$",
IF(SEQUENCE(1, G2-F2)<=G2-F2, F2+SEQUENCE(1, G2-F2, 0), ))&"'", 0)), "♥", ))
demo sheet
Assuming the name of your first sheet with the full data is actually Sheet1, place the following in Sheet2 cell A4:
=FILTER(Sheet1!A2:B,Sheet1!A2:A<>"",(Sheet1!C2:C>G2)+(Sheet1!D2:D<F2))
The combined either/or condition (Sheet1!C2:C>G2)+(Sheet1!D2:D<F2) in the FILTER means "either the start date is after the range date given, or the end date is before the range date given."
The other condition of Sheet1!A2:A<>"" just rules out blank rows in the original data set. It's not strictly necessary as far as the visual results are concerned; but it keeps null rows from being added to those results, which would allow you to enter data below the results in Col A and B of Sheet2 if you wanted, or to have fewer rows in Sheet2 than in Sheet1 without the formula adding more rows to accommodate null returns.
Your posted sample data is unclear. You have two different names for the same ID (i.e., 00731). And you have an "End Date" in D5 of February 30, 2021—which is not a valid date. In any case, it's unclear whether the same person/ID may turn up twice in the original data set. My formula above assumes you will not.
If your original data list may, in fact, contain duplicates, things get a bit trickier. In that case, use the following formula instead, in Sheet2 cell A4:
=UNIQUE(FILTER(A2:B,ISERROR(VLOOKUP(A2:A,FILTER(A2:A,((C2:C>=F2)*(C2:C<=G2))+((D2:D>=F2)*(D2:D<=G2))),1,FALSE))))
Here, the inner FILTER first forms a list of all people who are working during that range, and then the outer FILTER filters in a UNIQUE set of the people who are not on that inner list (i.e., trying to VLOOKUP them returns IS(an)ERROR).
I need an array formula only in column Date_2 with results like on screenshot and that will
insert last day of month depending on Date_0 (if bunch of Color&Fruit&Meal doesn't repeat in table)
insert first minimum date of column Date_1 (if bunch of Color&Fruit&Meal repeats first time) - 1
insert second minimum date of column Date_1 (if bunch of Color&Fruit&Meal repeats second time) - 1
and so on...
Is is possible to solve it with array formula?
I've tried but I can't..
=ArrayFormula(IF(A2:A="","",IF(COUNTIF(B2:B&C2:C&D2:D,B2:B&C2:C&D2:D)>1,INDEX(FILTER(B2:E,E2:E<>""),1,4),EOMONTH(A2:A,0))))
Google Sheets
I'm not quite sure what you need for Date_1 but try this arrayformula in cell F2 for Date_2:
=ARRAYFORMULA({"Date_2";if(IF(B2:B&""&C2:C&""&D2:D<>"",if(A2:A<>"",COUNTIFS(B2:B&"|"&C2:C&"|"&D2:D,B2:B&"|"&C2:C&"|"&D2:D,ROW(A2:A),"<="&ROW(A2:A)),),)=1,eomonth(A2:A,0),)})
I've added a duplicate sheet ("Erik Help") with the following formula in F1:
=ArrayFormula({"Date_2";IF(A2:A="",,IFERROR(VLOOKUP(B2:B&C2:C&D2:D&TEXT(COUNTIFS(B2:B&C2:C&D2:D,B2:B&C2:C&D2:D,ROW(A2:A),"<="&ROW(A2:A))+1,"000"),{B2:B&C2:C&D2:D&TEXT(COUNTIFS(B2:B&C2:C&D2:D,B2:B&C2:C&D2:D,ROW(A2:A),"<="&ROW(A2:A)),"000"),E2:E},2,FALSE)-1,EOMONTH(A2:A,0)))})
This formula creates the header (which you can change within the formula) and all results for Column F.
To lookup the "next instance of the group if there is one," I just wrote the formula to VLOOKUP that grouping plus a text rendering of the COUNTIFS-as-of-that-row-plus-1 for that grouping within a virtual array of each-grouping-plus-unique-count-thus-far in one column and the E2:E data in the next column. For instance, for Row 2, the formula VLOOKUPs redapplepie002
(002 being the text rendition of 001, which is the count of redapplepie as of row 2).
I have one column with Name.
I have a 2nd column with Date associated with a visit.
I wanted to generate a count of how many times the person has visited in a previous number of days.
If the number is greater than X, I want to fill another column with match.
I'm having trouble figuring out how to filter out names that don't match the row, while simultaneously counting how many times that person has dates that fall within the 7 day range.
So if John visited on 1/23, 2/4, 2/6, and 2/8, and the range is 7 days, it should add "3" to the "recent visits" column next to John's 2/8 row, fill 2 into the "recent visits" column for 2/6, and 1 for 2/4 and 1/23.
There will be other rows with other names that will have the same requirements, so it would also need to filter out names that don't match John.
What I'm trying to do with this, is trigger an alert through Zapier to send an email when there is a frequent visitor match.
cell C2: =UNIQUE(FILTER(A2:A, A2:A<>""))
cell D2:
=COUNTA(QUERY(ARRAYFORMULA($A$2:$B),
"select A where B >= date '"&TEXT(TODAY()-7, "yyyy-mm-dd")&"'
and B <= date '"&TEXT(TODAY(), "yyyy-mm-dd")&"'
and A = '"&C3&"'", 0))
and drag down from D2 cell
Do you have a suggestion on how to make a formula for the problem written in the title?
Here is the example so that you can get an idea of the data format:
Name,Location,Category,Total views for your listing,Total uniqe page views for your listing,Average time on page (listing),total,Facebook,Reviews,Telephone,Treatment Menu,Get Directions,Book Appointment,Enquiry,Instagram,Date
John,NSW Sydney,Apple,1,1,0:00:12,0,0,0,0,0,0,0,0,0,13/Nov/2018
Mike,NSW Sydney,Orange,1,1,0:00:10,0,0,0,0,0,0,0,0,0,13/Nov/2018
Kenny,NSW Sydney,Pear,1,1,0:00:00,4,1,1,1,1,0,0,0,0,13/Nov/2018
John,NSW Sydney,Apple,20,1,0:00:12,0,0,0,0,0,0,0,0,0,14/Nov/2018
Chris,NSW Sydney,Orange,1,1,0:02:48,3,0,0,1,1,1,0,0,0,14/Nov/2018
Stef,NSW Sydney,Orange,10,1,0:07:22,6,1,1,0,1,0,1,1,1,14/Nov/2018
So, the issue is in making a formula that gets put into cells containing numerical values (from D to O), for each of the Name rows.
What it should look like is:
for John and for 13th and 14th of November, the cell in column B in that row should be 21
for Mike for 13th and 14th, it returns 1
for Jenny, which is not on the list, because she didn't have any values in any of the numerical columns for that day (or a group of days), it should return 0
All of these should appear in the "Main Dashboard" sheet, while the data is stored in the "directory statistics" sheet.
The predefined list of all the possible Names, Categories and Locations is in the "customList" sheet. This means that we don't need to search through the whole dataset of all the values for all the dates, but rather only search through the Names in the "customList". "Name" should be the key value that connects values in different dates.
So far, I have tried with this formula:
=Filter('directory statistics'!A2:A,'directory statistics'!$P2:$P=$P2)
It looks for the name column (A) and then returns the value if the date entered (in P2) matches the value in that sheet for the date column (P)
And then I got stuck! :)
Thank you!
I'm not sure why FILTER. Assuming Name in A1, and Row 1 and ColumnA in Main Dashboard set up as in my image, then:
=SUMIFS('directory statistics'!D$1:D$7,'directory statistics'!A$1:A$7,$A2,'directory statistics'!P$1:P$7,">="&B$1,'directory statistics'!P$1:P$7,"<="&C$1)
in B2 and copied down would appear to me to achieve the results you seek.