Stop Using VLOOKUP — Here’s How INDEX MATCH Really Works

The first thing most people do when they need to pull a value from a table is type =VLOOKUP( — then hit Enter before checking if the column is sorted or if the lookup column is actually the leftmost one. That’s why their reports break silently every quarter. VLOOKUP isn’t wrong — it’s just brittle. INDEX MATCH isn’t magic. It’s arithmetic with intention.

The Setup

We’re working with a sales team roster at TerraNova Logistics. HR maintains this list weekly in Sheet1, columns A through D:

A (ID) B (Name) C (Department) D (Base Salary)
101 Sarah Chen Operations $72,500
102 Diego Mora Finance $84,100
103 Priya Kapoor Sales $69,800
104 Marcus Bell IT $91,200
105 Anya Petrova HR $65,400
106 Jamal Wright Sales $78,900
107 Lena Torres Finance $86,300
108 Rajiv Singh Operations $70,100

The Challenge

Marketing needs a quick report: given a list of employee IDs (say, in F2:F6 on Sheet2), return each person’s department and base salary. Simple — except the ID column is not the leftmost column in any other sheet, and departments are stored in column C, salaries in column D. VLOOKUP would fail here unless we restructure the source table — which we can’t, because HR owns that file and won’t move columns.

What makes this elegant is that INDEX MATCH doesn’t care about column order. It treats your table like coordinates: “Go to row X, column Y.” You decide both X and Y — no assumptions, no hidden sorting requirements.

Walking Through It

Let’s build it step by step in Sheet2. Assume F2 contains ID 103.

Step 1: Find the row number
Use MATCH to locate where 103 appears in Sheet1!A2:A9:
=MATCH(F2,Sheet1!A2:A9,0)
This returns 3 — because 103 is the third item in that range (A4). Note: the 0 forces exact match. Without it, you’ll get wrong results if IDs aren’t sorted.

Step 2: Pull Department (column C)
Now wrap that in INDEX:
=INDEX(Sheet1!C2:C9,MATCH(F2,Sheet1!A2:A9,0))
That says: “From C2:C9, grab the 3rd item” → Sales. Works. But typing that twice (once for Department, once for Salary) is messy.

Step 3: Lock the lookup range & use Ctrl+Enter
Select G2:H2, type:
=INDEX(Sheet1!C2:D9,MATCH($F2,Sheet1!A2:A9,0),COLUMN(A1))
Then press Ctrl+Enter. The COLUMN(A1) returns 1 for column G (Department), 2 for column H (Salary). Drag down to G6:H6. Done.

Before:

F (ID) G (Dept) H (Salary)
103 blank blank
107 blank blank

After:

F (ID) G (Dept) H (Salary)
103 Sales $69,800
107 Finance $86,300

The Result

Here’s the full output for all five IDs requested:

F (ID) G (Department) H (Base Salary)
103 Sales $69,800
107 Finance $86,300
101 Operations $72,500
104 IT $91,200
105 HR $65,400

What Could Go Wrong

These three mistakes appear in >80% of broken INDEX MATCH formulas I audit — not syntax errors, but logic traps.

  • Mistake 1: Mismatched range sizes
    You write =INDEX(A2:A10,MATCH(...)) but your MATCH searches B2:B12. Even if both ranges contain the same values, the row numbers won’t align. Excel won’t warn you — it’ll just return the wrong cell. Always verify COUNTA on both ranges first.
  • Mistake 2: Forgetting absolute vs relative references when dragging
    If you type =INDEX(C2:C9,MATCH(F2,A2:A9,0)) and drag down, A2:A9 becomes A3:A10 — shifting your lookup window. Fix: Use $A$2:$A$9 and $C$2:$C$9.
  • Mistake 3: Using approximate match (1 or -1) on unsorted data
    This is the sneakiest. If you omit the third argument in MATCH, Excel defaults to 1 — meaning “find largest value ≤ lookup”. With names or IDs? It returns nonsense — often the last row. Always specify 0 for exact match unless you’re doing tiered pricing lookups on sorted numeric tables.

Next step: Open your current workbook. Find one VLOOKUP formula. Replace it using this pattern:
=INDEX(return_range,MATCH(lookup_value,lookup_column,0),[column_num])
Then test it with an ID that doesn’t exist — you should see #N/A, not a silent wrong answer. That’s the sound of reliability kicking in.

Michael Lee

Michael Lee

Michael covers the latest in office software updates