How to get smallest result from multi-criteria index/match function - excel

I have a sheet with transactions. Each txn has an airport and an amount of fuel pumped. I have a second sheet with a list of locations, each row of which has min and max values for fuel bands (e.g, 1-500, 501-1000, min/max stored in separate columns), and each each of which have a price (for fuel per gallon).
I need to use the values per row in the first spreadsheet to search the second spreadsheet for a match on airport (ICAO code), greater than bottom of band, and less than top of band, and then return the unit price of fuel. The catch is that I can have multiple matches, and I need the smallest/lowest value.
I have some familiarity with Index/Match multi criteria arrays. So, I wrote the following and tried it:
=INDEX(FuelPrices!$D$2:$D$3398,MATCH(1,(FuelPrices!A:A=H2)*(FuelPrices!B:B>=N2)*(FuelPrices!C:C<=N2),0))
Where "Fuel" is my first sheet and "FuelPrices" is the sheet I'm looking up the values in. No matter WHAT I do it throws an #NA error. So, I figured maybe the problem was I was returning an array? I tried this:
=INDEX(FuelPrices!$D$2:$D$3398,SMALL(MATCH(1,(FuelPrices!A:A=H2)*(FuelPrices!B:B>=N2)*(FuelPrices!C:C<=N2),0),1))
Figuring it would give me the smallest value from the returned array. No go. I've tried some other tricks (using another Index function around the match) and nothing seems to work.
Basically I just want to get the function to return the lowest matching value for the provided criteria.

The short answer is that the < and > are the wrong way round. This does give an answer
=INDEX(FuelPrices!$D$2:$D$10,MATCH(1,(FuelPrices!$A$2:$A$10=H2)*(FuelPrices!$B$2:$B$10<=N2)*(FuelPrices!$C$2:$C$10>=N2),0))
if entered as an array formula using CtrlShiftEnter
I have changed all ranges to a small number of rows for testing purposes.
FuelPrices sheet
Fuel sheet
If you do want to find the smallest subject to the same conditions, you don't need index but can use small (or min)
=SMALL(IF((FuelPrices!$A$2:$A$10=H2)*(FuelPrices!$B$2:$B$10<=N2)*(FuelPrices!$C$2:$C$10>=N2),FuelPrices!$D$2:$D$10),1)
Or if you prefer you can use Aggregate (non-array formula)
=AGGREGATE(15,6,FuelPrices!$D$2:$D$10/((FuelPrices!$A$2:$A$10=H2)*(FuelPrices!$B$2:$B$10<=N2)*(FuelPrices!$C$2:$C$10>=N2)),1)

Related

Find closest value in a Poisson distribution table

I am trying to find the closest value in this Poisson Distribution table to help create some variation in my NHL game simulator. Right now I have the minimum value set to =(MAX(H4:R14)/1.25) and the max as MAX(H4:R14). My rand (random) value is set to =RAND()*($V$4-$U$4)+$U$4. My question is, is how do you find the closest value in the table when compared to the random value? Returning the closest match (percentage) is ideal and the table's values will change whenever the teams change. Eventually, I am trying to return the respective column and row values (goals for each team), but this is step 1 and haven't been able to figure it out yet - even with index and match. Feel like it should be fairly straightforward...
You may benefit from SUMPRODUCT and array formula to get closes match and goals values in rows and section. Just as example:
The upper table would be your data. The bottom table is just to check it it works, you can delete. This bottom table is just an absolute value of cell minus your rand. The minimun one is highlighted in green and that's the closest match. Notice how the formulas get the position of that match and the goals values:
Formula to get ROW VALUE:
=SUMPRODUCT(--(ABS(H4:R14-U6)=MIN(ABS(H4:R14-U6)))*G4:G14)
Formula to get COLUMN VALUE:
=SUMPRODUCT(--(ABS(H4:R14-U6)=MIN(ABS(H4:R14-U6)))*H3:R3)
Both of this formulas are array formulas, so to introduce them yo must press CTRL+ENTER+SHIFT or they won't work!
To get the closest match is just INDEX classic formula (we add +1 due to goals indexed as 0,1,2...):
=INDEX(H4:R14,U9+1,V9+1)
See it working!:
I've uploaded the file in case you want to check the formulas:
https://docs.google.com/spreadsheets/d/1wV8bn6B-jZ4jCxAonGdWFMluAEybzwkA/edit?usp=share_link&ouid=114417674018837700466&rtpof=true&sd=true
Please, notice this will work properly as far as there is a single closest match. If by any case two cells are both closest match, formula will return incorrect result.
And remember, as I said before, second table is just to explain the solution, you can delete it and everything will work.
You could create a 2nd table where you calculate the absolute or squared difference between your Poisson table values and the random value.
Then you can simply check for the smallest value in the 2nd table.
In your example, the 2nd table of differences could be created with the formula
=ABS($H$4:$R$14-$U$6)
Let's assume that this 2nd table is just below the 1st table, i.e. in H16:R26
Then the smallest value in this 2nd table is obtained by
=SMALL($H$16:$R$26,1)
from there you can get the row number through
=SUM(($H$16:$R$26=SMALL($H$16:$R$26,1))*($G$4:$G$14))
and the column number through
=SUM(($H$16:$R$26=SMALL($H$16:$R$26,1))*($H$3:$R$3))
Then, to find the closest match in the original table, you can use the INDEX() function and refer to the row and column calculated in the previous step.
You can of course skip all the intermediary steps and write everything into a single formula:
=LET(
table,$H$4:$R$14,
diff,ABS(table-$U$6),
closest,SMALL(diff,1),
closest_row,SUM((diff=closest)*SEQUENCE(ROWS(table))),
closest_col,SUM((diff=closest)*SEQUENCE(1,COLUMNS(table))),
INDEX(table,closest_row,closest_col)
)
Which looks like this:
Note: the last formula uses dynamic arrays and functions only available Excel O365.

Using vlookup while using web external data

Good afternoon,
I am pulling a fuel database from gasbuddy and trying to use the VLOOKUP function to grab address, prices and times last updated. However, all I am getting are #N/A (value not available) results. My code is below:
=VLOOKUP(
N5,
GasPriceSearch.aspx?typ_adv_fuel_limit_36,
COLUMN(B5),
FALSE)
I tried converting this information into a table and the formula works but I run into issues where new fuel prices are reported and it messes up the entire table. I would rather do it from the initial data without a table.
Thank you,
Jesse
There are several ways to achieve this. However, based on your data structure, a regular VLOOKUP won't work because VLOOKUP only searches to the right of the lookup value (i.e., the address) and, for example, the price is to the left of it. Thus, one possibility would be to restructure your data so that you have address, price, update, and so on. This would also circumvent the problem of having the price on a different row than the lookup value.
Another way to work with this data structure is to use the INDEX function:
=INDEX(array, row_num, [column_num])
Your array reflects the range where your data is stored that you want to look up; in your case, considering only price and station A:B. Since you've hidden some columns, it's hard to see what else is in this datasheet. But just adjust it to your needs of the data.
The row number can be hard coded. However, since you want to look up a specific value (i.e., address), you can use the MATCH function:
=MATCH(lookup_value, lookup_array, [match_type])
In this step you want to look up your address from column N in column B, where all stations are listed. You also need to specify the column you want to return. Again, you can either hard code it or use the MATCH function. With the match_type you can specify, for example, that you only want an exact match, i.e., match_type = 0.
To return the value "update" to the left of the address, your formula looks as follows:
=INDEX($A:$B,MATCH(N6,$B:$B,0),1)
To return the address itself (which is pretty much useless, since you already have it in column N), use the following formula with the adjusted column value from 1 to 2:
=INDEX($A:$B,MATCH(N6,$B:$B,0),2)
Lastly, your price information is one row above the address, you need to adjust the number of rows by -1 accordingly. That is, if your address is, for example, 4123 Town [...], you want to return column 1 of row 6 and not row 7:
=INDEX($A:$B,MATCH(N6,$B:$B,0)-1,1)
An alternative strategy would be to use the XLOOKUP function (only available in newer versions of Excel), which allows you to find values to the left of the lookup value. But also with this strategy you would have to deal with the problem of row differences. The OFFSET function could prove useful in this context, but it does not make the approach much easier than the INDEX function.

Excel INDEX MATCH IF greater than 10%

I'm trying to find the most efficient way to summarise an excel sheet where only the results that are higher than 10% are included in a separate sheet.
I know how to use INDEX MATCH, and need to go one further and only INDEX MATCH when VALUE is greater than 10%'
See table, where top sheet is found in other tabs and summary sheet will populate only the description where greater than 10%.
I'm sure there is an elegant way of doing this, and I seem to over complicate my steps, breaking them down into extra columns for if, then trying to match, then return the referenced value, but ultimately I fail.
Why can't I just use Index Match (0.1,C:C,-1)? Where 0.1 is 10%. Col E, unformatted 'real' value is 0.01-0.15. Excel fails if I try =Match(0.1,E:E,-1).
This is a common mistake with MATCH. To use greater than your data set must be arranged in descending order. Likewise with less than your data set must be arranged in ascending order.
I'd suggest using the something like the following formula instead
=INDEX(A:A, AGGREGATE(15,6,ROW($A$3:$A$5)/($D$3:$D$5>0.1),ROW(1:1)))
which returns

Excel Mac: If these two arguments are true then count/sum the number of unique ID#s

This is what I am trying to figure out:
IF date in cell matches dates in range
and
If name in cell matches names in range
then
count/sum the number of unique ID#s
This is the formula I have:
=IF(Data!A:A=E10,(IF(Data!D:D=D11,(IF(Data!D:D=D11,SUM(IF(FREQUENCY(Data!C:C,Data!C:C)>0,1)),"ERROR3")),"ERROR2")),"ERROR1")
It does not output the correct info. It either counts all the unique IDs or it Errors out when it should have a result.
I hope I am on the right track, thank you for any help.
Sample dataset:
Try it as,
=SUMPRODUCT(SIGN((B$2:B$10>=E2)*(B$2:B$10<=F2))/
(COUNTIFS(B$2:B$10, ">="&E2, B$2:B$10, "<="&F2, A$2:A$10, A$2:A$10)+(B$2:B$10<E2)+(B$2:B$10>F2)))
First let me say that the question was pretty confusing before you posted an image of the data, as it appears that the term "dates in range" was completely misleading. In fact you are trying to match exact dates, not "ranges of date".
FREQUENCY is useful to detect the first appearance of an item in a column, but unfortunately, this "artificial trick" is not flexible enough to be mixed easily with other criteria, and most importantly FREQUENCY is not array friendly.
There's another method to achieve you goal, which is:
=SUMPRODUCT(((Data!$A$1:$A$24=E$10)*Data!$C$1:$C$24=$D11))/
COUNTIFS(Data!$A$1:$A$24,Data!$A$1:$A$24,Data!$B$1:$B$24,Data!$B$1:$B$24,Data!$C$1:$C$24,Data!$C$1:$C$24))
You can enter this formula in E11 in your sample image and copy/paste in the whole matrix.
The denominator of the formula (the second line) generates an array that counts for each row the number of duplicates.
The numerator sets the criteria. Since each successful row will repeat as many times in the numerator and in the denominator, each matching row will be counted for a total of one.
As a result, we obtain the number of "unique rows" that match the criteria.
The formula should not use complete columns such as A:A etc, make the effort to limit it to a reasonable number of rows, say A1:A999 or so. Complex formulas involving arrays must avoid as much as possible entire columns.

Counting number of items between two values

I have a list of cargo items, each with a Quantity, Length, Width, Height and Weight. I'm trying to produce a summary of how their dimensions are distributed (ideally taking the quantities of each into account, but that's a step beyond where I'm stuck).
I have one spreadsheet with length values in 0.1m intervals in Statistics!A2:A302, and I'm hoping to put the quantity for each length interval in Statistics!B2:B302. The quantities per item are in 'Steel plate list'!$B$3:$B$1002, and the lengths to look at are in 'Steel plate list'!$C$3:$C$1002.
Now, at the moment I have the following formula in Statistics!B2 and filled down:
=COUNTIFS('Steel plate list'!$C$3:$C$1002, ">="&A2, 'Steel plate list'!$C$3:$C$1002, "<"&A3)
That works fine, gives me the number of line items that have that length, but it means that, for instance, a single 8-metre plate counts as heavily as 260 12-metre plates. Is there any way to take the quantities into account? I've thought of using a VLOOKUP for it, but I can't think of a way to make that work.
Any thoughts?
Instead of COUNTIFS, you should be using SUMIFS. SUMIFS works like COUNTIFS, except that it adds all rows which match your criteria, instead of simply counting them.
So your formula would look almost identical to what you currently have [the first argument passed to SUMIFS is the range which you want summed, and the following arguments alternate as being either the range to look for a criteria, or the criteria to use agaisnt that range]:
=SUMIFS('Steel plate list'!$B$3:$B$1002,'Steel plate list'!$C$3:$C$1002, ">="&A2, 'Steel plate list'!$C$3:$C$1002, "<"&A3)
As you can see, apart from changing the function from COUNTIFS to SUMIFS, all I needed to do was add the first argument referencing column B on the other sheet, which holds the quantities for each row matching all criteria.
To sum the quantity (not sum the dimensions) of the pieces you can use this array formula:
=SUM(IF('Steel plate list'!$B$2:$B$10>=A2,IF('Steel plate list'!$B$2:$B$10<A3,'Steel plate list'!$A$2:$A$10,0),0))
Press Ctrl+Shift+Enter to create the array formula.
This assumes that column A contains Quantity and column B contains Length.
The formula will show that you have how many pieces for a given dimension on the Statistic page. Example, 1 piece of 8-meter and 260 12-meter pieces.

Resources