Working with hierarchical data in Google Sheets - google-sheets

If I have hierarchical data in a Google Sheet as in columns A and B in the example below, how can I write a formula that will fill the corresponding cells in column C with the product of the "parent" value in A1, and the "child" values in column B. That is, The formula in C8 for example, will search upward in column A until it finds the value 5 in A6, then multiplies it by 8, the value in B8.
Obviously I'm trying to avoid having to put the "parent" value in every row in column A.

After a fiddling around and jogging my memory on ArrayFormulas I figured out how to get the result I wanted. Here's the formula I'm using:
=ArrayFormula(index($B$2:$B2,MAX(IF(ISNUMBER($B$2:$B2),ROW($B$2:$B2)))-1,1))
(Note: Row 1 contains headings)
Edit: Explanation of how I arrived at this solution:
Ordinarily, IF(ISNUMBER(cell)), and ROW(cell) would return TRUE/FALSE, or a row number respectively. When used in an array formula and a range of cells as input instead, what you get is a list of TRUE/FALSE values, and row numbers evaluated for each cell in the input range. Wrap MAX around that and it will return the position in those two lists where IF(ISNUMBER()) is TRUE and the row number returned by ROW() is the highest, effectively searching from the bottom of the range.
The absolute reference for the first element in the range to be searched (in this case $B$2) keeps the range anchored to the same starting location when dragging the formula into other cells, while the lower bound of the range (in this case $B2) to be searched grows vertically.
Finally, the INDEX takes the input range, row number returned by the above (-1 row because of the header) and column position (1, since there is only one column) in order to return the desired value.

One way you could do this would be to associate each value in column B with a category or key that can be used to lookup the value for A in a separate table. This abstracts it somewhat, so you can change the values for the A column without having to have them in every row, but there's no empty cells.
i.e.
and lookup table:
In column C
= VLOOKUP($A1, <range for category lookup table>, 2, 0) * $B1
(And then this formula can be filled down)
More on VLOOKUP in Google Sheets here
Alternatively I suppose you could use a formula to find the last non-empty row in column A, or something along those lines, but this is more of a hack than a proper way to structure your data. Tables aren't really designed to be used in a hierarchical fashion like what you've shown. But they can easily represent hierarchical data using techniques like what I've suggested.

Related

How to count rows between 2 non empty cells with their intermediary empty cells in Google Sheets?

I'm trying to count each rows of empty cells between two non-empy cells and adding the upper non empty-cell count (or the lower non-empty cells count) to the result when the empty cells/rows numbers are variable and irregular in this manner:
A1 Empty
A2 Non-empty
A3 Empty
A4 Empty
A5 Empty
A6 Empty
A7 Non-empty
(with A2 to A5 being irregular — could be any number of intermediary empty rows/cells — i.e. 10, 2, 30, 5, etc., and variable — could be located in any location within Column A)
The result should return as follow:
=IFS(
AND(A2="",A3=""),"",
AND(A2="",A3<>""),"",
AND(A2<>"",A3<>""),ROWS(A2),
AND(A2<>"",A3=""),ROWS(A2:UP TO NEXT NON-EMPTY ROW BENEATH (NOT COMPRISED (or minus the next non-empty row(-1)))
How do we program Google Sheets to count rows "UP TO NEXT NON-EMPTY ROW BENEATH (NOT COMPRISED (or minus the next ono empty row(-1)) when the emppty intermediary rows' count is variable/unknown for each occurence and irregular/can be any number of intremediary rows?
I have this data as example:
So far, I've come up with this partial solution:
=IFS(AND(A2="",A3=""),"", AND(A2="",A3<>""),"", AND(A2<>"",A3<>""),ROWS(A2), AND(A2<>"",A3=""),ROWS(A2:UP TO NEXT NON-EMPTY ROW BENEATH (NOT COMPRISED (or minus the next non-empty row(-1)))))
The expected result should return as follows:
The Sheet copy:
https://docs.google.com/spreadsheets/d/1eLXdFINKVtS5Fxon8mIQDmBUTZokyY_Fb6tfWJRDOVI/edit?usp=sharing
Well I think you can do it a bit more elegantly using a reverse lookup. The idea is to sort the data on descending order of row number, then use a match with -1 as the last parameter, which is equivalent to searching from the end of the data for the next non-blank.
=ArrayFormula(iferror(if(A2:A="","",rows(A2:A)+2-match(row(A2:A)+1,
query(SORT({IF(A2:A<>"",row(A2:A),""),row(A2:A)},2,false),"select Col1"),-1)-row(A2:A)),1))
If you wanted to keep it simple and just use a pull-down formula, an ordinary match is enough:
=ArrayFormula(iferror(if(A2="","",match(true,A3:A<>"",0)),1))
(it still has to be entered as an array formula because A3:A<>"" is an array of True and False)
I found a solution with a Monster formula but with simple iterative logics, and up to 50 intermediary blanks (for more only need to make the formula larger).
What I was lookind for was simply to print the cells/rows count of intermediary empty cells between 2 non-empty cells + adding to the count either the 1st non-empty cell or the last non-empty cell.
So for example if cell A1 and cell A9 have 8 empty cells between them, then return 8+1 (or 10-1).
The logics used is simple:
probe how many possible empty cells there can be between each 2 non-empty cells counting the 1st non-empty as well within column A (in the formula below the possibility is up to 50 empty cells), and for each case return the intermediary rows -1 (the last row).
The formula:
=IFS(AND(A1="",A2=""),"",AND(A1="",A2<>""),"",AND(A1<>"",A2<>""),ROWS(A1),AND(A1<>"",A2="",A3<>""),ROWS(A1:A3)-1,AND(A1<>"",A2="",A3="",A4<>""),ROWS(A1:A4)-1,AND(A1<>"",A2="",A3="",A4="",A5<>""),ROWS(A1:A5)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6<>""),ROWS(A1:A6)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7<>""),ROWS(A1:A7)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8<>""),ROWS(A1:A8)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9<>""),ROWS(A1:A9)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10<>""),ROWS(A1:A10)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11<>""),ROWS(A1:A11)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12<>""),ROWS(A1:A12)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13<>""),ROWS(A1:A13)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14<>""),ROWS(A1:A14)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15<>""),ROWS(A1:A15)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16<>""),ROWS(A1:A16)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17<>""),ROWS(A1:A17)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18<>""),ROWS(A1:A18)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19<>""),ROWS(A1:A19)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20<>""),ROWS(A1:A20)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21<>""),ROWS(A1:A21)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22<>""),ROWS(A1:A22)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23<>""),ROWS(A1:A23)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24<>""),ROWS(A1:A24)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25<>""),ROWS(A1:A25)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26<>""),ROWS(A1:A26)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27<>""),ROWS(A1:A27)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28<>""),ROWS(A1:A28)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29<>""),ROWS(A1:A29)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30<>""),ROWS(A1:A30)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31<>""),ROWS(A1:A31)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32<>""),ROWS(A1:A32)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33<>""),ROWS(A1:A33)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34<>""),ROWS(A1:A34)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35<>""),ROWS(A1:A35)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36<>""),ROWS(A1:A36)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37<>""),ROWS(A1:A37)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38<>""),ROWS(A1:A38)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39<>""),ROWS(A1:A39)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40<>""),ROWS(A1:A40)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41<>""),ROWS(A1:A41)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42<>""),ROWS(A1:A42)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43<>""),ROWS(A1:A43)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44<>""),ROWS(A1:A44)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45<>""),ROWS(A1:A45)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46<>""),ROWS(A1:A46)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46="",A47<>""),ROWS(A1:A47)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46="",A47="",A48<>""),ROWS(A1:A48)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46="",A47="",A48="",A49<>""),ROWS(A1:A49)-1,AND(A1<>"",A2="",A3="",A4="",A5="",A6="",A7="",A8="",A9="",A10="",A11="",A12="",A13="",A14="",A15="",A16="",A17="",A18="",A19="",A20="",A21="",A22="",A23="",A24="",A25="",A26="",A27="",A28="",A29="",A30="",A31="",A32="",A33="",A34="",A35="",A36="",A37="",A38="",A39="",A40="",A41="",A42="",A43="",A44="",A45="",A46="",A47="",A48="",A49="",A50<>""),ROWS(A1:A50)-1)
Here the images sheet of the result:
The Sheet
Can it be done in a simpler way but still with a single formula?
Thanks a lot for your next input!
In the mean time I did some simplification of my previous Monster formula and learned the ArrayFormula application in the process.
1st I tried to shorten the big blank cells intervals into ranges formulations to see if it still worked.
For example I changed:
AND(A1<>"",A2="",A3="",A4<>""),ROWS(A1:A4)-1,
into
AND(A1<>"",A2:A3="",A4<>""),ROWS(A1:A4)-1,
And it shortened my formula from this:
to this:
But then when pasting the new formula I got a #VALUE! error 'an array value could not be found'.
After further tests, I used the ArrayFormula and it worked by adapting the simple 'ranges' previously used to Arrays:
from this
AND(A1<>"",A2:A3="",A4<>""),ROWS(A1:A4)-1,
into this
AND(A1<>"",ArrayFormula(A2:A3=""),A4<>""),ROWS(A1:A4)-1,
With this final result:
=IFS(AND(A1="",A2=""),"",AND(A1="",A2<>""),"",AND(A1<>"",A2<>""),ROWS(A1),AND(A1<>"",A2="",A3<>""),ROWS(A1:A3)-1,AND(A1<>"",ArrayFormula(A2:A3=""),A4<>""),ROWS(A1:A4)-1,AND(A1<>"",ArrayFormula(A2:A4=""),A5<>""),ROWS(A1:A5)-1,AND(A1<>"",ArrayFormula(A2:A5=""),A6<>""),ROWS(A1:A6)-1,AND(A1<>"",ArrayFormula(A2:A6=""),A7<>""),ROWS(A1:A7)-1,AND(A1<>"",ArrayFormula(A2:A7=""),A8<>""),ROWS(A1:A8)-1,AND(A1<>"",ArrayFormula(A2:A8=""),A9<>""),ROWS(A1:A9)-1,AND(A1<>"",ArrayFormula(A2:A9=""),A10<>""),ROWS(A1:A10)-1,AND(A1<>"",ArrayFormula(A2:A10=""),A11<>""),ROWS(A1:A11)-1,AND(A1<>"",ArrayFormula(A2:A11=""),A12<>""),ROWS(A1:A12)-1,AND(A1<>"",ArrayFormula(A2:A12=""),A13<>""),ROWS(A1:A13)-1,AND(A1<>"",ArrayFormula(A2:A13=""),A14<>""),ROWS(A1:A14)-1,AND(A1<>"",ArrayFormula(A2:A14=""),A15<>""),ROWS(A1:A15)-1,AND(A1<>"",ArrayFormula(A2:A15=""),A16<>""),ROWS(A1:A16)-1,AND(A1<>"",ArrayFormula(A2:A16=""),A17<>""),ROWS(A1:A17)-1,AND(A1<>"",ArrayFormula(A2:A17=""),A18<>""),ROWS(A1:A18)-1,AND(A1<>"",ArrayFormula(A2:A18=""),A19<>""),ROWS(A1:A19)-1,AND(A1<>"",ArrayFormula(A2:A19=""),A20<>""),ROWS(A1:A20)-1,AND(A1<>"",ArrayFormula(A2:A20=""),A21<>""),ROWS(A1:A21)-1,AND(A1<>"",ArrayFormula(A2:A21=""),A22<>""),ROWS(A1:A22)-1,AND(A1<>"",ArrayFormula(A2:A22=""),A23<>""),ROWS(A1:A23)-1,AND(A1<>"",ArrayFormula(A2:A23=""),A24<>""),ROWS(A1:A24)-1,AND(A1<>"",ArrayFormula(A2:A24=""),A25<>""),ROWS(A1:A25)-1,AND(A1<>"",ArrayFormula(A2:A25=""),A26<>""),ROWS(A1:A26)-1,AND(A1<>"",ArrayFormula(A2:A26=""),A27<>""),ROWS(A1:A27)-1,AND(A1<>"",ArrayFormula(A2:A27=""),A28<>""),ROWS(A1:A28)-1,AND(A1<>"",ArrayFormula(A2:A28=""),A29<>""),ROWS(A1:A29)-1,AND(A1<>"",ArrayFormula(A2:A29=""),A30<>""),ROWS(A1:A30)-1,AND(A1<>"",ArrayFormula(A2:A30=""),A31<>""),ROWS(A1:A31)-1,AND(A1<>"",ArrayFormula(A2:A31=""),A32<>""),ROWS(A1:A32)-1,AND(A1<>"",ArrayFormula(A2:A32=""),A33<>""),ROWS(A1:A33)-1,AND(A1<>"",ArrayFormula(A2:A33=""),A34<>""),ROWS(A1:A34)-1,AND(A1<>"",ArrayFormula(A2:A34=""),A35<>""),ROWS(A1:A35)-1,AND(A1<>"",ArrayFormula(A2:A35=""),A36<>""),ROWS(A1:A36)-1,AND(A1<>"",ArrayFormula(A2:A36=""),A37<>""),ROWS(A1:A37)-1,AND(A1<>"",ArrayFormula(A2:A37=""),A38<>""),ROWS(A1:A38)-1,AND(A1<>"",ArrayFormula(A2:A38=""),A39<>""),ROWS(A1:A39)-1,AND(A1<>"",ArrayFormula(A2:A39=""),A40<>""),ROWS(A1:A40)-1,AND(A1<>"",ArrayFormula(A2:A40=""),A41<>""),ROWS(A1:A41)-1,AND(A1<>"",ArrayFormula(A2:A41=""),A42<>""),ROWS(A1:A42)-1,AND(A1<>"",ArrayFormula(A2:A42=""),A43<>""),ROWS(A1:A43)-1,AND(A1<>"",ArrayFormula(A2:A43=""),A44<>""),ROWS(A1:A44)-1,AND(A1<>"",ArrayFormula(A2:A44=""),A45<>""),ROWS(A1:A45)-1,AND(A1<>"",ArrayFormula(A2:A45=""),A46<>""),ROWS(A1:A46)-1,AND(A1<>"",ArrayFormula(A2:A46=""),A47<>""),ROWS(A1:A47)-1,AND(A1<>"",ArrayFormula(A2:A47=""),A48<>""),ROWS(A1:A48)-1, AND(A1<>"",ArrayFormula(A2:A48=""),A49<>""),ROWS(A1:A49)-1, AND(A1<>"",ArrayFormula(A2:A49=""),A50<>""),ROWS(A1:A50)-1)
New Sheet here

How to use ARRAYFORMULA with OFFSET to previous row without getting circular reference error

Example sheet: https://docs.google.com/spreadsheets/d/14ma-y3esh1S_EkzHpFBvLb0GzDZZiDsSVXFktH3Rr_E/edit?usp=sharing
In column B of ItemData sheet, I have achieved the result I want by copying the formula into every cell in the column, but I want to solve this using ArrayFormula instead.
In column C I have achieved the same result using ArrayFormula. However, for addition, column C is referring to cells in column B, while column B is referring to cells in column B. I.e. every cell in column B is adding 1 to the cell on the row above.
If I select the C3 formula text and paste it into the cell edit field for cell B3 (to not screw up cell references during copy - I know I could make them static references, but this is not my problem), the cell gets an error value of
#REF!
Error
Circular dependency detected. To resolve with iterative calculation, see File > Spreadsheet Settings.
Do note that the additions that need to be done are the same in both cases: Add 1 to the value of the cell on the previous row, so there is no circular reference involved. There is a starting value provided in B2, and cells in B3 and downwards should use the data from the B cell in the previous row.
Also, note that I did try File->Spreadsheet settings and enabling circular reference computation with max 25 items, but this only fills in the first two cells (B3 and B4).
How can I solve this problem? I would prefer having something like ArrayFormula, where the formula only exists in a single cell. But copy-pasting would be acceptable as long as any new rows, inserted in between or added at the bottom, would get the same formula added in column B.
Will matching items always be consecutive? It seems that way since you're comparing each Item cell to the cell above it right in your formula logic. That breaks an [unwritten?] rule of spreadsheet normalization; values' addresses themselves generally should not be treated as data.
IF you're committed to it though, have you considered explicitly using location as a data source? Example:
=ARRAYFORMULA(IFS(
NOT(LEN(A3:A40)),,
ROW(A3:A40)-3-MATCH(A3:A40,A$3:A$40,0)<=VLOOKUP(VLOOKUP(A3:A40,Items!$A$2:$D,2,false),DataPerColor!$A$2:$B,2,false),ROW(A3:A40)-3-MATCH(A3:A40,A$3:A$40,0),
true,
))
Just like your formulas, all that does in English is:
for each row,
if there's no Item, don't output any ItemData,
if the number that belongs in this cell¹ is less than or equal to the lookup, print it,
otherwise, don't output any ItemData
But then what is ¹ "the number that belongs in this cell" and how can we calculate it without using column B? I abuse locations of things to get it. Looking down your row B, each number that appears is just:
this row's number,  minus  
the row where items start [always 3],  minus  
the row number [in just the Item rows] of the first row containing this row's Item
Using the second-to-last ItemC as an example: the first ItemC is the 16th item listing, and the one we're looking up… the "second-to-last ItemC" is in row 21 of the sheet. 21-3-16 = 2 …the number you wanted.
If you can stomach that, it's a single formula and does work according to your specifications.

How to use index match formula that automatically expands in Google Sheets

In Google Sheets I am using a filter function to pull in Names into column A and a Timestamp into column B. Every time a second occurrence of the name shows up into columns A & B of the list I want column C next to the prior occurrence to reference the new timestamp. In column D I will then calculate the difference from the names timestamp and the next occurrence of that same name.
Currently I am using the following formula:
=IFERROR(INDEX(B3:B,MATCH(A2,A3:A,0)))
If I drag this formula down it does what I need it to do, but due to how many rows are being added to the first two columns, rows are being added to the bottom of the sheet due to the filter and the formulas keep needing to be dragged down. The durations in column D are being calculated with the following formula, that automatically arrays the results and automatically expands with the filter results:
=IFERROR(ARRAYFORMULA(IF(C2:C="","",C2:C-B2:B)))
I would like my index match formula to do the same, but it seems I cannot use the index formula with an arrayformula.
I attempted to achieve this by using a vlookup combined with an offset for the range. The first row is giving me the result I want, but all the subsequent rows are not referencing the offset range, probably because the offset isn't changing with each new array result here is that attempt:
=IFERROR(ARRAYFORMULA(VLOOKUP(A2:A,OFFSET(A2:B,1,0),2,FALSE)))
Any ideas how this could be accomplished by placing a formula in one cell, or would this have to be accomplished with a script?
I have added an example spreadsheet of the current method HERE
Thanks in advance for any help.
Formula
Instead of
INDEX, MATCH and OFFSET
try the following formula
=ArrayFormula(IFERROR(VLOOKUP(
TRANSPOSE(VALUE(REGEXEXTRACT(QUERY(TRANSPOSE(
IF(FILTER(ROW(A2:A),LEN(A2:A))<TRANSPOSE(FILTER(ROW(A2:A),LEN(A2:A))),
IF(FILTER(A2:A,LEN(A2:A))=TRANSPOSE(FILTER(A2:A,LEN(A2:A))),
TRANSPOSE(FILTER(ROW(A2:A),LEN(A2:A))),
),)
),,2000000),"(\d+)"))),
FILTER({ROW(A2:A),B2:B},LEN(A2:A)),2,0)))
Formula description
This part creates a square matrix showing the row number of the value that matches if it's below of the current row:
IF(FILTER(ROW(A2:A),LEN(A2:A))<TRANSPOSE(FILTER(ROW(A2:A),LEN(A2:A))),
IF(FILTER(A2:A,LEN(A2:A))=TRANSPOSE(FILTER(A2:A,LEN(A2:A))),
TRANSPOSE(FILTER(ROW(A2:A),LEN(A2:A))),
),)
This part takes the smallest row that matches the current row (the next occurrence of the row value)
TRANSPOSE(VALUE(REGEXEXTRACT(QUERY(TRANSPOSE( ),,2000000),"(\d+)")))
This part returns the related value, if any, otherwise a blank:
IFERROR(VLOOKUP( ,FILTER({ROW(A2:A),B2:B},LEN(A2:A)),2,0)))

Working with OFFSET and SPLIT together to get an array of looked-up cells

I'm unable to get OFFSET to return an array of data in Google Sheets. For example in the same sheet, I have a player table which eats an animal, the eats column stores the index of the animal. I want to add up all weights.
This is what I came up with (the example numbers might not be exactly right) but it only works with the first split value:
=SUM(IFERROR(OFFSET($H$11,SPLIT(D6,","),0,1,1),0))
Assuming User A is in B2 and your other table is a Named Range (1), please try:
=ArrayFormula(sum(vlookup(split(C2,","),NamedRange1,3,0)))

Improving a Spreadsheet Formula to be more dynamic

I have a a couple sheets that I want to filter the values of and sum them together. I have a working function:
=SUM(INDEX(Grades!M32:V32,0,B2)+INDEX(Grades!M32:V32,0,C2)+INDEX(Grades!M32:V32,0,D2)+INDEX(Grades!M32:V32,0,E2)+INDEX(Grades!M32:V32,0,F2)+INDEX(Grades!M32:V32,0,G2))
and this is working fine. The problem is it isn't really dynamic and I was wondering if there was a more efficient way to approach this instead of using so many Indexes.
Index is grabbing a horizontal range of numbers from another sheet and getting the needed index position from a small table in another sheet.
Update
I was able to get the formula working how I wanted by inserting an IF statement that would not do the VLOOKUP if one of the cells was empty.
=ArrayFormula(SUM(IF(B2:I2 <> "",VLOOKUP(1,{1,Grades!$M$32:$V$32},B2:I2+1))))
It looks a bit strange, but this is one way:
=ArrayFormula(SUM(VLOOKUP(1,{1,Grades!M32:V32},B2:G2+1,0)))
In the VLOOKUP, 1 is the value you are searching for, {1,Grades!M32:V32} is the array in which you are searching, B2:G2+1 is the column index (or rather, indices) you wish to return, and 0 dictates that you require an exact match.
{1,Grades!M32:V32} constructs a horizontal, one-row array that has 1 in the left-most element, with the values in Grades!M32:V32 to the right of it.
VLOOKUP will search down the left-most column of that array. It will always "find" the 1 that it is searching for in the left-most column, because we have purposely manufactured that.
Where the action really happens is in the third argument, where we return the columns in that manufactured array corresponding with the values in B2:G2 (I should add, I assumed that all cells in B2:G2 are populated - it will return the wrong result if any are blank). The +1 is to account for the extra element (the 1) we tacked on to the left of the lookup array.

Resources