How HLOOKUP works
HLOOKUP is VLOOKUP rotated 90 degrees. It searches the first ROW of a table from left to right, finds a match, then moves DOWN to return a value from whichever row you specify.
It's designed for data that flows horizontally: quarterly reports with periods (Q1, Q2, Q3, Q4) across the top, monthly dashboards, or grade scales running left to right. Whenever the category labels are arranged in a row instead of a column, HLOOKUP is the function to reach for.
The catch, same as VLOOKUP, is direction. HLOOKUP can only look DOWN from the first row. The lookup value must always live in the first row of your selected range. If the data is shaped differently you'll need INDEX MATCH or XLOOKUP.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
| lookup_value | any | ✓ Required | The value you want to find. Usually a cell reference like B1. Can be text, a number, or a cell reference. |
| table_array | range | ✓ Required | The range containing your data. HLOOKUP searches the first row of this range. Lock it with $ signs if you plan to copy the formula across. |
| row_index_num | number | ✓ Required | Which row to return, counted from the top of your table_array. Row 1 is the first row (the one being searched), row 2 is the next, and so on. |
| range_lookup | boolean | ✗ Optional | FALSE for exact match (almost always what you want). TRUE for approximate match. Only use this for sorted tables like grade scales or tax brackets where columns are sorted ascending. |
HLOOKUP basic: pull quarterly revenue by period
You're an FP&A analyst with a quarterly P&L laid out horizontally: Q1 through Q4 across the top, metrics stacked down the side. The CFO asks for Q3 revenue. HLOOKUP finds it in one formula.
=HLOOKUP(G2,$B$1:$E$5,2,FALSE)- •
G2→ the period you're looking up (e.g. "Q3") - •
$B$1:$E$5→ the quarterly P&L table (locked with $) - •
2→ return row 2 (the Revenue row) - •
FALSE→ exact match only
| A | B | C | D | E | F | G | H | I | |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Metric | Q1 | Q2 | Q3 | Q4 | Period | Revenue | ||
| 2 | Revenue | $4.2M | $4.8M | $5.6M | $6.1M | Q3 | $5.6M | ||
| 3 | Costs | $2.1M | $2.3M | $2.7M | $2.9M | Q1 | $4.2M | ↓ drag down | |
| 4 | Profit | $2.1M | $2.5M | $2.9M | $3.2M | Q4 | $6.1M | ||
| 5 | Margin | 50% | 52% | 52% | 52% | ||||
| 6 | Headcount | 84 | 89 | 94 | 101 | ||||
| 7 | |||||||||
| 8 | |||||||||
| 9 |
HLOOKUP with IFERROR: handle missing periods gracefully
Your dashboard pulls revenue by period. But what happens when someone types "Sep" or "Q1" and your dataset only has Jan through Apr? Without IFERROR, your report fills with #N/A. Wrap every HLOOKUP in IFERROR.
=IFERROR(HLOOKUP(G2,$B$1:$E$5,2,FALSE),"Not found")- •
G2→ the period being looked up (e.g. "Mar") - •
$B$1:$E$5→ the dashboard data: periods in row 1, metrics in rows 2-5 - •
If the period is found→ returns the Revenue (row 2) - •
If the period is missing→ returns "Not found" instead of #N/A
| A | B | C | D | E | F | G | H | I | |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Metric | Jan | Feb | Mar | Apr | Period | Revenue | ||
| 2 | Revenue | $4.2M | $4.5M | $4.8M | $5.1M | Mar | $4.8M | ||
| 3 | Costs | $2.1M | $2.3M | $2.4M | $2.5M | Sep | Not found | ↓ drag down | |
| 4 | Profit | $2.1M | $2.2M | $2.4M | $2.6M | Feb | $4.5M | ||
| 5 | Margin | 50% | 49% | 50% | 51% | Q1 | Not found | ||
| 6 | Headcount | 84 | 89 | 94 | 101 | ||||
| 7 | |||||||||
| 8 | |||||||||
| 9 |
HLOOKUP across sheets: pulling data from the master dashboard
Your monthly summary lives on Sheet1. The master dashboard with all metrics across the period axis lives on Sheet2. Pulling the right cell across tabs is HLOOKUP plus the Sheet2! prefix.
=HLOOKUP(A2,Sheet2!$B$1:$G$3,2,FALSE)- •
A2→ the period on Sheet1 (e.g. "Mar") - •
Sheet2!$B$1:$G$3→ the master dashboard on Sheet2 (the prefix points to the other tab) - •
2→ return row 2 of Sheet2 (the Revenue row) - •
FALSE→ exact match: period names must match exactly
| A | B | C | |
|---|---|---|---|
| 1 | Period | Revenue | |
| 2 | Mar | $4.8M | |
| 3 | Apr | $5.1M | ↓ drag down |
| 4 | May | $5.4M | |
| 5 | Jun | $5.6M | |
| 6 | |||
| 7 | |||
| 8 |
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 1 | Metric | Jan | Feb | Mar | Apr | May | Jun |
| 2 | Revenue | $4.2M | $4.5M | $4.8M | $5.1M | $5.4M | $5.6M |
| 3 | Costs | $2.1M | $2.3M | $2.4M | $2.5M | $2.6M | $2.7M |
| 4 | Profit | $2.1M | $2.2M | $2.4M | $2.6M | $2.8M | $2.9M |
| 5 | Headcount | 84 | 89 | 94 | 97 | 99 | 101 |
Sheet1 B2 looks up "Mar" on Sheet2's header row and pulls back $4.8M from row 2 (Revenue). The Sheet2! prefix tells HLOOKUP exactly which tab to search. The rest of the formula works identically to a same-sheet lookup.
HLOOKUP with TRUE: assigning letter grades from scores
Grade scales. Tax brackets. Tier tables laid out left to right. These are the cases where HLOOKUP with TRUE earns its keep, when you want to find which RANGE a value falls into, not an exact match.
Critical requirement: your lookup row must be sorted in ascending order. If it is not, HLOOKUP returns garbage with no error message.
=HLOOKUP(H2,$B$1:$F$2,2,TRUE)- •
H2→ the student's raw score - •
$B$1:$F$2→ the grade scale (locked with $ since the same scale applies to every student) - •
2→ return row 2 of the grade scale (the letter grade) - •
TRUE→ approximate match: pick the highest threshold ≤ the score
| A | B | C | D | E | F | G | H | I | J | |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Threshold | 0 | 60 | 70 | 80 | 90 | Score | Grade | ||
| 2 | Grade | F | D | C | B | A | 87 | B | ||
| 3 | 72 | C | ||||||||
| 4 | 95 | A | ||||||||
| 5 | 58 | F | ||||||||
| 6 | ||||||||||
| 7 | ||||||||||
| 8 |
The $ sign mistake: dragging an HLOOKUP across columns
HLOOKUP's drag-direction problem is the mirror image of VLOOKUP's. When you drag an HLOOKUP formula to the RIGHT across columns, every column reference in the table_array shifts right by one column. If you didn't lock the table with $ signs, your lookup range slides off the data.
=HLOOKUP(B$1,$A$1:$G$8,2,FALSE)- •
B$1→ the month header above each column ($1 locks the row, but the column letter shifts as you drag right) - •
$A$1:$G$8→ the full dashboard (header + 7 metric rows × 6 months), fully anchored so it stays put no matter where the formula is dragged - •
2→ return row 2 (Revenue) - •
FALSE→ exact match
| A | B | C | D | E | F | G | H | I | J | K | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Metric | Jan | Feb | Mar | Apr | May | Jun | ||||
| 2 | Revenue | $4.2M | $4.5M | $4.8M | $5.1M | $5.4M | $5.6M | ||||
| 3 | Costs | $2.1M | $2.3M | $2.4M | $2.5M | $2.6M | $2.7M | ||||
| 4 | Profit | $2.1M | $2.2M | $2.4M | $2.6M | $2.8M | $2.9M | ||||
| 5 | Tax | $420K | $440K | $480K | $520K | $560K | $580K | ||||
| 6 | Margin % | 50% | 49% | 50% | 51% | 52% | 52% | ||||
| 7 | Cash | $8.4M | $8.7M | $9.1M | $9.6M | $10.3M | $11.7M | ||||
| 8 | Headcount | 84 | 86 | 89 | 92 | 97 | 101 | ||||
| 9 | |||||||||||
| 10 | Pulled → | $4.2M | $4.5M | $4.8M | $5.1M | $5.4M | $5.6M | ||||
| 11 | |||||||||||
| 12 |
Where people go wrong
- Using TRUE instead of FALSE
You leave the fourth argument blank or type TRUE. Excel quietly returns approximate-match results that look almost right but reference the wrong period. There's no error, no warning, just bad numbers in your report.
Fix: Always explicitly type FALSE as the fourth argument unless you specifically need approximate matching (grade scales, tax brackets) and your lookup row is sorted ascending. - Forgetting $ signs when copying right
You write a perfect HLOOKUP in cell B7 and drag it right to fill C7, D7, E7. By the last cell the range has shifted off the data and your cells fill with #N/A or wrong numbers. The table_array shifted right with each drag.
Fix: Lock your table_array with $ signs: =HLOOKUP(B$1,$A$1:$E$5,2,FALSE). The $ before each column letter and row number makes the lookup table absolute. - Row index out of range
You specify row_index_num as 5 but your table_array only has 4 rows. Excel returns #REF! and you wonder why a formula that looks correct is failing.
Fix: Count the rows in your table_array carefully. If table_array is A1:E4 that is 4 rows, so row_index_num cannot exceed 4. - Lookup value not in first row
Your headers are in row 2 and totals are in row 1 (a sub-header above the labels). HLOOKUP can only search the FIRST row of your selected range. It doesn't matter what's logically the header, only what comes first geographically.
Fix: Adjust your table_array to start at the header row, e.g. A2:E5 instead of A1:E5. Or switch to XLOOKUP which lets you specify the lookup_array independently.
Notes
- HLOOKUP is case-insensitive. "Q1" and "q1" return the same result
- Wildcard characters (* and ?) work in lookup_value when range_lookup is FALSE
- For multiple matches HLOOKUP returns the first match only. It stops searching after the first hit (left to right)
- HLOOKUP is rarely used in modern spreadsheets. Most data is built vertically. Use it primarily on inherited reports or cross-tab summaries where the periods are already arranged across the top
- Row index counting starts at 1, not 0
- In Excel 365 and Excel 2021 and later use XLOOKUP instead. It works in any direction and has built-in error handling
- Approximate match (TRUE) requires the first row to be sorted ascending left-to-right. Unsorted data returns wrong results silently
Now prove it
Reading about HLOOKUP is one thing.
Using it on a real cross-tab report, with periods across the top and metrics stacked down the side, is what actually sticks.
These exercises put you in real workplace scenarios where HLOOKUP is the right tool.
Here is the thing about HLOOKUP.
You can read this page twice and still freeze when someone drops a quarterly cross-tab on your desk and asks for a specific cell, fast.
That gap, between knowing what HLOOKUP does and reaching for it confidently when it actually matters, is exactly what CellSkill is built to close.
Not with more reading.
With practice on scenarios that look like your actual job.
Start practicing HLOOKUP for free →