INDEX MATCH

The pair that replaces VLOOKUP entirely. MATCH finds the position of a value in a row or column. INDEX returns the value at a position. Together they look anywhere, in any direction, with no column counting.

Lookup & ReferenceIntermediate
Purpose
Look up a value in a table without the limitations of VLOOKUP. MATCH finds where, INDEX returns what.
Returns
A single value from any row or column you can describe
Combined syntax
=INDEX(return_column, MATCH(lookup_value, lookup_column, 0))
Excel version
Every version (INDEX since the beginning, MATCH since 1985)

How INDEX and MATCH work

Think of these as a two-step team. MATCH walks through a column or row looking for your lookup value and returns the position number when it finds it (3rd item, 12th item, etc.). INDEX takes a column or row plus a position number and returns the value at that position.

Used together, MATCH calculates the position and feeds that number straight into INDEX. The result is a lookup that doesn't care which column the value lives in or which direction it has to look. There's no column-counting like VLOOKUP requires, and inserting columns into your table doesn't break the formula.

= INDEX(array, row_num, [col_num])
= MATCH(lookup_value, lookup_array, [match_type])

Arguments

INDEX
ArgumentTypeRequiredDescription
arrayrange✓ RequiredThe range INDEX picks a value from. Can be one column, one row, or a 2D block (which enables the row+col form below).
row_numnumber✓ RequiredWhich row of the array to return, 1-based. Pass 0 to return the entire column. Most often supplied by a MATCH() call.
col_numnumber✗ OptionalWhich column of the array to return, 1-based. Only used when array is a 2D block. Skip it when array is a single column or row.
MATCH
ArgumentTypeRequiredDescription
lookup_valueany✓ RequiredThe value to find. Text, number, or cell reference.
lookup_arrayrange✓ RequiredThe single column or row to search. Must be one-dimensional, not a 2D block.
match_typenumber✗ Optional0 for exact match (almost always what you want). 1 for largest value <= lookup_value (data must be sorted ascending). -1 for smallest value >= lookup_value (sorted descending). Defaults to 1, which is the dangerous default.

INDEX alone: get a value at a specific row

Before pairing, see what each function does on its own. INDEX takes a column and a row number and returns the value at that position. The row number is relative to the array you give it, not the worksheet's row number.

=INDEX(B2:B11,5)
  • B2:B11 the column you're indexing into
  • 5 the position you want (1-based)
  • Returns the 5th value in B2:B11, which is whatever sits in B6
  • Static position this is just to show INDEX in isolation. The real power kicks in when MATCH calculates the position.
D2
fx
=INDEX(B2:B11,5)
ABCDE
1ProductPrice5th price
2Wireless mouse$29.99$67.99
3Keyboard$89.99
4Monitor 27"$349.99
5USB-C hub$44.99
6Laptop stand$67.99
7Webcam HD$129.99
8Desk lamp$39.99
9Cable manager$14.99
10Headset$159.99
11Mouse pad$19.99
Formula entered in cell D2. INDEX returns the 5th value of column B, which lives in B6.
The 5th item of B2:B11 lives in B6 (highlighted yellow). INDEX counts from the top of the array, not from row 1 of the sheet.

MATCH alone: find the position of a value

MATCH is the partner. Give it a value to find and a list to search, and it returns the position of the match. That's it. The third argument controls how MATCH compares, and you almost always want 0 (exact match).

=MATCH("Monitor 27\"",A2:A11,0)
  • "Monitor 27\"" what to find (the lookup value)
  • A2:A11 where to look (the lookup array)
  • 0 match type: 0 means exact match. The default of 1 is dangerous on unsorted data.
  • Returns the position number, not the value itself
D2
fx
=MATCH("Monitor 27""",A2:A11,0)
ABCDE
1ProductPricePosition
2Wireless mouse$29.993
3Keyboard$89.99
4Monitor 27"$349.99
5USB-C hub$44.99
6Laptop stand$67.99
7Webcam HD$129.99
8Desk lamp$39.99
9Cable manager$14.99
10Headset$159.99
11Mouse pad$19.99
Formula entered in cell D2. MATCH returns 3 because Monitor 27" is the 3rd item in A2:A11.
MATCH returns 3 because Monitor 27" sits in the 3rd position of A2:A11. That number is exactly what INDEX needs as its second argument.
Always pass 0 as the third argument unless you specifically want approximate matching. The default match_type is 1, which assumes your data is sorted ascending and silently returns wrong values when it isn't.

Combined: the classic VLOOKUP replacement

Now the magic. Drop MATCH into INDEX's row_num argument, and you have a lookup that finds the position automatically. This is the formula every senior analyst writes by reflex instead of VLOOKUP.

=INDEX(B2:B11,MATCH("Webcam HD",A2:A11,0))
  • B2:B11 the column to return from (Price)
  • MATCH("Webcam HD",A2:A11,0) calculates the position by finding Webcam HD in the Product column
  • The combo INDEX gets the position from MATCH and returns the price from the matching row
  • Add new columns doesn't break this formula. VLOOKUP would need its col_index_num updated.
D2
fx
=INDEX(B2:B11,MATCH("Webcam HD",A2:A11,0))
ABCDE
1ProductPriceWebcam price
2Wireless mouse$29.99$129.99
3Keyboard$89.99
4Monitor 27"$349.99
5USB-C hub$44.99
6Laptop stand$67.99
7Webcam HD$129.99
8Desk lamp$39.99
9Cable manager$14.99
10Headset$159.99
11Mouse pad$19.99
Formula entered in cell D2. MATCH finds the row for Webcam HD, INDEX returns the price from that row.
MATCH locates Webcam HD at position 6 in column A. INDEX returns the 6th item of column B, which is $129.99. Add a column between A and B and the formula keeps working.

Look left: the feature VLOOKUP literally cannot do

VLOOKUP can only look right. Your lookup column has to be first, and it returns from a column to its right. If your names are in column B and IDs are in column A and you want to look up by name and return the ID, VLOOKUP can't help. INDEX MATCH doesn't care about direction.

=INDEX(A2:A11,MATCH("Sarah Chen",B2:B11,0))
  • A2:A11 the column to RETURN (Employee ID, sitting to the LEFT of names)
  • MATCH("Sarah Chen",B2:B11,0) find the position by searching the Name column
  • No constraint the return column can be left, right, or in a different sheet entirely
  • VLOOKUP equivalent doesn't exist. Best you can do is restructure the sheet.
E2
fx
=INDEX(A2:A11,MATCH("Sarah Chen",B2:B11,0))
ABCDEF
1Employee IDNameDepartmentSarah's ID
2E-1042James MillerHRE-1156
3E-1088Maria SantosMarketing
4E-1103David BrownFinance
5E-1156Sarah ChenFinance
6E-1201Alex KimSales
7E-1245Rachel WoodEngineering
8E-1287Carlos GomezOperations
9E-1310Jenny LiuMarketing
10E-1356Mark ReillyEngineering
11E-1402Emma DavisIT
Formula entered in cell E2. The return column (A) sits to the LEFT of the lookup column (B). VLOOKUP can't do this.
MATCH finds Sarah Chen at position 4 of column B. INDEX returns the 4th item of column A, which is E-1156. The return column lives to the LEFT of the lookup column, which would be impossible with VLOOKUP.

Two-way INDEX MATCH: lookup by row AND column header

Use MATCH twice (once for the row, once for the column) and INDEX returns the value at the intersection. This is the formula for cross-tabbed tables: revenue by region by quarter, headcount by department by level, anything where you read across both dimensions.

=INDEX(B2:E5,MATCH("West",A2:A5,0),MATCH("Q3",B1:E1,0))
  • B2:E5 the data block, no headers (just the numbers)
  • MATCH("West",A2:A5,0) find which row holds West (returns 4)
  • MATCH("Q3",B1:E1,0) find which column holds Q3 (returns 3)
  • Result row 4, column 3 of B2:E5: the West/Q3 cell
G2
fx
=INDEX(B2:E5,MATCH("West",A2:A5,0),MATCH("Q3",B1:E1,0))
ABCDEFGH
1RegionQ1Q2Q3Q4West Q3 revenue
2North$71,800$68,400$74,200$80,100$92,400
3South$58,200$61,500$64,800$67,300
4East$45,600$48,900$52,300$55,800
5West$82,100$87,500$92,400$96,200
6
7
8
Formula entered in cell G2. The formula reads two MATCH calls and intersects them inside INDEX.
The first MATCH locates the West row (position 4). The second MATCH locates the Q3 column (position 3). INDEX intersects them and returns $92,400.
Two-way INDEX MATCH replaces an entire layer of pivot tables for simple cross-tab lookups. The headers can be any value and the formula keeps working as you reorder columns or rows.

INDEX MATCH vs VLOOKUP

Both functions solve the same problem: find a value in a table and return something based on it. INDEX MATCH wins on flexibility, VLOOKUP wins on readability. Here's the honest comparison.

CapabilityVLOOKUPINDEX MATCH
Look rightYesYes
Look leftNoYes
Two-way (row + column)NoYes
Survives column insertsNo (col_index_num breaks)Yes
Performance on huge sheetsSlowerFaster
ReadabilitySimplerTwo functions to read
Modern alternativeXLOOKUPXLOOKUP
In Excel 365 and Excel 2021+, XLOOKUP is the modern replacement for both. But INDEX MATCH still works in every version of Excel ever shipped, which matters when sharing files with clients on older versions.

Where people go wrong

  1. Forgetting the 0 in MATCH

    Leaving off the third argument (or passing 1) makes MATCH do approximate matching, which silently returns wrong positions on unsorted data. The formula returns a value but it's the value at a different row.

    Fix: Always pass 0 as MATCH's third argument unless you have a specific reason to use approximate matching.
  2. Mismatched array sizes between INDEX and MATCH

    If MATCH searches B2:B100 (99 rows) and INDEX returns from A2:A50 (49 rows), Excel returns wrong values for any match in rows 51-100, or #REF! errors.

    Fix: Make sure the rows in INDEX's array line up with the rows in MATCH's lookup_array. Use the same row range for both.
  3. Missing $ signs when copying down

    Drag a working INDEX MATCH formula down ten rows and the lookup arrays slide along with it. Result: formulas in lower rows search shifted ranges and return nonsense.

    Fix: Lock the array references with $ signs: =INDEX($A$2:$A$11,MATCH(B2,$B$2:$B$11,0)). The lookup value (B2) stays relative so each row searches for its own value.
  4. Using the wrong INDEX overload for two-way lookups

    INDEX has two forms. The single-array form takes one position. The full form takes both row_num and col_num. If you forget the col_num for a two-way lookup, INDEX returns the entire row instead of one cell.

    Fix: For two-way lookups, always pass both INDEX(array, MATCH(...), MATCH(...)). The third argument is what makes it cross-tab.

Notes

  • INDEX is one of the few Excel functions that returns a reference rather than just a value, which means you can use it inside dynamic ranges
  • MATCH returns a 1-based position. Position 1 is the first item of the lookup_array, not the first row of the worksheet
  • match_type 0 is exact match. 1 is approximate (data must be sorted ascending). -1 is approximate the other way (data must be sorted descending)
  • INDEX MATCH is consistently faster than VLOOKUP on large sheets because Excel only evaluates the columns you reference, not the whole table
  • Both functions are case-insensitive when matching text: "Apple" equals "APPLE"
  • Wildcards (* and ?) work in MATCH when match_type is 0
  • When MATCH can't find the value it returns #N/A, which then propagates through INDEX. Wrap the whole thing in IFERROR to handle this gracefully
  • XLOOKUP combines INDEX and MATCH into one function in Excel 365 and 2021+. Same power, simpler syntax.

Now prove it

Reading about INDEX MATCH is one thing.

Writing one fluently when your manager hands you a pricing model with no left column to anchor on is a different skill entirely.

These exercises put you in real workplace tables where INDEX MATCH is the only clean option.

Here's the thing about INDEX MATCH.

You can read this page twice and still freeze when your manager pastes a 12-column pricing model in front of you, asks for a left-direction lookup, and says she needs the answer before her 3pm.

That gap, between knowing what INDEX MATCH does and being able to write one fluently under pressure, is exactly what CellSkill is built to close.

Not with more reading.

With practice on tables that look like your actual job.

Start practicing INDEX MATCH for free →
Free account · No credit card · Cancel anytime
Browse exercises
INDEX MATCH in Excel: The VLOOKUP Killer Combo · CellSkill