VLOOKUP formula working in one sheet but not the other - google-sheets

I have two identical sheets, and the array/vlookup formula is working in one, but not the other. I've tried to make sure both are formatted exactly the same, but it's just not working. Can anyone tell me why this is?

The two sheets are not, in fact, identical. QUERY can only return one kind of information per column, not a mix; and the type returned will be the one that occurs the most. So your "WORKS" formula works because you have more numbers than text in Column E; but the "doesn't work" sheet does not work because it has many more instances of the string "done" in Column E, so only the string type is being returned.
Beyond that, your two formulas actually aren't the same. For instance, your first formula asks for a return of null-string where null-string is found in B3:B, while your second formula replaces those with spaces.
In order to be sure you are only returning numerical content in the QUERY regardless of inclusions of strings in Column E, you'll need to pre-process the information to FILTER in only the rows where Column E contains a number. However, pre-processing creates new virtual arrays in memory, and so direct column-letter references will need to be exchanged for Colx notation.
Delete the A3 formula in the "doesn't work" sheet and try replacing it with this one:
=ArrayFormula(IF(B3:B="",,IFERROR(VLOOKUP(B3:B,QUERY(FILTER(B3:E,ISNUMBER(E3:E)),"Select Col1, Min(Col4) WHERE Col4<30 GROUP BY Col1"),2,FALSE))))

Related

Unique Filter multiple sheets with ArrayFormula

I have no idea how to title this post, apologize in advance.
I have several sheets with a number in Column I and a name centered and merged in columns A:H. I want to obtain the name from A:H of the corresponding value within I but do have duplicates, therefore I need the nth value when permitted. The formula I have so far works up to the point it does not autofill down as an ArrayFormula, so when I drag the formula down I get an #REF! error due to the fact that when a duplicate is found it cannot overwrite the formula below.
This will be easier to showcase: LINK TO SHEET.
Essentially, in the main sheet all the values in I:I of all the other sheets are obtained and sorted, then using that column I want to return the name that corresponds to the value, allowing for duplicates to work themselves out. I believe my issues resides in the $B1 part at the end of the formula preventing it from being an array.
=ARRAYFORMULA(UNIQUE(FILTER({Sheet2!$A$1:$A;Sheet3!$A$1:$A;Sheet4!$A$1:$A},{Sheet2!$I$1:$I;Sheet3!$I$1:$I;Sheet4!$I$1:$I}=$B1)))
Cell F2 on the Sheet1 tab:
=QUERY({Sheet2!A:I;Sheet3!A:I;Sheet4!A:I},"select Col1,Col9 where Col9>0 order by Col9 asc",0)
You can read more about query here.

Is there a way to specify an input is a single cell in Google Sheets?

I want to iterate over an array of cells, in this case B5:B32, and keep the values that are equal to some reference text in a new array.
However, SPLIT nowadays accepts arrays as inputs. That means that if I use the array notation of "B5:B32" within ARRAYFORMULA or FILTER, it treats it as a range, rather than the array over which we iterate one cell at a time.
Is there a way to ensure that a particular range is the range over which we iterate, rather than the range given at once as an input?
What I considered was using alternative formulations of a cell, using INDEX(ROW(B5), COLUMN(B5)) but ROW and COLUMN also accept array values, so I'm out of ideas on how to proceed.
Example code:
ARRAYFORMULA(
INDEX(
SPLIT(B5:B32, " ", 1), 1
) = "Some text here"
)
Example sheet:
https://docs.google.com/spreadsheets/d/1H8vQqD5DFxIS-d_nBxpuwoRH34WfKIYGP9xKKLvCFkA/edit?usp=sharing
Note: In the example sheet, I can get to my desired answer if I create separate columns containing the results of the SPLIT formula. This way, I first do the desired SPLITS, and then take the values I need from that output by specifying the correct range.
Is there a way to do this without first creating an output and then taking a cell range as an input to FILTER or other similar functions?
For example in cell C35 I've already gotten the desired SPLIT and FILTER done in one go, but I'd still need to find a way to sum up the values of the first character of the second column. Doing this requires that I take the LEFT value of the second column, but for that I need to output the results and continue in a new cell. Is there a way to avoid this?
Ralph, I'm not sure if your sample sheet really reflects what you are trying to end up with, since, for example, I assume you are likely to want the total of the hours per area.
In any case, this formula extracts all of the areas, and the hours worked, and is then easy to do further calculations with.
=ArrayFormula({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))})
Try that in cell E13, to see the output.
The first REGEXEXTRACT pulls out all the text in front of the first space and number, and the second pulls out all the digits in a string of " #hr" in each cell. These criteria could be modified, if necessary, depending on your actual requirements. Note that it requires the use of VALUE, to convert the hours from text to numeric values, since REGEXEXTRACT produces text (string) results.
It involved concatenating your multiple data columns into one long column of data, to make it simpler to process all the cells in the same way.
This next formula will give you a sum, for whatever matching room/task you type into B6, as an example.
=ArrayFormula(QUERY({REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9},"(.*) \d"),
VALUE(REGEXEXTRACT({C5:C9;D5:D9;E5:E9;F5:F9;G5:G9;H5:H9}," (\d+)hrs"))},
"select Col1, sum(Col2) where Col1='"&B6&"' group by Col1 label sum(Col2) '' ",0))
I will also answer my own question given what I know from kirkg13's answer and other sources.
Short answer: no, there isn't. If you want to do really convoluted computations with particular cell values, there are a few options and tips:
Script your own functions. You can expand INDEX to accept array inputs and thereby you can select any set of values from an array without outputting it first. Example that doesn't use REGEXMATCH and QUERY to get the SUM of hours in the question's example data set: https://docs.google.com/spreadsheets/d/1NljC-pK_Y4iYwNCWgum8B4NJioyNJKYZ86BsUX6R27Y/edit?usp=sharing.
Use QUERY. This makes your formula more convoluted quite quickly, but is still a readable and universally applicable method of selecting data, for example particular columns. In the question's initial example, QUERY can retrieve only the second column just like an adapted INDEX function would.
Format your input data more effectively. The more easily you can get numbers from your input, the less you have to obfuscate your code with REGEXMATCHES and QUERY's to do computations. Doing a SUM over a RANGE is a lot more compact of a formula than doing a VALUE of a LEFT of a QUERY of an ARRAYFORMULA of a SPLIT of a FILTER. Of course, this will depend on where you get your inputs from and if you have any say in this.
Also, depending on how many queries you will run on a given data set, it may actually be desirable to split up the formula into separate parts and output partial results to keep the code from becoming an amalgamation of 12 different queries and formulas. If the results don't need to be viewed by people, you can always choose to hide specific columns and rows.

Sumifs match ANY from one column

So I have two sheets. Neither need to be pretty. One is the basic entry sheet where data should be pulled from and looks a bit like this.
There's colours in column A, random fruit in column B and the value of what those two together would be in any given situation in Column C. That's all entirely manual and based on whatever I need when I'm inputting. The idea behind it is that nothing is entirely unique. You can see Apples can be on the same row as Red or Green, similarly nearly everything on this list is next to the word Red.
The trouble I run into is on the calculating sheet.
Column A is now made up of SOME colours from the Entry Sheet. This is a dynamic list that can change depending on other inputs so the number of rows won't always be the same.
Column B successfully uses UNIQUE, FILTER, and IFERROR to search Column B on the Entry Sheet, and return all the different values where the value in the A column on the Entry sheet appears SOMEWHERE in the A column on the Calculate sheet. I can go ahead and add a "Green Frog" to my entry sheet but he won't show up here. For those curious the formula here is:
=unique(FILTER(Entry!B:B,iferror(match(Entry!A:A,A:A,0))))
So far so swell.
Now I want to add them. I've ended up, because many hours on google took me there, using some kind of SUMIFS but it's producing the result pictured. The actual formula in C1 is
=SUMIFS(Entry!C:C,Entry!A:A,A:A,Entry!B:B,B1)
The result in C1 is exactly what I want. 5 is indeed the number of Red Apples and does not include the number of Green apples.
However, the same formula doesn't produce the desired result for the rest of the column. All other returns are '0' because the word 'Red' in the A column is only on the top row and obviously 'Yellow' is also not on the same row as 'Grape'.
So the question is, how to I get the 'Entry!A:A,A:A' to essentially make that particular criteria say "See these? Yes ALL of these please"
try:
=SUM(FILTER(C:C; B:B=F1; REGEXMATCH(A:A; TEXTJOIN("|"; 1; E:E))))

Query Importrange in Google Sheets Not Importing Correctly

We are using Google Forms to collect data on our students. They use the same Google Form for all students, but as part of the form, they are asked the students name.
The data that ends up being collected you can see on the tab Form Responses 1 on the Google Sheet linked here.
I am attempting to use ImportRange to create a tab for each of the students. The formula that I am using for just one of the students is...
=QUERY(IMPORTRANGE("1nJANDP1fiQunxfxEf-EjwJrnIRICv6kLhYYY9XBXtD4", "Form Responses 1!A:I"),"SELECT * WHERE Col3 = 'Adam N.'")
You can take a look at the tab called Adam N. and you'll see it is kind of working.
One thing that doesn't seem to be working is when there is a text value in columns E-I, that text value doesn't end up showing on the Adam N. tab. Any ideas how I can get both the numbers and the text values to show up?
The other thing that seems to be a problem is the fact that on the Adam N. tab, the very first row has the same headers as the Form Responses 1 tab, but it also has the very first line of data. Any way to remove that?
Importrange is not needed since you are 'importing' from within the same spreadsheet. Also, I'd recommend using the (optional) header argument in query().
It is often noted that users are tempted to mix data types within a column. The query() function will give undesirable output. If a column is intended for numeric values then only numerical values must reside in that column. Date columns must only contain dates and text columns only contain text values.
This does not mean that numbers cannot appear in a text column as long as they are in a text format. So it is important to plan the columns in a table to make sure this rule is maintained regardless if the data table is created manually or via submissions from a Google Form.
Generally, the query() function will assume the greater number of cell types in a column to be that data type. For example, if there are 100 numbers and 20 text values in the same column then a numeric value will be assumed for that column. There is a good chance the text values will just be ignored. One way to avoid this, would be to convert everything to text.
See if this works
=ArrayFormula(QUERY(to_text('Form Responses 1'!A:I),"WHERE Col3 = 'Adam N.'", 1))

Why does my importrange query fail when I "wrap" with arrayformula

I have the following formula which is currently returning the expected results -
=join(",",query(importrange(vlookup(mid(G4,1,find(",",G4)-1),xref,2,false),vlookup(mid(G4,1,find(",",G4)-1),xref,3,false)),"Select Col3,Col6,Col9 where Col1 = '"&mid(G4,find(",",G4)+1,20)&"' "))
However, I naturally want to make this as dynamic and flexible as possible so I would like to "wrap" it in an arrayformula which ends up like this -
=arrayformula(join(",",query(importrange(vlookup(mid(G4:G,1,find(",",G4:G)-1),xref,2,false),vlookup(mid(G4:G,1,find(",",G4:G)-1),xref,3,false)),"Select Col3,Col6,Col9 where Col1 = '"&mid(G4:G,find(",",G4:G)+1,20)&"' ")))
This formula gives me "Unable to parse query string for Function QUERY parameter 2: NO_COLUMNCol3" error.
I tried to include an iferror to try to trap some error but this made no difference.
I tried various angles to debug and basically focussed on the importrange not providing the data to the query once it was wrapped by the arrayformula. I tried to explicitly reference the external sheet key and range in the importange function, instead of using the lookups, and this did give me a result - but only in the first cell. There should also have been a result returned about 4 rows down.
If I copy the formula down the column, I do get the expected result 4 rows down, but this obviously defeats the purpose of the arrayformula.
In my research in the Google forums there were some suggestions that arrayformula and importrange may not play well together, but no hard and fast facts.
I noticed in this forum that the combination of the two functions has been mentioned but no indication that they did not work together, so I am wondering if there is just some little thing I am missing in my syntax that is causing my ideal scenario not to work ?
I don't think this will work for a couple of reasons.
Firstly, not all the functions in Google Sheets can be automated using an arrayformula, and QUERY is one of them. As far as I know this is because the output of QUERY can be an array itself, so it is not possible to iterate an array output across another array (i.e. your results range).
Secondly, JOIN works across a either a single row or column, whereas your query outputs 3 columns. The arrayformula result would therefore consist of an array with multiple rows and columns, which JOIN cannot use.
I think the best solution is to use the IFERROR as you've described, and copy the single-row formula down the entire column - that way the blank records will not show as errors, but you will be able to add new values to column G and they will be picked up automatically.

Resources