Google Sheets: Lookup last matching values but with expanding rows - google-sheets

I'm using a dynamic, expanding sheet containing form responses. Search keys are in A2:A, responses are in the Responses sheet. So,
To get an expanding VLOOKUP, I do:
=ARRAYFORMULA(VLOOKUP(A2:A, Responses!A2:C, 3, 0))
To get the last matching value (for example, latest timestamp) of a repeating search key, I use a combination of FILTER, MAX, and INDEX like so:
=INDEX('Responses'!C2:C, MAX(FILTER(ROW('Follow-up Responses'!A2:A), 'Responses'!A2:A=A2)))
And this works by just dragging it down, but is there a way to make this expanding in an ARRAYFORMULA function? I tried modifiying it as ranges but all I get is one row. My form responses are added quickly so there may come a time where the formula has not been dragged down to the most current.
Thanks!

Sample formula with lookup of last value using row:
=VLOOKUP(D2 ; SORT(FILTER({$A:$B\ROW($A:$A)};$A:$A<>"");3;0) ; 2;)
D2 -- search value
A:B -- initial
row(A:A) -- any row for getting last values in the top.

Related

How to get last number in a row on Google Spreadsheets

Spreadsheet
So Basically i'm building a sheet to monitor my NW, my problem is simple, i need the 2023 column to adapt to whatever last number on that row there is, for income i just sum values, but for example the total amount in my bank account is different every month, i just need 2023 column to track that, i update the 31 of each month.
With the formula you can see in the screenshot i have some problem, if i input the number alright, if the value is defined by other formulas it won't show up. Any solutions?
THANKS
Only formula present in the row
Another formula from the comments that seems to not work
I tried =INDEX(X:Y;1;COUNTA(X:Y)) but it won't update if the last number in the row is generated by other formulas.
You can use this formula to find the last value of each row in the range D2:O26. Adapt it as needed!
=BYROW(D2:O26,LAMBDA(e,XLOOKUP(1,INDEX(1/(e<>"")),e,,0,-1)))
Explanation:
BYROW creates an array formula in each row of the range. To each row, here denoted as e, the specified lambda function is applied.
INDEX(1/(e<>"")) returns an array with 1 in places where cell is not empty, and #N/A for empty cells.
XLOOKUP finds the index of the last occurrence (parameter search_mode set to -1) of 1 (first parameter) in the array returned by INDEX and returns corresponding value in the row.
You haven't show what formula in columns Jan-Dec causes you problems. If formula produce values 0 in case you don't what them to count, you can use countif to filter them out:
=INDEX(D13:O13,1,COUNTIF(D13:O13,">0"))
Same as your solution, this only works if columns are filled sequentially - if there are no gaps in each row, e.g. Jan and Mar are filled while Feb is blank.
If you need a more general solution, you may go with series of nested if(isblank(). Here is an example for the first three months, to get an idea:
=INDEX(D13:O13,1,IF(ISBLANK(F13),if(ISBLANK(E13),1,2),3))

Google Sheets Fill Down with Formula

I have a very hard problem to solve, which must be completed with a formula (not a script).
Basically, the Raw input column needs to be dynamically filled down until it hits the next piece of text.
Here's an example file with includes the expected output.
https://docs.google.com/spreadsheets/d/1ibqCvY39NlhCRWsbBdxKITUUpVpp9wXdEz44T-pHDY0/
Is it even possible to achieve?
Thanks
This will work based on your ask, assuming that A2 is never blank, place this in the first row of data (not header):
=ArrayFormula(IF(A2:A<>"", A2:A, B1:B))
It checks to see if there is a value in column A, if there is, it fills that column, if not, it copies the cell above.
Delete everything in Column B (including the header) and place the following formula in B1:
=ArrayFormula({"Header";VLOOKUP(FILTER(ROW(A2:A),ROW(A2:A)<=MAX(FILTER(ROW(A2:A),A2:A<>""))),FILTER({ROW(A2:A),A2:A},A2:A<>""),2,TRUE)})
Here is a basic explanation of how this formula works:
A virtual array is created between the curly brackets { }; this virtual array contains a header and all results. You can change the header name to whatever you like.
VLOOKUP looks up every row number that is less than or equal to the highest row number that contains text in A2:A. Each of these qualifying rows is looked up in a second array that contains only the row numbers and Column-A data from non-blank rows, returning the data itself. Since rows are in perfect ascending order and the last parameter of VLOOKUP is set to TRUE, all blank rows in the first array will "fall backward" to find the most recent row that did have something in Column A.

Compare two tab's headers, copy column below maintaining blank columns

I have two tabs, one with all of my column headers (data tab), the other tab with less headers, but all from the data tab.
I want to search the headers of the "data" tab using the headers from the second tab starting at column I through BI. The second tab's headers will periodically change but always be present in the data tab. If the search criteria isn't present, I want to leave that column blank. If it is present, return the values below from the data tab.
I've tried a few formulas, but can't quite get what I'm looking for.
This formula worked to find the data:
'FILTERED'!I2
=FILTER(data!I2:AK,COUNTIFS($I$1:$1,data!I1:AK1))
This formula got the placement right, but produced the wrong information:
'Copy of FILTERED'!I3
=ArrayFormula(IF(ISBLANK(I2:2),,FILTER(data!I2:AK,COUNTIFS($I$1:$1,data!I1:AK1))))
Here's my sheet.
You've got a large range to process, so there may be a slight delay filling the grid by formula (2 or 3 seconds maybe). But I have added a sheet ("Erik Help") with the following formula in I2:
=ArrayFormula(IF(ROW(A2:A),IFERROR(VLOOKUP(ROW(data!A2:A),{ROW(data!A2:A),INDIRECT("data!I2:"&ROWS(data!A:A))},HLOOKUP(FILTER(I1:1,I1:1<>""),{data!I1:1;SEQUENCE(1,COLUMNS(data!I1:1),2)},2,FALSE),FALSE))))
Honestly, it's hard to explain how this works, but I'll try to cover the basics.
=ArrayFormula(...)
This just means the formula will be processing a range rather than one cell.
IF(ROW(A2:A), ... HLOOKUP(FILTER(I1:1,I1:1<>""),{data!I1:1;SEQUENCE(1,COLUMNS(data!I1:1),2)},2,FALSE) ...)
IF(ROW(A2:A) is important, because it signals to do something for every row, thereby creating a 2D grid instead of just processing the current row. The HLOOKUP will look up every header in I1:1 that isn't blank [FILTER(I1:1,I1:1<>"")], which as the sheet is now, will be all of them. They will be looked up in in a virtual array formed from a top row consisting of all headers in data!I1:1 over a bottom row made up of a SEQUENCE of numbers made of 1 row and the same number of columns as are in data!I1:1, starting at the number 2 and moving up. (It starts at 2, because part of the VLOOKUP virtual array which I haven't explained yet, will be forming a column 1.)
VLOOKUP(ROW(A2:A),{ROW(data!A2:A),INDIRECT("data!I2:"&ROWS(data!A:A))}, *the HLOOKUP RESULT NUMBER*,FALSE)
Now a VLOOKUP will kick in. It will look up every row in data!A2:A within a virtual array made of two columns; the first column will be those same row numbers, and the second will be everything from data!I2 over and down (the INDIRECT setup allows this to be a dynamic grid in case you add or delete columns later). As to which column from that should be returns, that will pull from the HLOOKUP results explained above (which, as you'll recall, will all match the headers).
Finally, IFERROR(...) will return null if any step in that process returns an error, which would be because something wasn't found.
see:
=ARRAYFORMULA(QUERY(VLOOKUP(ROW(A2:A), {ROW(A2:A),
A2:C},
MATCH(HLOOKUP(E1:G1,
{E1, F1, G1;
B1, A1, C1},
2, 0), A1:C1, 0)
+1,
0),
"select *"))
for missing headers:

Why can INDEX(...,COUNTA(...),..) find the last value of one array, but not another?

I'm learning basic =ARRAYFORMULA usage for a finance spreadsheet:
https://docs.google.com/spreadsheets/d/12cAGuUBzIo0LPbmtqWJZNFgjt94f1ybGoj6x2g0c2Y0/edit?usp=sharing
First, I used =GOOGLEFINANCE at B1 to pull up stock prices for a given date range in Column C
=GOOGLEFINANCE(A1,"price",DATE(2020,1,1),DATE(2020,5,30),"DAILY")
Then, I used simple arithmetic to multiply by number of shares at D2 and dragged the formulas down to get a nice column of values
=C2*20
Then, I used INDEX and COUNTA to pull out the last value of Column D at F3 === Great!
=INDEX(AAPL!D2:D,COUNTA(AAPL!D2:D),1)
Next, I turned my arithmetic formula into an ARRAYFORMULA at G2 === Cool!
=ARRAYFORMULA(C2:C103*20)
Of course, the problem with that ARRAYFORMULA is that I would have to manually change the array name in G2 every time the date range updated.
That is, instead of C2:C103, I would need to change the reference to C2:104 to get the columns to match === Rookie mistake!!!!!
So, I got smart with an ARRAYFORMULA containing a IF(ISBLANK(),...,...) at J2
=ARRAYFORMULA(IF(ISBLANK(B2:B),"",C2:C*20))
Column J stays fully populated with the correct values for any date range === !!!!!!!
But now the =INDEX(AAPL!J2:J,COUNTA(AAPL!J2:J),1) at L3 can't find the last value in Column J
Whaaat???
I've tried everything I can think of
It works if I use =INDEX(AAPL!J2:J104,COUNTA(AAPL!J2:J104),1) but that would defeat the purpose, since the reference J:J104 is going to change as the dates change
WHY???
I get the same results in both cells "L3" and "L5" when using:
=ARRAYFORMULA(IF(ISBLANK(B2:B),,C2:C*20))
Check that you are not returning a blank string ("") in your IF like: "=ARRAYFORMULA(IF(ISBLANK(B2:B),"",C2:C*20))" doing so will fill the cells up to the last row in the sheet with empty strings, thus when you use COUNTA(AAPL!J2:J),1) you get a lot more cells than you would expect, these extra cells are the ones you filled with blank strings in the array formula.
On the contrary when you limit the =INDEX(AAPL!J2:J104,COUNTA(AAPL!J2:J104),1) to cells with numbers only it doesn't mix strings and numbers in the calculation and you are naturally get the expected results.

Sort the value of a column with a relative position (using an other column data order)

I've created a form to collect data from user A in a sheet and reformat it for user B in the other sheet.
I have to sort the data for user B. I'm using vlookup to sort the column of values from the form to a new sheet (sort based on the order of the 'value description column'). It's working.
My problem is that when a new column is added to the first sheet (the form) the column range is modified and the index parameter in vlookup is not good anymore. So I lost everything on my second sheet.
How can I do to have a solid link with the column in the first sheet even if it's position change?
you can make use of INDIRECT with COUNTA and SUBSTITUTE. something like:
=INDIRECT("Sheet1!A1:"&SUBSTITUTE(ADDRESS(1, COUNTA(Sheet1!1:1), 4), 1, "")
this will count non-empty cells in row 1 of Sheet1 and converts that number to later which is used in constructing the range put together by indirect formula and all of it can be placed in vlookup as same as you would place any ther regular range.

Resources