A1 B1 C1

fruit and veg fruit and veg Value

Carrot Broad bean 20

Butternut Squash Asparagus 5

Brussels sprout Grape 90

Broccoli Fig 60

Broad bean Broccoli 150

Black-eye bean Banana 450

Beetroot

Banana

Avocado

Aubergine

Asparagus

Apricot

Apple

Cherry

Clementine

Courgette

Date

Elderberry

Endive

Fennel

Fig

Garlic

Grape

I want formula to get result as follow:

fruit and veg Value

Carrot

Butternut Squash

Brussels sprout

Broccoli 150

Broad bean 20

Black-eye bean

Beetroot

Banana 450

Avocado

Aubergine

Asparagus 5

Apricot

Apple

Cherry

Clementine

Courgette

Date

Elderberry

Endive

Fennel

Fig 60

Garlic

Grape 90

This is a common request whereby you want to match multiple criteria. The three general methods I employ to do this us:

- INDEX & MATCH using Array Formulas
- SUMPRODUCT
- SUMIFS

Given the blog post is based on INDEX & MATCH, the formula I’ve used is as follows:

`=INDEX(`

After typing this formula you need to press Ctrl + Shift as it is an Array Formula (i.e. it references/joins multiple ranges). You’ll note the formula will display in between { and } brackets to indicate as much.

I include the “::” string in between as a delimeter between the fields we are querying. In essence, the string we are matching is a concatenation of the **Product** and the **Store**.

So introducing a string in between, the query string becomes `1-234::1`

for `Product = 1-234`

and `Store = 1`

. If it is not there, it is difficult for us to tell the difference between `Product = 1-234`

and `Store = 1`

and `Product = 1-23`

from `Store = 41`

, for example.

I’ve included a solution to your request using all three methods here: Multiple Criteria Lookup for Margaret (RK 2014-03-04).xls

Hope this helps.

]]>I would like to match a set of values (product codes in table 1) to another set of values (in several tables as shown in table 2, 3) to see if they match. If yes, then return a value. I appreciate your suggestion. Thank you.

For example,

Table 1.

Store Product Return

1 1-234 2

1 2-345 2

1 3-456 2

2 1-234 3

2 4-567 3

2 6-789 3

Table 2.

Return Product

2 1-234

2 2-345

2 3-456

Table 3.

Return Product

3 1-234

3 4-567

3 6-789

The Dynamic Named Range refers to the following:

`=OFFSET('Input Data'!$A$1,0,0,COUNTA('Input Data'!$A:$A),COUNTA('Input Data'!$1:$1))`

And will expand as you add more rows below your data set in the ‘Input Data’ worksheet.

Reply to me if you have any other questions or this isn’t what you are after.

]]>Unfortunately, I don’t think that VLOOKUP or INDEX/MATCH are the right tools for you to use to output a filtered list.

In essence you are simply filtering the list, rather than looking up a value against a set of criteria.

What about using a Pivot Table whereby you filter the table to display only those with non-zero quantities? You can have the Pivot Table refer to a dynamic named range. You have to manually refresh the Pivot Table data when you make any changes (which you can do via menus), otherwise you can make it update automatically with a few lines of VBA:

`Private Sub Worksheet_Activate()`

PivotTables(1).PivotCache.Refresh

End Sub

I’ve uploaded an example of the file here: http://blog.kirgs.com/wp-content/examples/Example-for-Wealth-Coach.xlsm

]]>Name State Qty

Apples WA 5

Oranges FL

Car MI 8

Furniture VA 3

Corn IN

Notice that the Qty is null in many of the rows. Desired output on Worksheet B:

Name State Qty

Apples WA 5

Car MI 8

Furniture VA 3

So the output does not include the empty qty records. I’ve tried various vlookup formulas and others and am just having a hard time. I’d prefer to do this with a formula rather than VBA macro or such and not using a filter. Any help would be gratifying.

]]>If you don’t want to use INDEX() and MATCH() you might like to try:

`=SUMPRODUCT(($A2=dataName)*(B$1=dataID)*(dataResult))`

in B2. It’s not an array formula (so no Ctrl + Shift + Enter) and it’s a lot more intuitive.

Where there’s no match, you’ll see a 0. You can hide these in a number of ways:

1. `=IF(SUMPRODUCT(($A2=dataName)*(B$1=dataID)*(dataResult))=0,"",SUMPRODUCT(($A2=dataName)*(B$1=dataID)*(dataResult)))`

2. Select the cells, right-click and select “Format Cells”. From the “Custom” menu, append two semi-colons to the format. e.g. “General” becomes “General;;”

Plus others.

]]>I had a look at the *email *of your post (that maintained the correct formatting for some reason) and think I have an idea as to what you are after. My interpretation is that you want to match two criteria; the name in the leftmost column of **Sheet1** and the number in the top row **Sheet1** – if there’s a match in **Sheet2**, then return the value in the rightmost column of **Sheet2**.

Lets start with **Sheet2** because this is where your raw data is kept. In fact, if it’s ok, I’ll rename the worksheet to **Data**

**Data**

A | B | C | |

1 | 1 | name1 | 5 |

2 | 2 | name2 | 6 |

3 | 3 | name3 | 7 |

4 | 4 | name4 | 8 |

5 | 5 | name5 | 9 |

6 | 6 | name6 | 9 |

7 | 7 | name7 | 10 |

8 | 8 | name8 | 11 |

9 | 9 | name9 | 12 |

At this point, I’d always recommend using named ranges on these columns, but to keep the solution in cell reference terms, we can substitute this in later.

Now, turning our attention to **Sheet1** (which I’ll call **Output**)…

**Output**

A | B | C | D | E | F | G | H | I | |

1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |

2 | name1 | ??? | ??? | ??? | ??? | ??? | ??? | ??? | ??? |

3 | name2 | ??? | ??? | ??? | ??? | ??? | ??? | ??? | ??? |

4 | name3 | ??? | ??? | ??? | ??? | ??? | ??? | ??? | ??? |

5 | name4 | ??? | ??? | ??? | ??? | ??? | ??? | ??? | ??? |

6 | name5 | ??? | ??? | ??? | ??? | ??? | ??? | ??? | ??? |

7 | name6 | ??? | ??? | ??? | ??? | ??? | ??? | ??? | ??? |

8 | name7 | ??? | ??? | ??? | ??? | ??? | ??? | ??? | ??? |

9 | name8 | ??? | ??? | ??? | ??? | ??? | ??? | ??? | ??? |

To reiterate, what I think you want to do is populate the coloured cells (containing **???**) when there is a match to the column and row. As mentioned, there are more ways to do this than I care to mention, but the first that comes to mind involves using INDEX() and MATCH() (thank goodness, being the title of the blog entry and all

Let’s start by clicking on the first cell we want to calculate on the **Output** worksheet: **B2**.

From earlier, INDEX() can be described as:

=**INDEX**(**array,row_num,column_num)**

Here, the **array** we are after is the rightmost column in the **Data** worksheet (**Data!$C$1:$C$8**). Being only one column wide, the only **column_num** we can have is **1**. But how do we work out the **row_num** when there are two criteria? One way to do this is to concatenate the two search terms. You do this by using an ampersand (&). You then concatenate the columns you want to search so you’re comparing apples to apples (so to speak.)

Describing MATCH():

=**MATCH**(**Lookup_value**,**Lookup_array**,**Match_type**)

So our **Lookup_value** for this first cell is **$A2&B$1**. We use the dollar ($) symbol in front of the **A** in **$A1** to confine the search queries to the first column (i.e. the ones with **name1**…**name8** in them). Similarly, we use the dollar ($) symbol in from of the **1** in **B$1** to confine the searches to the first row. That way, when we copy the formula to the other cells, we’re always matching the leftmost/top column that corresponds the cell we’re in.

As mentioned, our **Lookup_array** is also a concatenation, however this time it is **Data!$B$1:$B$8&Data!$A$1:$A$8**. We have dollar ($) symbols in front of of all row and column references here because the raw data doesn’t move (i.e. its position is not relative the cells).

This results in:

`=MATCH(Output!$A2&Output!B$1,Data!$B$1:$B$8&Data!$A$1:$A$8,0)`

So…putting it altogether we have:

`=INDEX(Data!$C$1:$C$8,MATCH(Output!$A2&Output!B$1,Data!$B$1:$B$8&Data!$A$1:$A$8,0),1)`

but pressing return results in **#VALUE**. This is because concatenating strings in a function such as this returns an array. To formulate cells like this instead of press **Enter** after entering the formula, you need to press **Shift and Enter** at the same time. This will put curly brackets ({ and }) around the formula. In doing so, for this example, you should now see the number **5** in **B2** which corresponds to the two criteria in the raw data.

You only need to do this once, as we’re going to now place the cursor on the bottom right-hand corner of **B2** until the cross appears and will drag the formula to the other cells in the table. You can’t copy and paste the formula to more than one cell as Excel will complain that you “cannot change part of an array.”

The only problem now is that there are **#N/As** where there isn’t a corresponding value in the raw data What’s a quick way to get rid of this. What I do is use a simple if statement to return nothing if the result is an **#N/A**. What I do in this instance is use a combination of the **IF()** and **ISNA()** functions.

To describe this in broad terms:

=`IF(ISNA(`

*cell value*),*nothing*,*something*)

i.e. if the cell value is #N/A then return nothing; otherwise, return something. In this case, it’s the **MATCH()** function that is returning the **#N/A**, so we only need to use that as the in the above.

Our formula for **B2** now becomes:

=`{IF(ISNA(MATCH(Output!$A2&Output!B$1,Data!$B$1:$B$8&Data!$A$1:$A$8,0)),”",INDEX(Data!$C$1:$C$8,MATCH(Output!$A2&Output!B$1,Data!$B$1:$B$8&Data!$A$1:$A$8,0),1))}`

(without the curly brackets – these are put in the cells formula after pressing **Shift** + **Enter**.

As you can see, this formula is ridiculously long. Named ranges will improve this. For instance defining:

dataID => Data!$A$1:$A$8

dataName => Data!$B$1:$B$8

dataResult => Data!$C$1:$C$8

reduces the formula to:

`={IF(ISNA(MATCH($A2&B$1,dataName&dataID,0)),”",INDEX(dataResult,MATCH($A2&B$1,dataName&dataID,0),1))}`

**Output**

A | B | C | D | E | F | G | H | I | |

1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |

2 | name1 | 5 | |||||||

3 | name2 | 6 | |||||||

4 | name3 | 7 | |||||||

5 | name4 | 8 | |||||||

6 | name5 | 9 | |||||||

7 | name6 | 10 | |||||||

8 | name7 | 11 | |||||||

9 | name8 | 12 |

Hopefully this is what you were after

]]>