9.1 Modern Lookups with XLOOKUP & XMATCH

Key Takeaways

  • XLOOKUP fundamentally modernizes data retrieval by decoupling lookup and return arrays, defaulting to exact matching (match_mode 0), and supporting leftward and vertical/horizontal lookups without column index numbers.
  • The optional [if_not_found] argument provides native error handling, cleanly intercepting missing records without the computational overhead of external IFERROR or IFNA wrappers.
  • Advanced match modes support exact or next smaller (-1), exact or next larger (1), and wildcards (2), while search modes enable reverse scanning from bottom to top (-1) and high-speed binary searches (2 and -2).
  • XLOOKUP can return multi-column or multi-row dynamic arrays that spill across adjacent cells, and nesting two XLOOKUP functions enables dynamic two-way matrix lookups across rows and columns.
  • XMATCH returns the relative 1-based index position of an item within an array or range, superseding legacy MATCH by defaulting to exact matching and supporting reverse and binary search options.
Last updated: September 2026

Modern Lookups with XLOOKUP & XMATCH

Data retrieval is a core operational requirement in enterprise financial modeling, auditing, and business intelligence. For decades, spreadsheet engineers relied on legacy functions such as VLOOKUP, HLOOKUP, and LOOKUP. While functional, these legacy tools suffer from structural fragility: VLOOKUP requires hardcoded column index numbers that break whenever table columns are inserted or deleted, cannot natively retrieve data positioned to the left of the lookup column, and defaults to approximate matching if the final argument is omitted—frequently returning silent errors.

The modern Microsoft 365 calculation engine resolves these architectural limitations through XLOOKUP and XMATCH. Introduced to replace VLOOKUP, HLOOKUP, and legacy MATCH, these functions separate lookup and return vectors, default to exact match behavior, support dynamic array spilling, and offer native error handling.


Anatomy and Argument Architecture of XLOOKUP

The XLOOKUP function searches a range or array for a specified match and returns the corresponding item from a second range or array. Its syntax contains three required arguments and three optional arguments:

=XLOOKUP(lookup_value, lookup_array, return_array, [if_not_found], [match_mode], [search_mode])
ArgumentRequired / OptionalDescription & Functional Rules
lookup_valueRequiredThe value or cell reference to search for. Supports text, numbers, dates, wildcards, and dynamic array references.
lookup_arrayRequiredThe 1D range or array vector to search across (can be a vertical column or horizontal row).
return_arrayRequiredThe range or array containing values to return. Can span a single column/row or multiple adjacent columns/rows.
[if_not_found]OptionalThe value or text returned when no match is found (e.g., "Not Found", 0, or ""). If omitted and no match exists, returns #N/A.
[match_mode]OptionalSpecifies match type: 0 (Exact, default), -1 (Exact or next smaller), 1 (Exact or next larger), 2 (Wildcard match: *, ?, ~).
[search_mode]OptionalSpecifies search direction and algorithm: 1 (First-to-last, default), -1 (Last-to-first / reverse), 2 (Binary search, ascending), -2 (Binary search, descending).

Because lookup_array and return_array are separate arguments, XLOOKUP can look in any direction. If the lookup values reside in column D and the desired return values reside in column A, the formula =XLOOKUP(G2, D2:D100, A2:A100) executes a left-lookup seamlessly without rearranging the worksheet.


Parameter Deep Dive: Match Modes and Search Modes

Configuring match_mode and search_mode allows XLOOKUP to solve complex enterprise retrieval challenges that previously required convoluted array formulas.

Match Mode Behaviors

  • 0 — Exact Match (Default): Finds the first item exactly matching lookup_value. If no exact match is found, returns #N/A (or if_not_found).
  • -1 — Exact Match or Next Smaller: Matches the exact value, or the largest value that is smaller than lookup_value. This is the standard setting for tiered commission schedules, progressive tax brackets, and volume discount tiers where inputs fall between defined minimum thresholds.
  • 1 — Exact Match or Next Larger: Matches the exact value, or the smallest value that is greater than lookup_value. Ideal for shipping weight bands and inventory reorder triggers where any quantity exceeding a tier bumps into the next tier.
  • 2 — Wildcard Match: Enables the question mark (?) to match any single character, the asterisk (*) to match any sequence of characters, and the tilde (~) to escape literal wildcards.

Search Mode Behaviors

  • 1 — First to Last (Default): Searches sequentially from the first element of lookup_array to the last.
  • -1 — Last to First (Reverse Lookup): Scans backwards from the bottom or end of the array to the top. In chronological transactional ledgers where new entries are appended at the bottom, setting search_mode to -1 retrieves the most recent transaction for a customer or stock ticker without sorting.
  • 2 and -2 — Binary Searches: Executes binary search algorithms on pre-sorted arrays (2 requires ascending sort; -2 requires descending sort). While binary search offers O(log n) computational efficiency on massive datasets (100,000+ rows), it returns invalid results if the underlying array is not strictly sorted.

Native Error Handling with [if_not_found]

In legacy formulas, shielding users from #N/A errors required wrapping formulas in error traps:

=IFERROR(VLOOKUP(E2, A2:D100, 4, FALSE), "Not Found")

This pattern has two significant drawbacks: it obscures the formula's core intent and suppresses all errors, including internal syntax mistakes, reference corruption (#REF!), and division by zero (#DIV/0!).

XLOOKUP replaces this pattern with its built-in fourth argument:

=XLOOKUP(E2, A2:A100, D2:D100, "Not Found")

This parameter intercepts only lookup misses (#N/A), allowing other legitimate calculation errors to surface during auditing while avoiding additional calculation overhead.


Multi-Column Returns & Dynamic Spilling

XLOOKUP is fully integrated into Excel's dynamic array calculation engine. When return_array spans multiple contiguous columns or rows, XLOOKUP returns a dynamic array that automatically spills across adjacent worksheet cells.

=XLOOKUP("SKU-104", A2:A100, C2:E100)

If cell G2 contains this formula, Excel populates G2 with Description (column C), H2 with Unit Price (column D), and I2 with Stock Quantity (column E). The formula exists solely in G2, while H2:I2 display the spilled output surrounded by a thin blue ghost border. Downstream formulas can reference the entire spilled range using the spill operator (G2#).


Two-Way (Matrix) Dynamic Lookups

Complex financial schedules often require querying a 2D data grid by matching both a row identifier and a column identifier. Nesting XLOOKUP inside another XLOOKUP constructs an elegant two-way lookup:

Row Headers (A2:A5):   Department names
Col Headers (B1:E1):   Quarter names (Q1, Q2, Q3, Q4)
Data Grid   (B2:E5):   Budget figures

Lookup Target:         G2 = "Marketing" (Row) | H2 = "Q3" (Column)
=XLOOKUP(G2, A2:A5, XLOOKUP(H2, B1:E1, B2:E5))
Step 1: Inner XLOOKUP searches H2 ("Q3") in B1:E1
        └── Returns the entire Q3 column vector (D2:D5)
Step 2: Outer XLOOKUP searches G2 ("Marketing") in A2:A5
        └── Uses D2:D5 as its return_array to yield the intersection value

Relative Position Retrieval with XMATCH

When a model requires the numerical position of an item rather than the value itself, XMATCH replaces the legacy MATCH function:

=XMATCH(lookup_value, lookup_array, [match_mode], [search_mode])

Unlike legacy MATCH (which defaults to approximate match 1), XMATCH defaults to exact match (0), eliminates the need to specify the match parameter for standard lookups, and supports reverse lookups (search_mode: -1) and wildcards (match_mode: 2).


High-Frequency MO-211 Exam Traps

  • Dimension Mismatch (#VALUE!): The lookup_array and return_array must share identical lengths along the search axis. Entering =XLOOKUP(F2, A2:A50, B2:B60) produces an immediate #VALUE! error because the lookup vector contains 49 cells while the return vector contains 59 cells.
  • Unsorted Binary Searches: Setting search_mode to 2 or -2 on an unsorted dataset returns incorrect values without generating an error alert. Never use binary search unless the prompt explicitly confirms the data is sorted.
  • Spill Collisions (#SPILL!): When returning multi-column ranges, ensure all target spill cells are completely empty. Any existing text, value, or formatting block generates a #SPILL! error.
  • Approximate Bracket Reversal: In graduated tax or commission tables, using match_mode: 1 (next larger) when brackets define lower bounds will incorrectly assess taxpayers in the higher tax bracket.
Test Your Knowledge

A candidate needs to extract the most recent stock closing price for ticker "MSFT" from an unsorted historical log where new records are appended chronologically at the bottom of the table (rows 2 through 500). Which formula correctly returns the latest entry without re-sorting the dataset?

A
B
C
D
Test Your Knowledge

An analyst enters the formula =XLOOKUP(F2, A2:A50, B2:D60) into cell G2. Which error will Excel return upon evaluation, and what is the underlying technical cause?

A
B
C
D
Test Your Knowledge

In the two-way matrix formula =XLOOKUP(H2, A2:A20, XLOOKUP(H3, B1:F1, B2:F20)), what intermediate object is generated by the nested inner XLOOKUP to allow the outer function to resolve?

A
B
C
D