How to use Index to find all values greater than - excel

I've been researching my situation quite a bit, both on this site and others, with this being the closest to my problem/solution:
Find all values greater or equal than a certain value
However, using that solution in my situation does not give me the correct results. I have a list of 83 names with penalties being given to each name. On a separate tab, I'd like to display the output of all names that have any penalty (>0).
I only have four possible penalties, so if I need to reference them in the formula (match or lookup), that would be fine also. Shortening and dummying the data, here is an example of what I have:
+----------+---------+
| Name | Penalty |
+----------+---------+
| Name 1 | 0 |
| Name 2 | 0 |
| Name 3 | 5 |
| Name 4 | 0 |
| Name 5 | 0 |
| Name 6 | 10 |
| Name 7 | 0 |
| Name 8 | 0 |
| Name 9 | 0 |
| Name 10 | 20 |
+----------+---------+
Using this formula, then CSE and drag down:
=INDEX($R$4:$R$13,SMALL(IF($S$4:$S$13>0,ROW($S$4:$S$13)),ROW(1:1)))
It gives me these results:
+---------+
| Name 6 |
| Name 9 |
| #REF! |
| #NUM! |
| #NUM! |
| #NUM! |
| #NUM! |
| #NUM! |
| #NUM! |
| #NUM! |
+---------+
I'll be taking care of the errors by using an IFERROR and making them blank, but it's still not finding the correct names of those with penalty points >0
edit: Changing the last "ROW" part gives me different answers, so I think my problem lies there somehow, but I still don't know what to do with it. That's supposed to be the "k" value of the "SMALL" function.
Any help is much appreciated. Thanks!

I prefer using MATCH() instead of SMALL():
=INDEX($R$4:$R$13,MATCH(1,($S$4:$S$13>0)*(COUNTIF($U$3:U3,$R$4:$R$13)=0),0))
It is an Array formula so use Ctrl-Shift-Enter.
Also this formula requires that it start in at least the second row as the countif needs to refer to the cell above to avoid a circular reference.
If you really want to use SMALL() then you need to make an adjustment for the starting row:
=INDEX($R$4:$R$13,SMALL(IF($S$4:$S$13>0,ROW($S$4:$S$13)-ROW($S$4)+1),ROW(1:1)))
Or as #dirk pointed out the array part is the SMALL() not the INDEX, so it is okay to use the full column in the INDEX part and use your SMALL as is as it will return the actual row number:
=INDEX($R:$R$,SMALL(IF($S$4:$S$13>0,ROW($S$4:$S$13)),ROW(1:1)))
Also an array formula so confirm with Ctrl-Shift-Enter.
Another method is to use the AGGREGATE which is entered without the CSE as a normal formula:
=INDEX($R:$R,AGGREGATE(15,6,ROW($R$4:$R$13)/($S$4:$S$13>0),ROW(1:1))
This gets entered in as a regular formula. It is still an array type formula so one still needs to use only the dataset as a reference and avoid full column references in the array part of the formula.
The last two are particularly helpful when first returned result is desired in the first row, as they do not require the COUNTIF() to maintain the Unique return.

Related

Excel: Partial matching Range 1 against each cell string individually in Range 2, then returning value in column

If you can help me I love you.
Let's say I have a bunch of URLs:
| Range 1 |
|------------------------|
| www.orange.com |
| www.orange.example.com |
| www.example.red.com |
| www.example.com/blue |
And I also have a table like this:
| Range 2 | Range 3 |
|---------|---------|
| orange | 1 |
| red | 2 |
| blue | 3 |
| green | 4 |
| pink | 5 |
How could I write a formula to pull down alongside the URL list so that it looks like:
| Range 1 | Results |
|------------------------|---------|
| www.orange.com | 1 |
| www.orange.example.com | 1 |
| www.example.red.com | 2 |
| www.example.com/blue | 3 |
Essentially doing partial matches every time and then returning a result to the right.
Driving me nuts, you're my only hope!
Google Sheets.
=ArrayFormula(LOOKUP(1,0/COUNTIF(A1,"*"&C$1:C$5&"*"),D$1:D$5))
MSOFFICE
=LOOKUP(1,0/FIND(C$1:C$5,A1),D$1:D$5)
This will only work if the string does not contain multiple partial strings in your list, but you can just INDEX the lookup array using the row number of a partial match.
For example:
=IFERROR(
INDEX($B$1:$B$5, CONCAT(IFERROR(
FIND($A$1:$A$5,D5)+ROW($A$1:$A$5)-FIND($A$1:$A$5,D5),
""))),"")
Here we first generate a vector testing the location of all values in the lookup array against the string using FIND. All but one element in this vector are #VALUE!. The remaining element is the location of the first character in the string being tested that is the same as the value in the lookup array.
Next we convert this value to the row number in the lookup array by adding another equal sized vector of sequential row numbers, and then subtracting the original quantity. Note that arithmetic on a #VALUE! return will still yield #VALUE!. Also note that the vector of row numbers as generated in the answer above (the ...ROW($A$1:$A$5)) must begin in the first row; if your lookup array starts in row 3 for example, you would need to do something like ...ROW($A$3:$A$7)-2 to get the result you desire.
Finally, we replace any #VALUE! return with an empty string and concatenate the entire vector. The result is the row number of the lookup array which contains a partial string in the full string. This row number is used in an INDEX to achieve the desired results.

Sum All VLOOKUP Matches

I have a sheet where I am recording what I eat:
Another where I keep an index of values to lookup
I tried
=SUM(VLOOKUP('Sheet1'!A2:A11,'Sheet2'!A2:E11,2,FALSE))
but that only returned the first match, so then I tried
=SUMPRODUCT(SUMIF('Sheet1'!A2:A11,'Sheet2'!A2:A11,'Sheet2'!B2:B11))
but that isn't working either.
does anyone have a solution, where I can also multiply the value of the return match by the # of servings in the first sheet?
Thanks!
If you want a single output of calories through SUMPRODUCT then you can use
=SUMPRODUCT(B2:B11*IFERROR(VLOOKUP(A2:A11,Sheet2!A2:B11,2,0),0))
If you are sure that all entries on Sheet 1 can be located on Sheet 2 then you can drop IFERROR portion like
=SUMPRODUCT(B2:B11*VLOOKUP(A2:A11,Sheet2!A2:B11,2,0)).
Beware that if a value is not found in Sheet 2 then formula will produce wrong result as IFERROR will multiply the serving quantity with 0.
I combine 2 tables into one sheet, Table 1 housed in Column A & B and Table 2 housed in Column D & E
In G2, "Total Serving Colories" enter formula :
=SUMPRODUCT(VLOOKUP(T(IF({1},A2:A12)),D2:E12,2,FALSE)*B2:B12)
It's not super-clear what you're trying to get at. But defining the "Calories Per Serving" in a range called "cals",
+---+---------+-----+--------------------------------+
| | A | B | C |
+---+---------+-----+--------------------------------+
| 1 | egg | 3 | =(VLOOKUP(A2,cals,2,FALSE))*B2 |
| 2 | oatmeal | 1.5 | =(VLOOKUP(A3,cals,2,FALSE))*B3 |
| 3 | shrimp | 2 | =(VLOOKUP(A4,cals,2,FALSE))*B4 |
+---+---------+-----+--------------------------------+
Results in:

Excel: retrieve data based on a column

I have an excel document with a checklist like this one:
| number | yes/no | notes |
| 1 | yes | blablabla |
| 2 | yes | twinkle twinkle |
| 3 | no | little star |
I'd like to "echo" the fields which are set as "no" (in the second column) in another sheet, echoing the columns "number" and "notes". The result of my example would be:
| number | notes |
| 3 | little star |
How could I do it? Thanks!
Assuming your Main Table is in Sheet2, range A2:A4 (row 1 being headers). Use this formula, as an array (enter with CTRL+SHIFT+ENTER) in your sheet 2:
=INDEX(Sheet2!A$2:A$4,SMALL(IF(Sheet2!$B$2:$B$4="No",ROW(Sheet2!A$2:A$4)-ROW(Sheet2!A$2)+1),ROWS(Sheet2!A$2:A2)))
This will return all the Numbers. To get the Notes, change the very first index range to Sheet2!C$2:C$4. Obviously adjust your range down as necessary (I doubt you only have 4 of these).
Finally, just wrap an IfError() around that, so it looks nice when you use it. As you add data to your table, your table of only "no" values will update.
=IfError(INDEX(Sheet2!A$2:A$4,SMALL(IF(Sheet2!$B$2:$B$4="No",ROW(Sheet2!A$2:A$4)-ROW(Sheet2!A$2)+1),ROWS(Sheet2!A$2:A2))),"").
edit:
Screenshots:
(Using the IfError([above formula],"") wrapper hides the #NUM results when there's no match.)

EXCEL find the last relative maximum in a array (formula, not VBA)

I have a range containing values such as:
169.7978
168.633
168.5479
168.7819
167.7407
165.4146
165.1232
I don't need the maximum value of the range, i.e., the first cell in this example), but the last relative maximum, which in this case is the fourth cell. Is there a way to get this value without having to write a VBA macro? The formula must be general enough to work with a multiple number of maxima.
It may be a bit limited, but you may start somewhere as below.
Stated array in the OP is:
+----------+---+
| y | x |
+----------+---+
| 169.7978 | 1 |
| 168.633 | 2 |
| 168.5479 | 3 |
| 168.7819 | 4 |
| 167.7407 | 5 |
| 165.4146 | 6 |
| 165.1232 | 7 |
+----------+---+
Given this, you can find direct adjacency relative min/max with the following helper columns
Assign a Global_Rank helper column and look for y distro identical trend on both adjacent f(x) with the following formulas ( assuming your data is sorted by the x index )( formulas from Row 2 and filled down ).
RelativeMax:
=IF(AND(D2<=D1,D2<=D3),"RelativeMax","")
RelativeMin:
=IF(AND(D2>=D1,D2>=D3),"RelativeMin","")
Modify as needed. Hope this helps.
Edit:
Although...
If you're going to assume the data is ordered properly, you could also just use =IF(AND(B2>=B1,B2>=B3),"RelativeMin",IF(AND(B2<=B1,B2<=B3),"RelativeMax","")) and skip all the malarkey. This should work with multiple maxima/minima. Please report back with results from your dataset!

MAX date value within a range with 2 conditions

To make it easy
+---+----+-------------+
| | A | B |
+---+----+-------------+
| 1 | xx | 12-05-2015 |
| 2 | xx | 15-05-2015 |
| 3 | yy | 13-05-2015 |
| 4 | yy | 16-05-2015 |
+---+----+-------------+
(today is 14-05-2015)
I need to get the MAX date value for each "A" value only if it is before today.
In case it's not, move to the 2nd biggest value. Case it does not find, empty cell.
What I've done so far:
=MAX($A$1:$A$4='xx';$B$1:$B$4<TODAY();$B$1:$B$4)
and confirm with SHIFT+CTRL+ENTER
The error I get is that it yields 13-05-2015 as max value for xx, which is obviously wrong (as if it does not take into account the $A$1:$A$4='xx'
You need to use nested if-functions. I.e. change your formula into:
{=MAX(IF($A$1:$A$4="xx", IF($B$1:$B$4<TODAY(), $B$1:$B$4)))}
And end it with Ctrl+Shift+Enter
A standard (non-array) formula alternative.
=MAX(INDEX((B:B)*(A:A="xx")*(B:B<TODAY()), , ))
      
This formula would benefits from having its cell ranges cut down from full columns to something closer to the usable data range.
If your dates are sorted ascending as shown in the example then you can use LOOKUP like this:
=LOOKUP(2,1/(A$1:A$100="xx")/(B$1:B$100<TODAY()),B$1:B$100)
Doesn't require "array entry"

Resources