๐ Lesson 4.1: VLOOKUP & XLOOKUP
This is the lesson where casual users become power users. Up to now, every formula has worked inside one table. But real work is spread across several tables โ an orders list here, a product catalog there โ and the magic is teaching a cell to reach into another table, find the row that matches, and pull back exactly the value you need. That skill is called a lookup. In this lesson we meet the two you'll reach for most: VLOOKUP, the everyday workhorse you'll see in everyone else's sheets, and XLOOKUP, its cleaner modern replacement. (Next lesson adds INDEX/MATCH, the rock-solid classic, and a decision guide for choosing between all three.)
๐ What You'll Learn
By the end of this lesson, you will be able to:
- Explain the lookup problem โ matching a key in one table to data in another โ and why copy-paste doesn't scale
- Write a VLOOKUP with an exact match, lock its range with
$signs, and recognize its real-world limits - Rebuild the same lookup with XLOOKUP, the cleaner modern replacement that can even look left
- Handle a missing match gracefully with IFNA and IFERROR, and know which to reach for
โฑ๏ธ Estimated Time: 50 minutes
๐ฏ Project: Build a two-table lookup โ an orders table that pulls each product's name and price from a separate products table โ first with VLOOKUP, then rebuilt with XLOOKUP, with a friendly not-found fallback.
In This Lesson
The Lookup Problem
Picture a small shop. You keep two lists. One is your products table โ a tidy catalog with each product's ID, name, and price, one row per product. The other is your orders table โ a running log of what sold, one row per order line, with a quantity and the product ID that was bought. The orders table doesn't repeat the product's name or price; it just records the ID. That's good design: each fact lives in exactly one place.
But now you want the orders table to show the product name and price next to each line, so you can multiply price by quantity and get a line total. The information exists โ it's sitting in the products table โ but it's in a different table, matched only by that shared product ID. You need a way to say: "take the product ID on this order row, go find the row in the products table with the same ID, and bring back its price." That is the lookup problem, and it is one of the most common tasks in all of spreadsheeting.
๐ง Mindset
Think of a lookup like using a phone's contacts. You know the person's name (your key), you flip to the contact with that name (the match), and you read off their phone number (the return value). Every lookup function in this module does exactly that three-step dance โ key, match, return. The functions differ only in how they find the match and how flexibly they let you point at the answer.
Why not just copy-paste?
You could, of course, look up each price by hand and type it into the orders table. For five rows, fine. But copy-paste is static and fragile. When a price changes in the catalog, every pasted copy is now silently wrong. When you add 200 more orders, you're back to hand-copying. And a typo creeps in the moment you get bored. A lookup formula stays live: change a price in the products table once, and every order that references it updates automatically. That's the whole reason this scales and copy-paste doesn't.
๐ก The shared "key" is everything
A lookup only works when both tables share a common piece of information โ the key. Here it's the product ID. The key must be unique in the table you're searching (one row per product), or the lookup will just return the first match it finds and quietly ignore the rest. Clean, unique keys are the foundation every lookup rests on.
product ID P-002"] --> B["๐ Search the Products table
find the row with P-002"] B --> C["๐ฏ Matched row
Notebook ยท price 4"] C --> D["โฉ๏ธ Return the value
into your Orders table"]
VLOOKUP โ The Workhorse
VLOOKUP stands for "Vertical Lookup." It searches down the first column of a range for your key, and when it finds a match, it returns a value from a column to the right in that same row. It has been the go-to lookup for decades, and you will see it in countless real sheets, so it's worth knowing well even though we'll meet a cleaner tool later in this same lesson.
๐ Definition
The shape of the function is:
=VLOOKUP(search_key, range, index, is_sorted)
- search_key โ the value you're looking for (your key), e.g. the product ID
A2. - range โ the table to search. Its first column must contain the keys.
- index โ which column of that range to return, counted from the left starting at 1.
- is_sorted โ use
FALSEfor an exact match. This is the setting you want almost every time.
A full worked example
Say your products catalog lives in the range E2:G5 like this โ column E is the product ID,
F is the name, G is the price:
| E (ID) | F (Name) | G (Price) |
|---|---|---|
| P-001 | Pen | 2 |
| P-002 | Notebook | 4 |
| P-003 | Stapler | 7 |
| P-004 | Marker | 3 |
Over in your orders table, cell A2 holds the product ID P-002. To pull its
price into C2, you'd write:
=VLOOKUP(A2, $E$2:$G$5, 3, FALSE)
Read it aloud: "Take the ID in A2, search for it in the first column of E2 through G5, and when you find
it, return the value from column 3 of that range โ the price โ using an exact match." It returns
4, Notebook's price. To pull the name instead, you'd change the index to
2. Change P-002 to P-003 in A2 and the formula instantly returns 7. That's the
live behavior copy-paste can never give you.
โ Pro Tip โ lock the range with $ signs
Notice the $E$2:$G$5. Those dollar signs make the range an absolute
reference (which we met back in the formula-references lesson), so when you drag the formula
down all your order rows, the range stays pinned to the catalog instead of sliding down with each row.
Forgetting the $ signs is the single most common reason a dragged VLOOKUP suddenly returns
#N/A halfway down the column.
Where VLOOKUP falls short
VLOOKUP is reliable but showing its age. Three limits bite people constantly:
- It only looks to the right. The key column must be the leftmost column of the range, and you can only return something to its right. If the name sat to the left of the ID, VLOOKUP simply can't reach it.
- It breaks when columns move. That
3is a hard-coded column count. If someone inserts a new column into the middle of your catalog, column 3 now points at the wrong data and your prices go quietly wrong โ no error, just bad numbers. - It needs the absolute range refs to survive being dragged, which trips up beginners as we just saw.
โ ๏ธ Important Note: The most dangerous VLOOKUP failure is the silent one. Deleting or inserting a column shifts what "column 3" means, and the formula keeps returning a value โ just the wrong one. It won't show an error, so nobody notices until a total looks off. This fragility is exactly why the newer approaches โ XLOOKUP below, and INDEX/MATCH next lesson โ exist.
XLOOKUP โ The Modern Replacement
XLOOKUP is the modern function built to fix VLOOKUP's frustrations. Instead of a single range plus a column-number guess, you point at the column to search and the column to return separately. That one change removes most of VLOOKUP's fragility at a stroke.
๐ Definition
=XLOOKUP(search_key, lookup_range, result_range, [not_found], [match_mode])
- search_key โ the value you're looking for, same as before.
- lookup_range โ the single column to search in (e.g. the IDs,
E2:E5). - result_range โ the single column to return from (e.g. the prices,
G2:G5). - not_found โ optional: a value to return if there's no match, so you don't get a bare error.
- match_mode โ optional: exact by default, with options for approximate or wildcard matching.
The same lookup, rebuilt
The price lookup from before becomes:
=XLOOKUP(A2, $E$2:$E$5, $G$2:$G$5, "Not found")
Read it: "Find A2 in the IDs column, and return the matching value from the prices column; if there's no match, say Not found." Notice what's better here:
- No column counting. You point straight at the prices column, so inserting columns elsewhere doesn't break anything.
- It defaults to exact match. No
FALSEto remember โ the safe behavior is the default. - Built-in not-found handling. That fourth argument replaces wrapping the whole thing in an error-catcher for the common case.
- It can look left. Because search and result columns are independent, the result column can sit anywhere โ to the left of the key, to the right, wherever.
โ Pro Tip โ looking left, the thing VLOOKUP can't do
Suppose you know a product's price and want its ID, but the ID column sits to the
left of price. VLOOKUP is stuck. XLOOKUP just swaps its arguments:
=XLOOKUP(4, $G$2:$G$5, $E$2:$E$5) searches the price column and returns from the ID
column to its left. This freedom is why many people never write a VLOOKUP again once XLOOKUP is
available to them.
โ ๏ธ Watch Out โ availability varies
XLOOKUP is relatively recent in Google Sheets and rolled out over time. On most current personal
Google accounts it's there, but if a formula returns a name error like #NAME?, your
account or version may not have it yet, or it's spelled differently. Don't panic โ the concept
is what matters, and INDEX/MATCH (next lesson) does the same job everywhere. When in doubt, check
Google's current function
list for what's available to you.
Handling Not-Found Gracefully
What happens when a lookup finds nothing? By default, both VLOOKUP and XLOOKUP (and the INDEX/MATCH combo
you'll meet next lesson) return the #N/A error, which means "no available value โ I couldn't
find a match." That's honest, but a dashboard full of red #N/A cells looks broken and can
break totals downstream. So we wrap the lookup to return something friendlier. (XLOOKUP has this built in
via its not_found argument; VLOOKUP needs a wrapper.)
IFNA โ the precise catch
IFNA catches only the #N/A error and lets you supply a
replacement:
=IFNA(VLOOKUP(A2, $E$2:$G$5, 3, FALSE), "No match")
If the lookup works, you get the price. If the key isn't found, you get No match instead of
#N/A. Crucially, IFNA leaves other errors alone โ if you had a genuine mistake like a
broken reference, IFNA won't hide it, which is exactly what you want.
IFERROR โ the broad catch
IFERROR catches every kind of error โ #N/A, but also
#REF!, #VALUE!, #DIV/0!, and the rest:
=IFERROR(VLOOKUP(A2, $E$2:$G$5, 3, FALSE), "No match")
โ ๏ธ Watch Out โ IFERROR can hide real bugs
Because IFERROR swallows all errors, it can mask a genuine problem. If you accidentally typed
a wrong column index and got a #REF!, IFERROR would quietly show "No match" and you'd never
know your formula was broken. For lookups, prefer IFNA โ it catches only the "not
found" case you actually expect, and leaves real bugs visible so you can fix them. Reach for IFERROR only
when you truly want to suppress any and all errors.
โ ๏ธ Important Note: Hiding an error is sometimes the wrong choice entirely. If a
missing match means a data problem โ an order referencing a product that doesn't exist in your catalog โ
you may want to see #N/A so you catch the bad data. Cleaning up display is good;
papering over real problems is not. Ask yourself: "Is a not-found result expected and harmless, or is it
a signal something's wrong?"
๐ฏ Project: A Two-Table Lookup
Time to make it real in your own sheet. You'll build two small tables and teach the orders table to pull product names and prices out of the products table โ first with VLOOKUP, then rebuilt with XLOOKUP โ and finish by handling a missing match cleanly. (Next lesson you'll rebuild this same lookup a third way with INDEX/MATCH, so keep the sheet.)
๐๏ธ Build an orders-and-products lookup
Objective: Create a live lookup so that each order line automatically shows the right product name and price, and a line total, drawn from a separate products catalog.
Instructions (about 25 minutes):
- (5 min) In a fresh sheet, build a Products table in columns EโG. Row 1 headers:
ID,Name,Price. Then four products in E2:G5 โ for example P-001 / Pen / 2, P-002 / Notebook / 4, P-003 / Stapler / 7, P-004 / Marker / 3. - (4 min) Build an Orders table in columns AโD. Row 1 headers:
Product ID,Name,Price,Qty. In A2:A4 type three product IDs (mix them up, e.g. P-002, P-004, P-001), and put a quantity in D2:D4. - (4 min) In
B2write a VLOOKUP to pull the name, and inC2a VLOOKUP to pull the price. Remember to lock the range with$signs, then drag both down to row 4. - (3 min) Add a line-total column: pick an empty column and multiply price by quantity, e.g.
=C2*D2. Change a price in the catalog and watch the totals update live. - (5 min) Rebuild the
C2price lookup with XLOOKUP instead, pointing at the ID column and the price column separately, with a not-found fallback. Confirm it returns the same numbers. - (4 min) Type a product ID that doesn't exist (like P-999) into A5 and wrap the VLOOKUP version in IFNA to show "No match" instead of
#N/A. Notice XLOOKUP already handles this with its fourth argument.
๐ก Hint โ starter formulas
Products table (E1:G5)
E1: ID F1: Name G1: Price
E2: P-001 F2: Pen G2: 2
E3: P-002 F3: Notebook G3: 4
E4: P-003 F4: Stapler G4: 7
E5: P-004 F5: Marker G5: 3
Orders table (A1:D4)
A1: Product ID B1: Name C1: Price D1: Qty
VLOOKUP the name and price:
B2: =VLOOKUP(A2, $E$2:$G$5, 2, FALSE)
C2: =VLOOKUP(A2, $E$2:$G$5, 3, FALSE)
Line total in a spare column:
=C2*D2
XLOOKUP the price instead:
=XLOOKUP(A2, $E$2:$E$5, $G$2:$G$5, "Not found")
Graceful not-found (VLOOKUP version):
=IFNA(VLOOKUP(A2, $E$2:$G$5, 3, FALSE), "No match")
If a dragged formula suddenly shows #N/A lower down, check that the range has
$ signs โ that's the classic cause.
โ Project Completion Checklist
- Two tables exist: a Products catalog and an Orders log sharing a product ID key
- VLOOKUP pulls both the name and the price into the orders table, dragged down all rows
- A line-total column multiplies price by quantity and updates when a catalog price changes
- You rebuilt the price lookup with XLOOKUP and confirmed matching results
- An unknown ID shows a friendly "No match" via IFNA (and XLOOKUP's built-in fallback)
๐ฏ Quick Quiz
Question 1: Someone inserts a new column into the middle of your products catalog and your VLOOKUP prices are suddenly wrong โ but there's no error. Why?
Question 2: You want a lookup to show "No match" only when the key genuinely isn't found, but still reveal any real formula bug. Which wrapper should you use?
Best Practices for VLOOKUP & XLOOKUP
โ Do's
- Always lock the lookup range with
$signs so it survives being dragged down a column. - Prefer XLOOKUP when it's available โ it doesn't break when columns move, defaults to exact match, and can look left.
- Keep your keys unique and clean. Trailing spaces and numbers stored as text cause mysterious "not found" results. (Capitalization doesn't matter โ these lookups ignore case.)
- Wrap with IFNA (or use XLOOKUP's not-found argument) to keep dashboards tidy while still surfacing real errors.
โ Don'ts
- Don't copy-paste values you could look up. Pasted numbers go stale silently; formulas stay live.
- Don't reach for IFERROR by reflex. It hides genuine bugs. Use the narrower IFNA for lookups.
- Don't trust a VLOOKUP index after editing columns. Re-check it, or switch to a range-based lookup.
- Don't forget FALSE in VLOOKUP. Omitting it enables approximate matching, which can return wrong-but-plausible values.
๐ก Pro Tips
- If a lookup mysteriously fails, check the data types: a key stored as text ("007") won't match a number (7) even though they look identical.
- When you'll reuse the same catalog across many formulas, give its range a named range (Data menu) so
Productsreads clearer than$E$2:$G$5.
๐ Learning Journal
Keep a learning journal as you work through this course โ a document, a note, or even a tab in your own spreadsheet. After each lesson, take a few minutes to write down:
- Key concepts you learned
- Techniques that clicked for you
- Questions or confusion points to revisit
- Ideas you want to try in your own sheets
- Your progress and feelings about learning this โ including where your confidence grew
โ๏ธ This lesson's prompt: Think of two lists in your own life or work that share a common key โ a contacts list and an invoices list, a menu and an order log, a members roster and an attendance sheet. Which value would you want to pull from one into the other, and would VLOOKUP reach it, or would you need XLOOKUP's freedom to look left? Note anything about lookups that still feels fuzzy.
๐ Lesson Summary
๐ Key Takeaways
- A lookup matches a key from one table to a row in another and returns a value โ the live, scalable alternative to copy-paste.
- VLOOKUP searches the first column and returns a column to its right by number; use
FALSEfor exact match, but beware it breaks silently when columns move and only looks right. - XLOOKUP points at the search column and result column separately โ cleaner, can look left, defaults to exact match, and has built-in not-found handling (availability varies by account).
- Wrap lookups with IFNA to catch only the not-found case; use IFERROR sparingly, and never hide an error that signals real bad data.
๐ What You've Accomplished
You built a genuine two-table lookup two different ways, watched prices flow live from a catalog into an orders log, and learned to handle the missing-match case cleanly. This is the exact skill that turns a pile of separate lists into a connected, self-updating system โ the heart of what makes spreadsheets powerful at work.
โ Common Questions at This Stage
Should I just always use XLOOKUP and forget VLOOKUP?
If XLOOKUP is available in your account, it's a great default. But you'll constantly read other people's sheets full of VLOOKUP, so you must recognize it. And where XLOOKUP isn't present, INDEX/MATCH (next lesson) works everywhere. Knowing all three makes you fluent, not just functional.
My lookup returns #N/A even though I can see the value in the other table. Why?
Almost always a subtle key mismatch: a trailing space, a stray character, or a number stored as
text versus a real number. (Capitalization isn't the culprit โ VLOOKUP and XLOOKUP ignore case.) Click both cells and compare exactly. The TRIM function and
checking data types (Format menu) usually solve it.
What's the difference between VLOOKUP and HLOOKUP?
VLOOKUP searches vertically down a column (the common case). HLOOKUP searches horizontally across a row, for the rarer layout where your keys run along the top. XLOOKUP can do both directions, which is one more reason it's handy.
๐ญ Looking Ahead
In the next lesson โ Lesson 4.2: INDEX/MATCH & Choosing Your Lookup โ we meet the rock-solid classic that power users reached for long before XLOOKUP existed. You'll learn how MATCH and INDEX combine, why the combo survives column changes, how to do a two-way lookup (matching a row and a column at once), and you'll get a clear decision guide for choosing among all three lookups.
โ Before the Next Lesson
- Make sure your two-table lookup works and updates live when you change a catalog price
- Try switching your VLOOKUP to XLOOKUP from memory, without the hint
- Write your Learning Journal entry for this lesson
๐ Additional Resources
- Google Sheets function list (Google Support)
- Google Sheets Help Center (Google Support)
- sheets.google.com โ open the app and try it
๐ Encouragement for the Journey
You just crossed a real threshold. Lookups are the skill people list on rรฉsumรฉs and the moment spreadsheets stop feeling like grids and start feeling like databases you command. If any of it felt like a stretch, that's exactly right โ this is power-user territory, and you're standing in it now. Next, we add the most flexible lookup of all and a guide for choosing between them. ๐