I'd like you to explain why this formula works: =LOOKUP(2,1/(A2:A10=D2),B2:B10)
I know about lookup, I know what this formula does (The following formula searches A2:A10 for the last instance of the value in D2, and returns the corresponding value from B2:B10...) but I don't understand how it works. For example what does this part do: A2:A10=D2 ?
Here is the source where you can find the workbook also: http://www.xl-central.com/lookup-last-instance.html
LOOKUP(lookup_value, lookup_vector, [result_vector])
The LOOKUP function is a very basic cousin of the HLOOKUP function and VLOOKUP function. The latter two provide additional functionality for selecting the row/column of data to return from their table_array parameter (row_index_num/col_index_num) as well as a range_lookup option which can force an exact match or an approximate (aka nearest) match when used with sorted data. The LOOKUP function has to have the result_vector (return row or column) specified if it is not the same as the lookup_vector and always returns the nearest match.
Excel treats TRUE as one and FALSE as zero when used mathematically. A 1 divided by 1 will equal 1 and a 1 divided by 0 is a #DIV/0! error. A #DIV/0! error will not match anything; not even another #DIV/0! error. Since you are looking for a 2, it finds something that might be the best match in row 2 (e.g. 1/1) but keeps looking since it is not an exact match. It finds another possible in row 5 but keeps looking. It finds another possible in row 8 and cannot find anything remotely close below that so it returns the value from column B in row 8. We are looking to match a 2 with a series on 1's and errors because we want the last nearest match.
For all intents and purposes, you are breaking the rules when using this type of formula as the lookup_vector is not in ascending order (which conventionally it should be). With the unsorted duplicate values we are achieving the correct results by relying on the function's 'broken' behavior when looking for a value it will never find; e.g. looking for a 2 in an array of 1's and errors.
Related
We use this format in our casino to know where we have to send our employees to certain tables or games. We recently changed the way we do this and we now need to have some checks to make sure we didn't forget certain tables.
Every hour/half hour/20mins we assign a table to a person, everyone else moves one up. We know exactly which tables are open at which times. We fill this in at the top. When we fill in the upcoming timeslot we would like to have some check so we don't forget a table and maybe miss out a employee.
Example:
In the example supplied you can see that we accidentally have two number 6's but no 7 I highlighted the number 7 in the top row but it would be nice if this is doable automatically
I used VLOOKUP and INDEX/MATCH in the formula for Conditional formatting but that does not seem to create the correct outcome.
Here is an example of how it can be done:
The formula used has the array {1;2;3;4;5;6;7} hard written into it, assuming that the number of tables does not vary. The output is 0 when no table is missing, otherwise it returns a list of missing tables separated by commas.
Note: That of course means, the comma separated list is not a numeric value but a string value and cannot be used for further calculations. If further calculations on this output are required, the 'solution' has to be changed accordingly.
Formula
=IFERROR(CONCAT(FILTER({1;2;3;4;5;6;7},ISERROR(MATCH({1;2;3;4;5;6;7},H5:H24,0)))&", "),0)
Explanation
The MATCH() function checks which of the numbers 1 to 7 are present in the given range (here H5:H24) and returns the cell index of where it is found. When a number does not appear in the range, the MATCH() function will generate an #N/A error for that number.
Then, the ISERROR() function will output a FALSE value for all numbers found by MATCH() and a TRUE value for those numbers where the MATCH() function lead to an error.
The FILTER() function filters and thereby reduces the number array {1;2;3;4;5;6;7} to only those numbers where the ISERROR() function is TRUE.
The CONCAT() function concatenates the resulting array from the FILTER() function (in case more than 1 number is missing) to a single string of numbers separated by commas.
However, when there are no open tables, i.e. the MATCH() function finds all numbers 1 to 7 in the given range, then the ISERROR() function will only return FALSE values and the thus the FILTER() function returns an 'empty' array, which is not allowed in excel and leads to an #CALC error in excel. This case is captured by the IFERROR() function encapsulating the whole calculation, and instead of showing the error, returning 0.
What about this formula:
=AND(COUNTIF(A$2:A$10,1)=1,COUNTIF(A$2:A$10,2)=1,COUNTIF(A$2:A$10,3)=1,COUNTIF(A$2:A$10,4)=1,COUNTIF(A$2:A$10,5)=1,COUNTIF(A$2:A$10,6)=1,COUNTIF(A$2:A$10,7)=1)
A bit clearer:
=AND(COUNTIF(A$2:A$10,1)=1,
COUNTIF(A$2:A$10,2)=1,
COUNTIF(A$2:A$10,3)=1,
COUNTIF(A$2:A$10,4)=1,
COUNTIF(A$2:A$10,5)=1,
COUNTIF(A$2:A$10,6)=1,
COUNTIF(A$2:A$10,7)=1)
... which means that the number of ones need to be 1, the number of twos need to be 1, ..., up to the number of sevens.
Hereby a screenshot of an Excel sheet, which contains that formula:
In order to understand how this works, you might work with formula auditing, more especially formula evaluating, hereby an extra screenshot, showing formula evaluating after some steps:
Have fun :-)
I wonder if there is a VLOOKUP formula that looks first in one column and if there is no match, proceeds to the next column and if there's still no match returns a value, for example, NO MATCH.
I've been trying to Google and YouTube the issue but couldn't find anything. Hope someone can help me here.
lets say you lookup table is is from A1:D6 with columns A and B your look up values. And the value you are looking for is in G6
start with your basic VLOOKUP function as follows:
=VLOOKUP(G6,A1:D6,3,0)
This assumes you want the value from the third column in your range (C in this case) to be returned because of the 3. You are also looking for an exact match as defined by 0.
If the value you are looking for is not found in column 1 it will produce an error. As such we can use the IFERROR function to tell us what to do when an error occurs.
=IFERROR(VLOOKUP(G6,A1:D6,3,0),VLOOKUP(G6,B1:D6,2,0))
So in the event of an error it performs the second lookup. notice the range for the look up starts in column B instead of A. Also notice that Column C is now the 2nd column in the range so the 3 changed to a 2. Now if its not found in either situation, we can simply nest the IFERROR inside another IFERROR as follows:
=IFERROR(IFERROR(VLOOKUP(G6,A1:D6,3,0),VLOOKUP(G6,B1:D6,2,0)),G6&" not found in first two columns")
This method will return the first value that matches your search criteria that it encounters starting from the top in column one and if that fails the first value from the top in column 2. It neither is found it will post an error message.
There are other ways to do this especially if there were a max of one instance of the look up value in the two columns or if you did not care about columns and just wanted the first/last row (or nth row) of the occurrence.
Ok, let me see if i can phrase this properly. I have a table with values I want to search that have duplicate items in the reference column but i want the lowest value in the adjacent column. I've sorted according to the reference column then the column with the values in ascending order. For normal look-ups the vlookup function returns the first row and that suits me for normal searches. The caveat here is that my reference column values contain wildcards and when it it finds similar items it returns the values from the last instance; here is my issue:
1. Item Value
2. abc* 3
3. abd* 5
4. abe* 4
5. abe* 6
I want my vlookup to return the first instance of abe* of 4 but it always gets the second or last instance of 6. Since I'm searching in items containing wildcards I use the parameter FALSE for the closest match. I don't understand why it wont return the first instance. Am I missing something? Is there a better function to do what I need?
I apologize if this is the wrong venue for my question. Please direct me to the correct one if I am in error.
I am working through a spreadsheet created by someone else and in one Worksheet Column A has a value obtained with the formula below;
=INDEX(Sites!A$2:AC$10000,MATCH(F2,Sites!P$2:P$10000,FALSE),3)
I am confused by this formula and wondered if someone could clarify it for me please. I have never used an INDEX MATCH formula before and when I google for it, there are no examples that use a FALSE or TRUE before the end value, in this case "3". Also if the last value is "3" or the third column in the lookup range - how can this be when the P$2:P$10000 only has one column, Column P?
Here is a screen image of the worksheet
The FALSE works but is wrong.
With the MATCH function the 3rd parameter is optional. If not specified it defaults to the value of 1, which tells the MATCH function that the data to search is sorted and to therefore use a Binary Search algorithm to do the matching... which is really fast.
A value of zero, tells the MATCH function to instead do a linear search from top to bottom until the value is found, or not found at the end. This is called an Exact-Match search. The value 0 should be used here. It just so happens that FALSE evaluates to zero, but there is no reason to use it here, and it is just misleading. It should be simply 0.
...
Regarding the 3 at the very end. This instructs the INDEX function to return the corresponding value in the THIRD column of: Sites!A$2:AC$10000.
Index Match is a pretty powerful combination. It will return a value from an Index (which you set via a range), then uses a Match() to get the row.
In your example, the formula will return some value in the range A2:AC10000. [I think though this needs to be edited to just A2:A10000?]
Great, but which cell in that range? We need to know a row. Think of it like getting a cell in a cross section. The Index part is the column, and now you need a way to say what ROW to use. This is where Match() comes in.
Match first uses some value you want to find. In your example, it's looking at the building name ("Kilibarachan Primary"). This name exists in a column somewhere, Column P. It will find that factory name in column P, and return the row number. This row number is then fed to the Index. Now you have the column (A) and the intersection row.
Edit: Excel Hero beat me to this, but I figured I'd leave it anyways.
There are quite a few questions on Stack Overflow about doing a conditional MIN and MAX in Excel
e.g. Excel: Find min/max values in a column among those matched from another column
However, I don't think the following question is covered.
Normally the MIN and MAX functions will ignore blank rows, however it seems that if used in conjunction with a conditional array formula then they will NOT ignore.
For instance
If I enter the array formula =MAX(IF(A1:A8="A",B1:B8)) then I get zero, when I really want to see -1, since of all the non-blank 'A' rows, the maximum is -1.
I thought that the following array formula would work =MAX(IF(AND(A1:A8="A",B1:B8<>""),B1:B8)) but it ALWAYS returns zero
You nearly had it! However, in an array formula, you cannot replicate an "AND" construction so straightforwardly, in essence since the return from the AND function is always a single value, never an array.
Hence, your attempt:
=MAX(IF(AND(A1:A8="A",B1:B8<>""),B1:B8))
would initially correctly resolve to (using the values you posted):
=MAX(IF(AND({TRUE;FALSE;TRUE;FALSE;TRUE;FALSE;TRUE;FALSE},{TRUE;TRUE;FALSE;TRUE;FALSE;TRUE;TRUE;FALSE}),B1:B8))
though the AND function would then look at that those two arrays of Boolean TRUE/FALSE returns and return a single value, i.e. FALSE (since there is at least one FALSE amongst those 16 entries).
The correct syntax would be:
=MAX(IF(A1:A8="A",IF(B1:B8<>"",B1:B8)))
Regards
you can test for blank in the if, and substitute an appropriate value if found.
The Array formula =MAX(IF(A1:A8="a",IF(ISBLANK(B1:B8),-999,B1:B8))) will substitute the value -999 for any blank cells, allowing you to find you maximum - alter the -999 depending on how low your numbers get