I'm trying to use IF statements to execute multiple vlookups, with the goal of searching multiple ranges in sequence for a single search key if the key is not found in the first range.
This is premised on the output of a Vlookup when the key is not found being "#N/A", and triggering the second vlookup when that is the output from the first range. My code:
=if(vlookup(A6,Range1!A:A,1,false)<>#N/A,"Match",if(vlookup(A6,Range2!A:A,1,false)<>#N/A,"Match",if(vlookup(A6,Range3!A:A,1,false)<>#N/A,"Match",if(vlookup(A6,Range4!A:A,1,false)<>#N/A,"Match",if(vlookup(A6,Range5!A:A,1,false)<>#N/A,"Match","Not")))))
What I was expecting is for the lookup to proceed through the ranges if an output of #N/A is found, ultimately resulting in each search key being assigned "Match" or "Not". What is happening is that the second If statement is not executing, and my outputs are either "Match" or "#N/A".
try this out:
=if(NOT(ISERROR(vlookup(A6,Range1!B:B,1,false))),"Match",if(NOT(ISERROR(vlookup(A6,Range2!B:B,1,false))),"Match",if(NOT(ISERROR(vlookup(A6,Range3!B:B,1,false))),"Match",if(NOT(ISERROR(vlookup(A6,Range4!B:B,1,false))),"Match",if(NOT(ISERROR(vlookup(A6,Range5!B:B,1,false))),"Match","Not")))))
I think this is a more compact representation that achieves the same result:
=arrayformula(if(sum(n(A6={Range1!B:B;Range1!B:B;Range3!B:B;Range3!B:B;Range4!B:B;Range5!B:B;Range6!B:B}))>=1,"Match","Not"))
The VLOOKUPs are not needed (as you're just looking for a match in a list rather than actually doing a lookup here), and you can union all the ranges together to eliminate a lot of unnecessary nesting.
Related
I'm creating a crypto tracking spreadsheet and I'm getting some strange results using the LOOKUP function.
I have two named ranges:
The symbol range is called USDCoinSymbols
and the coin name range is called USDCoinNames
Here are some function results when I try using the LOOKUP function:
Apologies for the mixed casing on the search term. I was experimenting, but
it seems the LOOKUP function isn't case sensitive (for example, BNB returned the correct coin name).
I also tried the inverse, looking up a coin symbol with a coin name (2nd result) and that works fine.
I spent a good couple hours trying to figure this out.
Am I missing something or is this a bug?
Edit: Here is a link to sample spreadsheet and I'm using the CoinGecko API to get this data.
I'm trying to pull the coin name using the symbol to fill up a table I'm creating.
This is not a bug. It's just how LOOKUP works.
LOOKUP requires that all search-column information be in strict least-to-greatest order, so it wouldn't work with your data.
I've added a new sheet ("Erik Help") which is a duplicate of your first sheet. In my sheet, I deleted your LOOKUP formulas from B20:B27 and replaced them with one array formula. This formula uses VLOOKUP with FALSE as the final parameter, meaning that your data is NOT ordered in strict least-to-greatest order and that exact matches should be searched anywhere instead. This one formula fills all results for B20:B:
=ArrayFormula(IF(A20:A="",,IFERROR(VLOOKUP(A20:A,B2:C14,2,FALSE))))
If you are going to be applying this to a larger list elsewhere and want to use your named ranges, just replace B2:C14 with {USDCoinSymbols, USDCoinNames}.
References:
LOOKUP
VLOOKUP
You will need to use the VLOOKUP function instead
=INDEX(IFERROR(VLOOKUP(A20:A25, {USDCoinSymbols, USDCoinNames},2,0)))
This single formula is all you need.
Since your lists are NOT sorted you should use 0 in the function
(please -as always- adjust formula according to your ranges and locale)
I want to create a formula, that gets me the specific value(s) from row in another table. The formula I've created
=LOOKUP(E5;Ingredients!$A$6:$B$49;Ingredients!$F$6:$F$49)
gives me false results. But when I sort the values by alphabet the results are correct.
Is there some way to create a formula that is not dependent on alphabetical sort of source table?
From https://support.google.com/docs/answer/3256570?hl=en-GB
"Notes:
The LOOKUP function will only work properly if data in search_range or search_result_array is sorted. Use VLOOKUP, HLOOKUP or other related functions if data is not sorted."
Personally, I've never really used the lookup functions because of issues like this, so I'm a bit rusty on the specifics of how they all work. My go-to is the INDEX MATCH solution, which might be something like
=index(Ingredients!$F$6:$F49, match(E5, Ingredients!$A$6:A$49))
What I'm also not sure about is how Lookup is supposed to work when you're giving it more than one column as the input, though; you're giving it A and B - I thought that syntax was for an array where the output comes from the last column, and I don't know what happens if you then specify the output column as well, as you've done.
So I've got the following formula to correlate two ranges:
=ROUND(CORREL(ARRAYFORMULA(MMULT('E0:Sample'!$D$2:$AY,TRANSPOSE(SIGN(COLUMN(('E0:Sample'!$D$2:$AY)))))),FILTER(OFFSET('E0:Sample'!$D$2:$D,0,ROW()-2),NOT(ISBLANK(OFFSET('E0:Sample'!$D$2:$D,0,ROW()-2))))),3)
The formula works fine, as long as there are no blanks in 'E0:Sample'!$D$2:$AY. Otherwise the error message Function MMULT parameter 1 expects number values. But '' is a empty and cannot be coerced to a number. is thrown.
I´ve tried to filter() for empty rows, but the filter-function won't work since the ranges differ.
How do I solve this without the best way?
Thanks!
It's difficult to test your complete formula, but I did a test on a mini-version of matrix multiply and it seems that you can use the N function the same way as you can in Excel. Here is my mini-test:-
=ArrayFormula(MMULT(n(B1:G1),n(A1:A6)))
where both ranges contain a mix of numbers, alphas and blanks. Non-numeric cells are treated as zeroes.
Reference
I'm not totally clear about the context for this - I think you're trying to get the row sums from your large 2D array by using the mmult - if this is correct I think my answer is OK because the blanks would contribute nothing to the sums. Since CORREL ignores blanks in the second range, you don't need to filter at all?
I did eventually set up some test data for your formula, and my formula ended up like this:-
=ROUND(CORREL(ARRAYFORMULA(MMULT(n('E0:Sample'!$D$2:$AY),TRANSPOSE(SIGN(COLUMN(('E0:Sample'!$D$2:$AY)))))),OFFSET('E0:Sample'!$D$2:$D,0,ROW()-2)),3)
I am trying to figure out if it is possible to use LOOKUP function that is based on a dyanmic value. For example:
=LOOKUP("A", C$2:C$1000, B$2:B$1000)
The above will look for Letter A in C Column and then write the value from the corresponding B Column row. What I wish to do is now read the Letter A from the D column, like so:
=LOOKUP(D2, Sheet2!C$2:C$1000, Sheet2!B$2:B$1000)
However, the above gives me an error. Is there a way to accomplish the above?
The above keeps returning me with an error saying value not found, I'm not sure what I am doing wrong.
EDIT
Ok so I have been playing more with this and I started having some very strange results. Lets take the following table: https://docs.google.com/spreadsheets/d/1ki3pmCOQoI1DLcbjEO-uwgwZGFfnHhM-fodspw8v1Qs/#gid=1001637055
Then my second sheet is this:
https://docs.google.com/spreadsheets/d/1ki3pmCOQoI1DLcbjEO-uwgwZGFfnHhM-fodspw8v1Qs/edit#gid=1993578337
If you look at the second sheet, bob shows up multiple times and I don't understand why.
Reason for #N/A's
lookup produces #N/A if it is looking up an empty range as is the case here. `'Draft Options'!A:A is empty so lookup cannot find a value to look up against.
Reason for multiple appearances
The documentation states that:
The LOOKUP function will only work properly if data in search_range or
search_result_array is sorted. Use VLOOKUP, HLOOKUP, or other related
functions if data is not sorted.
If search_key is not found, the item used in the lookup will be the
value that’s immediately smaller in the range provided. For example,
if the data set contains the numbers 1, 3, 5 and search_key is 2, then
1 will be used for the lookup.
Now, you are looking up Text but the same thing applies, it needs to be ordered alphabetically.
This is because lookup is doing something called binary search
Since your data is unordered and (assuming you have column A filled with keys the following can happen which leads to weird results:
Lookup looks at the middle entry and checks if the value comes before or
after the lookup value in an alphabetically sorted list.
If it comes
before it checks the the entry int he middle between the beginning
of the list and the middle.
If your entry happens to be in the latter half lookup never finds this entry
or
This value might not exists so it picks the first value it can find that would come before that (assuming the data is sorted) or something (seemingly random) where lookup finds value n to be alphabetically after the lookup value and n+1 alphabetically before and returns value n+1.
You should only use lookup if you know the lookup values will be there and that they will be sorted. Otherwise you might want to take a look at VLookup or Index Match
Solution
If Column A in Sheet Draft options Actually contains those letters you are looking up you can use a simple VLookup:
=VLOOKUP(F2, `Draft Options`!$A$2:$B$1000, 2, FALSE)
Here FALSE specifies that VLookup shall not use a binary search algorithm and instead go through the list linearly (i.e. one by one) which is slower but will retrieve the first matching value or throw an error if it is not there instead of returning something odd.
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.