Using ArrayFormula with a Dynamic Number of Column Header Names - google-sheets

My goal is to use ArrayFormula with the SPLIT() function, and name the headers of each column.
My problem is that the formula below only works when the number of headers declared exactly matches the first row's number of elements to split ie. if there are 3 elements being split on the first row, the formula needs 3 headers named (g1, g2, g3), but if any rows have more than 3 elements to split, it gives an error.
Is there a way to make the column header names dynamic in number, so that the number of elements to split can be, say, from 0-10? The elements to be split will always be separated by a comma and no spaces.
=ArrayFormula({"g1", "g2", "g3";if(A2:A="","",split(A2:A,","))})
link to example: https://docs.google.com/spreadsheets/d/1c2pskSYsGs12Yjbn-5gORQ22mDSaC9cSnp1nWeULlf4/edit?usp=sharing

You can try:
=index(iferror({"g"&sequence(1,max(len(substitute(
transpose(query(transpose(if(iferror(split(A2:A,","))="",,"z")),,9^9)),
" ",))));split(A2:A,",")}))
If we can use the Orders column, it's as simple as:
=index(iferror({"g"&sequence(1,max(B:B));split(A2:A,",")}))

You can achieve it by combining the index function, the sequence function and the max function. Here is the thought process behind it:
The max function (you can read more about it here) will retrieve the maximum value of the orders column.
The sequence function (you can read more about it here) will generate a series starting at 1 and ending at the previous maximum value.
The index function (you can read more about it here) will distribute the elements of the sequence (with a "g" in front) across as many cells as elements are in the sequence.
If you combine those, you get:
=INDEX("g"&SEQUENCE(1,MAX(B:B)))

Related

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.

In Google Sheets, how can Array elements be passed as individual arguments to a Google Sheets native function?

My question is very similar to the one described here: How can I pass an array's elements as individual arguments to a function?
The twist here is doing it inside Google sheets. In column A, there are a series of entries, from which I want to filter those that match certain criteria, and then in some other individual cells, populate the n-th result of the filter.
COL A1:A4
John A
Hector C
Mario G
Hecate J
Cell C4: =CHOOSE(1,FILTER(A1:A4, LEFT(A1:A4,1)="H"))
Cell D8: =CHOOSE(2,FILTER(A1:A4, LEFT(A1:A4,1)="H"))
But what happens is that C4:C5 are populated with Hector C and Hecate J, and D8 returns "Error Function CHOOSE parameter 1 value is 2. Valid values are between 1 and 1 inclusive."
My conclusion is that the Array that FILTER returns, is simply taken as a single argument by the CHOOSE function, instead of taking the individual elements as arguments.
I tried fiddling with the ArrayFormula, but no luck. I tried the long shot of preppending the "..." and obviously is not recognized as a function.
Any ideas that do not involve writing my own Script function?
Thanks.
You can use index() instead:
Then you can select the n-th element of the list like that:
=index(FILTER(A1:A4, LEFT(A1:A4,1)="H"),2)
Instead of having 2 as a hardcopy number you can also specify the length of the list to take for example the last element of the filtered list:
=index(FILTER(A1:A4, LEFT(A1:A4,1)="H"),COUNTA(FILTER(A1:A4, LEFT(A1:A4,1)="H")))

Import multiple ranges to a single sheet

I have two different sheets, with two of the same ranges (age). I want to combine these two separate ranges into one on a different sheet. Current formula / function I am using:
={(importrange("https...", "Sheet1!A2:A100"));(importrange(""https...", "Sheet2!A2:A100"))}"))
What am I doing wrong?
I was able to bring in one range at a time with this formula / function:
=IMPORTRANGE("https...", "Sheet1!A2:A100")
=IMPORTRANGE("https...", "Sheet2!A2:A100")
but I need them to be in one column together (the order does not matter, I just need the values to be pulled across).
Try two IMPORTRANGE functions within one formula separated by a semi-colon and wrapped in braces (e.g. { and } that you type yourself)
={IMPORTRANGE("https://docs.google.com/spreadsheets/d/1mYWnO8vzyb5o4jzp-Ti-369nSyQoCfg-WzqaaTb94tE", "Sheet1!A2:A10");IMPORTRANGE("https://docs.google.com/spreadsheets/d/1mYWnO8vzyb5o4jzp-Ti-369nSyQoCfg-WzqaaTb94tE", "Sheet2!A2:A")}
If you do not have a set number of rows in the source sheet1 (e.g. A2:A100), then the retrieved data from sheet2 will start on the 101st row with blanks above it. To get around this, concatenate a dynamic 'last populated' row number onto the range string.
={IMPORTRANGE("https://docs.google.com/spreadsheets/d/1mYWnO8vzyb5o4jzp-Ti-369nSyQoCfg-WzqaaTb94tE", "Sheet1!A2:A"&match(1E+99, IMPORTRANGE("https://docs.google.com/spreadsheets/d/1mYWnO8vzyb5o4jzp-Ti-369nSyQoCfg-WzqaaTb94tE", "Sheet1!A:A")));IMPORTRANGE("https://docs.google.com/spreadsheets/d/1mYWnO8vzyb5o4jzp-Ti-369nSyQoCfg-WzqaaTb94tE", "Sheet2!A2:A")}
source link
destination link
What am I doing wrong?
You have a couple of double inverted commas too many and unmatched parentheses (also some unnecessary spaces and parentheses). Following should work, with granting authorisation if required.:
={importrange(" k e y 1 ","Sheet1!A2:A100");importrange(" k e y 2 ","Sheet2!A2:A100")}
It might help to compare 'yours' and 'mine' in a word processor and fixed width font.

Reduce a range of values to a list in Google Sheets

I have a table with printer names and the model numbers of the toner and drums which they use. I'm looking for a way to generate a single column list from this range of values, excluding blank cells. Below is the table:
I'd like to end up with a list of values as such:
MX-C30NT-B
MX-C30NT-C
MX-C30NT-M
MX-C30NT-Y
MX-C30DR
MX-C30HB
MX-C30NV-B
MX-C30NV-C
MX-C30NV-M
MX-C30NV-Y
...
I know in Excel I can use an array formula to accomplish this, but array formulas don't seem to be as robust in Sheets. Is there a formula which will perform this conversion?
Combining nonempty cells in columns E-M into a single column, ignoring the header row:
=filter({E2:E; F2:F; G2:G; H2:H; I2:I; J2:J; K2:K; L2:L; M2:M}, len({E2:E; F2:F; G2:G; H2:H; I2:I; J2:J; K2:K; L2:L; M2:M}))
The first argument is just a bunch of column stacked; the filter excludes empty ones. Note that the second {...} construct is identical to the first, it's a copy-paste.

How to use INDEX() inside ARRAYFORMULA()?

I am trying to use the INDEX() formula inside an ARRAYFORMULA(). As a simple (non-sense) example, with 4 elements in column A, I expected that the following array formula entered in B1 would display all four elements from A in column B:
=ARRAYFORMULA(INDEX($A$1:$A$4,ROW($A$1:$A$4)))
However, this only fills field B1 with a the value found in A1.
When I enter
=ARRAYFORMULA(ROW($A$1:$A$4))
in B1, then I do see all numbers 1 to 4 appear in column B. Why does my first array formula not expand similar like the second one does?
The INDEX function is one that does not support "iteration" over an array if an array is used as one of its arguments. There is no documentation of this that I know of; it simply is what it is. So the second argument will always default to the first element of the array, which is ROW(A1).
One clumsy workaround to achieve what you require relies on a second adjacent column existing next to the source data* (although it is unimportant what values are actually in that second column):
=ArrayFormula(HLOOKUP(IF(ROW($A$1:$A$4);$A$1);$A$1:$B$4;ROW($A$1:$A$4);0))
or indeed something like:
=ArrayFormula(HLOOKUP(IF({3;2;4;1};$A$1);$A$1:$B$4;{3;2;4;1};0))
edit 2015-06-09
* This is no longer a requirement in the newest version of Sheets; the second argument in the HLOOKUP can just be $A$1:$A$4.
Here is a tip for using vlookup with an array, so that even if the columns are moved later on the formula will still work correctly....
In general, configure the vlookup so that it's reading only 2 columns and returning the second. This can be done by inputting only the 2 columns required, rather than a range and column index.
Example:
Replace the following formula which would fail if columns are moved
=arrayformula( vlookup(C:C, booking!$A:$E ,5 ,false) )
with this formula which will continue to work even if columns are moved
=arrayformula( vlookup(C:C, {booking!$A:$A,booking!$E:$E} ,2 ,false) )
Note, you can also simulate the index function using vlookup.
Example:
Column R:R contains the row index numbers for looking up data in column booking!$A:$A
=arrayformula(vlookup(R:R ,arrayformula({row(booking!$A:$A), booking!$A:$A}),2 , false))
It's a nested array, so it can be helpful to test in stages, eg just the inner part for one example, eg return entry in row 10:
=vlookup(10 ,arrayformula({row(booking!$A:$A), booking!$A:$A}),2 , false)

Resources