VLOOKUP vs XLOOKUP in Excel

VLOOKUP vs XLOOKUP in Excel: When Each Works, When Both Fail, and Why INDEX/MATCH Still Matters

VLOOKUP
All Excel versions — right-only, breaks on column insertion
XLOOKUP
Microsoft 365 / 2021 — any direction, fallback value, match modes
INDEX/MATCH
All Excel versions — two-way, immune to column insertion
#N/A
All three return this when the lookup value is not found — handle it with IFERROR or IFNA

VLOOKUP vs XLOOKUP is not a simple upgrade question — each has specific failure modes, version constraints, and edge cases that determine which is correct for a given workbook. INDEX/MATCH remains relevant in 2026 despite XLOOKUP’s advantages because it handles scenarios neither VLOOKUP nor XLOOKUP manage cleanly. This article maps every failure mode, limitation, and use case for all three functions, with real scenarios from healthcare IT, revenue cycle, and QA analyst workbooks.

VLOOKUP: Syntax, How It Works, and Its Three Failure Modes

VLOOKUP searches for a value in the first column of a range and returns a value from a specified column to the right. Its four arguments are lookup value, table array, column index number, and range lookup (exact or approximate match).

=VLOOKUP(lookup_value, table_array, col_index_num, [range_lookup])— Example: look up ICD-10 code description from a reference table
=VLOOKUP(A2, CodeTable, 2, FALSE)

The fourth argument, range_lookup, is one of the most misunderstood parameters in Excel. FALSE means exact match — the lookup value must appear exactly in the first column. TRUE or omitting the argument means approximate match — VLOOKUP finds the largest value less than or equal to the lookup value, but the first column must be sorted ascending for this to work correctly. Most analyst lookups should use FALSE. Omitting the argument defaults to TRUE, which produces wrong results on unsorted data without any error.

VLOOKUP Failure Mode 1: It Cannot Look Left

VLOOKUP always searches in the first column of the table array and returns from a column to the right. If the value you want to return sits to the left of the lookup column, VLOOKUP cannot retrieve it without rearranging the table or adding helper columns. This is a structural constraint, not a formula error.

In practice: a denial code reference table has Code in column C and Description in column B. VLOOKUP cannot look up the Code in column C and return the Description from column B. You must either restructure the table (put Code first), add a helper column, or use INDEX/MATCH or XLOOKUP instead.

VLOOKUP Failure Mode 2: Column Insertion Breaks the Index Number

The column index number in VLOOKUP is a hardcoded integer — 2 for the second column, 3 for the third, and so on. When anyone inserts a column inside the table array, all column index numbers shift. A VLOOKUP with col_index_num=3 that used to return Description now returns whatever is in the new third column — without any error, without any warning.

This is the silent wrong number failure — the most dangerous failure mode in any lookup function. The formula continues to run, returns a value that looks plausible, and no one notices until a stakeholder spots an implausible result in a report. Workbooks shared with teams who may add columns are particularly vulnerable.

VLOOKUP Failure Mode 3: Duplicate Lookup Values Return Only the First Match

VLOOKUP stops at the first match. If the lookup column contains duplicate values, VLOOKUP returns the result for the first occurrence and ignores all subsequent ones. In a claim export where a patient has multiple encounters on the same date, a VLOOKUP on patient ID may return only the first encounter’s data — silently missing the others.

This is not a bug — it is documented behaviour. The fix for multiple matches is not a lookup function at all. Use FILTER (Microsoft 365) to return all matching rows, or SUMIFS/COUNTIFS for aggregating across duplicates.

XLOOKUP: What It Fixes and What It Does Not

XLOOKUP (available in Microsoft 365 and Excel 2021) replaces VLOOKUP’s table array and column index with separate lookup array and return array arguments. This separation eliminates two of VLOOKUP’s three failure modes immediately.

=XLOOKUP(lookup_value, lookup_array, return_array, [if_not_found], [match_mode], [search_mode])— Example: look up ICD-10 code description, return “Unknown” if not found
=XLOOKUP(A2, CodeTable[Code], CodeTable[Description], “Unknown code”)

— Example: look LEFT — return Description column when Code is to its right
=XLOOKUP(A2, CodeTable[Code], CodeTable[ShortName], “Not found”)

What XLOOKUP Fixes Over VLOOKUP

XLOOKUP’s lookup array and return array are specified separately. The return array can be to the left, right, above, or below the lookup array — direction is irrelevant. Insert a column between them and the formula still references its arrays by address, not by a hardcoded position number. XLOOKUP also has a built-in if_not_found argument — you specify the fallback value directly in the formula without wrapping in IFERROR.

XLOOKUP’s match_mode and search_mode Arguments

XLOOKUP has two optional arguments that VLOOKUP lacks. match_mode controls how the match is performed: 0 = exact match (default), -1 = exact or next smaller, 1 = exact or next larger, 2 = wildcard match. search_mode controls search direction: 1 = first-to-last (default), -1 = last-to-first (useful for returning the most recent match), 2 = binary search ascending, -2 = binary search descending.

The last-to-first search mode is particularly useful in healthcare IT. If a patient has multiple entries in a registration table, search_mode=-1 returns the most recent entry without sorting the table. This is a capability neither VLOOKUP nor INDEX/MATCH provides without additional complexity.

What XLOOKUP Does Not Fix

XLOOKUP still returns only the first match in forward search mode, same as VLOOKUP. It is also version-restricted: Microsoft 365 and Excel 2021 only. Any workbook using XLOOKUP that is opened in Excel 2019 or earlier will show a #NAME? error where the formula appears. If your workbook is shared with colleagues on older Excel versions, XLOOKUP is not safe to use as the primary lookup function.

XLOOKUP also does not handle two-condition lookups natively — you cannot look up a combination of two columns as a single key without a helper column or an array formula approach. INDEX/MATCH handles this more cleanly.

INDEX/MATCH: Why It Still Wins in Specific Situations

INDEX/MATCH is two functions combined. INDEX returns a value from a range based on row and column numbers. MATCH returns the position of a value within a range. Together, they replicate VLOOKUP but without its directional constraint, without a hardcoded column number, and without the column insertion failure mode — and they work in every Excel version.

— INDEX/MATCH equivalent of the VLOOKUP example above
=INDEX(CodeTable[Description], MATCH(A2, CodeTable[Code], 0))— Two-condition lookup: match on both Payer AND ServiceType
=INDEX(RateTable[Rate],
MATCH(1, (RateTable[Payer]=A2)*(RateTable[ServiceType]=B2), 0))

Why INDEX/MATCH Is Immune to Column Insertion

INDEX references the return range directly: CodeTable[Description]. MATCH references the lookup column directly: CodeTable[Code]. Insert a new column between Description and Code — both references still track to their named columns. The formula does not break. This is the core reason INDEX/MATCH remains the lookup function of choice in shared workbooks where column structure may change.

Two-Condition Lookups: The INDEX/MATCH Advantage

The two-condition INDEX/MATCH pattern uses multiplication of two boolean arrays inside MATCH. Each condition returns an array of TRUE/FALSE values (1/0). Multiplying them produces 1 only where both conditions are TRUE in the same row. MATCH then finds the first 1 in that product array and returns its row position.

— Rate lookup: find the rate where Payer=BCBS AND ServiceType=Inpatient
=INDEX(RateTable[Rate],
MATCH(1,
(RateTable[Payer]=”BCBS”)*(RateTable[ServiceType]=”Inpatient”),
0))

In Excel 2019 and earlier, this formula requires Ctrl+Shift+Enter to enter as an array formula (CSE). In Microsoft 365, it evaluates as a regular formula because dynamic arrays are available. XLOOKUP can replicate this with a helper column or a concatenated lookup value, but the native INDEX/MATCH array approach is more maintainable when the lookup has two or more conditions and no helper column is acceptable.

Two-Dimensional Lookup: INDEX with Two MATCH Functions

INDEX can return a value from a matrix using both a row position and a column position. Two MATCH functions supply both positions. This is the two-dimensional lookup that neither VLOOKUP nor XLOOKUP handles natively.

— Find the value at the intersection of a row label and column label
— Row: payer name in A2, Column: service type in B2
=INDEX(RateMatrix,
MATCH(A2, RateMatrix[Payer], 0),
MATCH(B2, RateHeaders, 0))

XLOOKUP can approximate this by nesting one XLOOKUP inside another — XLOOKUP on rows, inner XLOOKUP on columns. The INDEX/MATCH/MATCH pattern is shorter and clearer for analysts already familiar with MATCH logic.

VLOOKUP vs XLOOKUP vs INDEX/MATCH: Full Comparison

CapabilityVLOOKUPXLOOKUPINDEX/MATCH
Excel version compatibilityAll versionsM365 / 2021 onlyAll versions
Look left (return col before lookup col)✗ No✓ Yes✓ Yes
Immune to column insertion✗ Breaks silently✓ Yes✓ Yes
Built-in not-found fallback✗ Needs IFERROR✓ 4th argument✗ Needs IFERROR
Last-to-first search (most recent match)✗ Not available✓ search_mode=-1✗ Requires workaround
Wildcard match (*,?)✓ With FALSE✓ match_mode=2✓ With MATCH type 0
Two-condition lookup (no helper column)✗ Not possibleWorkaround needed✓ Boolean array
Two-dimensional (row + column lookup)✗ Not possibleNested XLOOKUP✓ INDEX with 2×MATCH
Approximate match (sorted data, tiered lookup)✓ range_lookup=TRUE✓ match_mode=-1 or 1✓ MATCH type 1 or -1
Formula length / readabilityShort — easy to readMedium — readableLonger — complex scenarios are harder to audit
Safe in shared workbooks with column changes✗ No✓ Yes✓ Yes

When All Three Fail: Shared Limitations

VLOOKUP, XLOOKUP, and INDEX/MATCH share three failure modes that no amount of syntax knowledge can fix. Understanding these prevents the mistake of reaching for a lookup function when a different approach is needed.

Shared Failure 1: Duplicate Lookup Values — All Return Only One Result

All three functions return a single value. When the lookup key appears multiple times in the lookup array, all three return only the first match (or last match if XLOOKUP uses search_mode=-1). No lookup function returns multiple rows. When you need all rows where a condition is met, use FILTER (Microsoft 365) or SUMIFS/COUNTIFS for numeric aggregation.

Shared Failure 2: Text vs Number Type Mismatch

All three functions match by value and data type. A lookup value of the number 197 does not match a lookup array cell containing the text “197”. This is the most common cause of unexpected #N/A results in lookup formulas used against data exported from EHR systems, ticketing tools, and billing platforms — where codes that look like numbers are often stored as text.

Diagnose type mismatches: left-aligned numbers in a cell are stored as text. Right-aligned numbers are stored as numbers. Check alignment before building any lookup formula against exported data. Fix with VALUE() to convert text-numbers to numbers, or TEXT() to convert numbers to text, depending on which side needs adjusting.

Shared Failure 3: Trailing Spaces Prevent Matches

“BCBS ” (with trailing space) does not match “BCBS”. All three lookup functions treat them as different strings. Exported data from EHR systems, billing systems, and project management tools frequently contains invisible trailing spaces. Wrap the lookup value and lookup array in TRIM before using them:

— XLOOKUP with TRIM on both sides
=XLOOKUP(TRIM(A2), TRIM(ClaimData[Payer]), ClaimData[Rate], “Not found”)— Better: clean trailing spaces in Power Query before they reach the worksheet
— Text.Trim([Payer]) in Power Query Applied Steps

The more sustainable fix is to clean trailing spaces in Power Query before the data reaches the worksheet. Wrapping every lookup formula in TRIM is functional but adds formula length and recalculation overhead on large datasets.

Real Analyst Scenarios: Healthcare IT and Finance

Scenario 1 — Healthcare IT: ICD-10 Code Mapping in Epic Clarity Exports

Context

A reporting analyst at a health system exports encounter data from Epic Clarity. The export includes ICD-10 diagnosis codes but not descriptions. A separate reference Table called CodeMap has Code in column A and Description in column B. The analyst needs to add a Description column to the encounter export for a readability report sent to clinical leadership.

Three formulas, three different approaches:

— VLOOKUP: works if Code is column A, Description is column B
=IFERROR(VLOOKUP([@DiagCode], CodeMap, 2, FALSE), “Code not in reference”)— XLOOKUP: direction-independent, built-in fallback, safer long-term
=XLOOKUP([@DiagCode], CodeMap[Code], CodeMap[Description], “Code not in reference”)

— INDEX/MATCH: works in all Excel versions, immune to column insertion
=IFERROR(INDEX(CodeMap[Description], MATCH([@DiagCode], CodeMap[Code], 0)), “Code not in reference”)

The VLOOKUP formula works correctly today but will break silently if a new column is inserted into CodeMap between Code and Description. The XLOOKUP formula is cleaner and safe from that failure. The INDEX/MATCH formula is the correct choice if the workbook must support colleagues still on Excel 2019.

One practical issue specific to ICD-10 codes in Clarity exports: some ICD-10 codes are stored without the decimal separator (F321 instead of F32.1). The CodeMap reference table may use the formatted version. If the formats do not match, all three functions return #N/A. Fix the mismatch in Power Query before the data reaches the worksheet — either remove decimals from the reference table or add them to the export, consistently. This is the kind of data quality constraint that appears in every healthcare IT workbook that joins Clarity data against external reference tables.

Scenario 2 — Revenue Cycle: Payer-Service Rate Lookup with Two Conditions

Context

A revenue cycle analyst needs to pull the contracted rate for each claim. The rate table has three columns: Payer, ServiceType, and Rate. Each payer-service combination has a unique rate. A claim with Payer=”BCBS” and ServiceType=”Inpatient” should return the rate for that specific combination — not just the first BCBS rate or the first Inpatient rate.

VLOOKUP cannot do this without a helper column. XLOOKUP requires a concatenated helper column or a nested array approach. INDEX/MATCH handles it natively:

— INDEX/MATCH two-condition lookup (Ctrl+Shift+Enter in pre-365 Excel)
=IFERROR(
INDEX(RateTable[Rate],
MATCH(1,
(RateTable[Payer]=[@Payer])*(RateTable[ServiceType]=[@ServiceType]),
0)),
“Rate not found”)— XLOOKUP approach using concatenated helper column (less elegant)
— Helper column in RateTable: =[@Payer]&”|”&[@ServiceType]
=XLOOKUP([@Payer]&”|”&[@ServiceType], RateTable[LookupKey], RateTable[Rate], “Rate not found”)

The INDEX/MATCH approach avoids adding a helper column to the rate table. If the rate table is managed by another team and you cannot modify its structure, the INDEX/MATCH array formula is the only option without column additions. The XLOOKUP helper column approach requires modifying the rate table — which may be a governance issue in a shared workbook.

Scenario 3 — QA: Test Case Status Lookup with Most Recent Entry

A UAT workbook has a TestLog Table where test cases are re-entered each time they are retested. Scenario SC-042 may appear three times in the log — initial test (Fail), first retest (Fail), second retest (Pass). A summary formula needs the most recent status for each scenario ID, not the first.

— XLOOKUP with search_mode=-1: returns the LAST match (most recent retest)
=XLOOKUP(A2, TestLog[ScenarioID], TestLog[Status], “Not found”, 0, -1)— VLOOKUP: always returns the FIRST match — wrong for retest tracking
=VLOOKUP(A2, TestLog, 3, FALSE) — returns initial test result, not most recent

— INDEX/MATCH workaround for last match (complex, requires helper or LARGE)
=IFERROR(
INDEX(TestLog[Status],
MATCH(2, 1/(TestLog[ScenarioID]=A2), 1)),
“Not found”)

This is the scenario where XLOOKUP is unambiguously the best choice. The search_mode=-1 argument provides exactly this capability in a single, readable formula. The INDEX/MATCH workaround for last match is functional but significantly more complex and harder to maintain. VLOOKUP cannot do it at all without restructuring the data.

This UAT tracking pattern connects directly to the BAT vs UAT sign-off requirements — the sign-off condition depends on the most recent status, not the original test result.

Error Handling: IFERROR vs IFNA for Lookup Functions

VLOOKUP and INDEX/MATCH return #N/A when the lookup value is not found. XLOOKUP returns the if_not_found value instead — no wrapper needed. For VLOOKUP and INDEX/MATCH, use IFNA rather than IFERROR when the only expected error is “not found”:

— IFNA: catches only #N/A — structural errors (#REF!, #VALUE!) still visible
=IFNA(VLOOKUP(A2, CodeMap, 2, FALSE), “Code not in reference”)
=IFNA(INDEX(CodeMap[Description], MATCH(A2, CodeMap[Code], 0)), “Code not in reference”)— IFERROR: catches all errors — hides structural problems silently
=IFERROR(VLOOKUP(A2, CodeMap, 2, FALSE), “Code not in reference”)

The distinction matters in analyst workbooks. A VLOOKUP wrapped in IFERROR that returns #REF! because the table array reference is broken will silently show “Code not in reference” for every row — making a structural formula error look like a data quality issue. IFNA lets #REF! and #VALUE! errors surface where they should be visible.

Error wrapperWhat it catchesBest used withRisk
IFNA#N/A onlyVLOOKUP, INDEX/MATCH, MATCH when “not found” is the only expected errorLow — structural errors remain visible
IFERRORAll errors: #N/A, #REF!, #VALUE!, #DIV/0!, etc.Division formulas where zero denominator is expected; IFERROR(formula, 0)High if overused — hides structural formula problems
XLOOKUP if_not_found#N/A only (built into the function)Any XLOOKUP formula — cleaner than an IFNA wrapperLow — structural errors still surface separately

Decision Framework: Choosing the Right Lookup Function

Answer four questions about the lookup before choosing a function. The answers determine which function is correct — not preference or familiarity.

1
Will this workbook be opened in Excel 2019 or earlier?
Yes → XLOOKUP is off the table. Use VLOOKUP (if the table structure is stable and you control it) or INDEX/MATCH (if columns may change or you need left-lookup). No → XLOOKUP is available.
2
Do you need to match on two or more conditions simultaneously?
Yes, and no helper column → INDEX/MATCH with boolean array. Yes, and helper column is acceptable → XLOOKUP on concatenated key. No → single-condition lookup; any of the three works.
3
Do you need the most recent match (duplicate keys, last entry wins)?
Yes → XLOOKUP with search_mode=-1. This is the clearest available solution. INDEX/MATCH workaround exists but is more complex to maintain.
4
Could someone insert a column into the lookup table in future?
Yes → avoid VLOOKUP. Use XLOOKUP or INDEX/MATCH. Both reference columns by address or name rather than position number. No → VLOOKUP is acceptable if version constraints are met.

The Default for Most Analyst Workbooks

For analysts on Microsoft 365 building workbooks where all colleagues are also on Microsoft 365: XLOOKUP is the default for single-condition lookups. It handles left-lookup, built-in fallback, and is safe from column insertion. Use INDEX/MATCH for two-condition lookups and two-dimensional lookups. Never use VLOOKUP in new workbooks unless there is a specific version compatibility requirement.

For analysts in healthcare organisations where Excel versions vary across departments: INDEX/MATCH is safer as the default. It works in every version, handles left-lookup, and is immune to column insertion. The formula is longer, but it is correct in every environment the workbook may reach.

VLOOKUP should only be chosen when all four of these conditions are true: the table structure is stable and controlled, no colleague will add columns to the lookup table, all users are on a consistent Excel version, and a single condition lookup is sufficient. In practice, few shared analyst workbooks meet all four conditions. The column insertion failure mode alone eliminates VLOOKUP from most shared workbooks in enterprise environments.

The lookup function choice connects to the broader Excel skill stack described in the Excel for IT Analysts hub. XLOOKUP and INDEX/MATCH are Analyst Core level skills that determine whether workbooks remain accurate and maintainable over time — or become sources of silent wrong numbers that reach leadership reports.

Converting VLOOKUP to XLOOKUP or INDEX/MATCH: The Conversion Pattern

When you inherit a workbook with VLOOKUP formulas and need to convert them to a safer function, the pattern is mechanical:

VLOOKUP argumentMaps to in XLOOKUPMaps to in INDEX/MATCH
lookup_value (A2)lookup_value (A2)MATCH lookup_value (A2)
table_array, column 1 ($F$1:$H$50 → col 1 = F)lookup_array ($F$1:$F$50)MATCH lookup_array ($F$1:$F$50)
table_array, col_index 2 ($F$1:$H$50 → col 2 = G)return_array ($G$1:$G$50)INDEX return_range ($G$1:$G$50)
range_lookup (FALSE)match_mode (0)MATCH match_type (0)
IFERROR fallback (added separately)if_not_found (“Not found”)IFNA fallback (added separately)

Performance Differences: Does the Lookup Function Choice Affect Speed?

For datasets under 50,000 rows, the performance difference between VLOOKUP, XLOOKUP, and INDEX/MATCH is negligible in practice — all three execute in milliseconds. For workbooks with 100,000+ rows or with hundreds of lookup formulas referencing large Tables, the differences become measurable.

XLOOKUP uses binary search by default when data is sorted (search_mode=2), which is significantly faster than sequential search on large sorted datasets. VLOOKUP with range_lookup=TRUE also uses binary search — but requires sorted data and uses approximate match, not exact. INDEX/MATCH with MATCH type 0 always uses sequential search, making it slower on very large unsorted arrays than XLOOKUP with binary search mode.

For most analyst workbooks, this distinction does not matter. Reference tables for ICD-10 codes, payer names, and denial codes have hundreds to a few thousand rows — not hundreds of thousands. If performance is a genuine concern on a large workbook, the correct fix is usually to move the lookup logic to Power Query (which processes the join once during query refresh rather than recalculating on every worksheet change) rather than switching lookup functions.

Approximate Match Lookups: Tiered Rates and Aging Buckets

Approximate match is the least understood capability of all three functions — and the most useful for tiered rate lookups and aging bucket categorisation. Instead of finding an exact value, approximate match finds the largest value in the lookup array that is less than or equal to the lookup value.

For approximate match to work correctly, the lookup array must be sorted in ascending order. All three functions require this for approximate match — the VLOOKUP documentation notes this explicitly but the warning is often ignored.

— AR aging buckets: thresholds sorted ascending: 0, 31, 61, 91
— Bucket names: 0-30, 31-60, 61-90, 90+— VLOOKUP approximate match (range_lookup=TRUE)
=VLOOKUP([@DaysOutstanding], AgingBuckets, 2, TRUE)

— XLOOKUP with match_mode=-1 (exact or next smaller)
=XLOOKUP([@DaysOutstanding], AgingBuckets[Threshold], AgingBuckets[Label], “Unknown”, -1)

— INDEX/MATCH with match_type=1 (next smaller on sorted ascending data)
=INDEX(AgingBuckets[Label], MATCH([@DaysOutstanding], AgingBuckets[Threshold], 1))

All three produce the same result for sorted data. XLOOKUP with match_mode=-1 has an advantage: it does not require sorted data for the approximate match to work correctly. The VLOOKUP and INDEX/MATCH approaches will return wrong results silently if the threshold column is not sorted ascending. XLOOKUP’s explicit match mode argument makes the intent clear and removes the sorting dependency.

VLOOKUP on Tables vs Plain Ranges: The Hidden Fragility

The column insertion failure mode of VLOOKUP is most dangerous when the table array is a plain range with a hardcoded end row: $F$1:$H$200. When a new column is inserted between F and H, the column index number is wrong. When data grows past row 200, rows 201 and beyond are excluded silently.

Using VLOOKUP with an Excel Table as the table array partially mitigates the second problem. =VLOOKUP(A2, CodeMap, 2, FALSE) where CodeMap is a Table name will include all Table rows regardless of how many exist. But the column index number problem remains — insert a column inside CodeMap and the 2 now points to the wrong column.

XLOOKUP and INDEX/MATCH with structured references solve both problems completely:

— XLOOKUP with Table structured references: immune to row growth and column insertion
=XLOOKUP(A2, CodeMap[Code], CodeMap[Description], “Not found”)— INDEX/MATCH with structured references: same immunity, all Excel versions
=IFNA(INDEX(CodeMap[Description], MATCH(A2, CodeMap[Code], 0)), “Not found”)

Both formulas reference the columns by name. Insert any number of columns inside CodeMap — the formulas still find their columns correctly. Add any number of rows — the Table expands and the formulas include every row automatically. This combination of Table structure with XLOOKUP or INDEX/MATCH is the most maintainable lookup pattern available in Excel for analyst-managed workbooks.

The complete Excel Tables coverage — why to convert before touching any dataset, how structured references work, and the integration with Power Query and pivot tables — is in the Excel for IT Analysts hub. That foundation is what makes lookup formulas like the ones in this article maintainable over time rather than fragile workarounds.

Wildcard Matching: Partial Text Lookups

All three functions support wildcard matching for partial text lookups. The asterisk (*) matches any sequence of characters. The question mark (?) matches any single character.

— Find any payer name that contains “Blue” anywhere in the string
=XLOOKUP(“*Blue*”, PayerTable[PayerName], PayerTable[ContractTier], “Not found”, 2)— Find denial codes that start with “CO-“
=VLOOKUP(“CO-*”, DenialTable, 2, FALSE)

— INDEX/MATCH with wildcard
=IFNA(INDEX(PayerTable[ContractTier], MATCH(“*Blue*”, PayerTable[PayerName], 0)), “Not found”)

Wildcard matching has an important constraint: it always returns the first match, and it is case-insensitive. “Blue Cross”, “BlueCross”, and “bluecross” would all match “*Blue*”. For strict pattern matching on structured codes like ICD-10 or denial codes where partial matches could produce ambiguous results, use exact match (FALSE or 0) rather than wildcards. Reserve wildcards for genuinely fuzzy text lookups where multiple variations of the same entity name appear in different data sources.

The Case for Never Using VLOOKUP in New Workbooks

The argument against VLOOKUP in new workbooks is not that it is technically incorrect — it is that it is fragile by design. The column index number is a maintenance liability that no amount of documentation prevents in shared workbooks. Every experienced analyst who works in environments where multiple people maintain the same workbook has encountered a VLOOKUP that silently started returning wrong values after a column was inserted. The fix is always the same: switch to XLOOKUP or INDEX/MATCH.

VLOOKUP has one remaining legitimate use case: workbooks that must remain compatible with Excel 2016 or earlier, AND where the analyst controls the full table structure, AND where no other user will modify the column layout. This describes a very small percentage of analyst workbooks in enterprise healthcare IT environments. In most cases, the version compatibility argument for VLOOKUP is actually an argument for INDEX/MATCH — which is also universally compatible and does not have the column index number problem.

The practical transition: in any workbook you build from scratch, use XLOOKUP or INDEX/MATCH. In inherited workbooks with VLOOKUP, convert to INDEX/MATCH when you first encounter a VLOOKUP that has produced a wrong result — which is usually the first time a column is inserted into the lookup table after you inherit the workbook. After converting it once, the pattern becomes fast and the habit becomes automatic.

The Rule That Replaces Most VLOOKUP Debates

Check your organisation’s Excel version before choosing a lookup function, not after. If Microsoft 365 is the standard for everyone who will open the workbook — use XLOOKUP for single-condition lookups, INDEX/MATCH for two-condition and two-dimensional lookups. If any user might open the workbook on Excel 2019 or earlier — use INDEX/MATCH throughout. Never use VLOOKUP in a new shared workbook regardless of version. The column insertion silent failure mode alone makes VLOOKUP the wrong default for any workbook that will be maintained by more than one person.

Authoritative References

Downloads

📋
VLOOKUP vs XLOOKUP vs INDEX/MATCH Reference Card (PDF)
Full comparison table across 10 dimensions, the 4-question decision framework, the VLOOKUP-to-XLOOKUP conversion mapping table, IFERROR vs IFNA decision guide, and the three shared failure modes with fixes. One page, print-ready.

Download Reference Card (PDF)

📊
Lookup Function Practice Workbook Guide (PDF)
Four exercises: ICD-10 code mapping with all three functions side by side, two-condition payer-service rate lookup using INDEX/MATCH boolean array, most-recent-match UAT status using XLOOKUP search_mode=-1, and error handling comparison (IFNA vs IFERROR on the same formula).

Download Workbook Guide (PDF)

Scroll to Top