Available in:Excel 2021 or later (Works in Excel 2021, every later version, Microsoft 365 and Excel for the web)Category:Lookup & reference

XLOOKUP

X.ZOEKEN in Dutch Excel

Find a value in one list and bring back the matching item from another.

Difficulty rating 3 of 5. The three required arguments are simple; the three optional ones change how it searches and take practice to use with confidence.

Last updated: 23 October 2026

See the worked examples

Sheet excerpt: D2 holds the formula
RowABCD
1InvoiceCustomerInvoice to findCustomer found
21023110231Visser Bouw1023310233De Wit BV=XLOOKUP(C2, A2:A5, B2:B5)=XLOOKUP(C2; A2:A5; B2:B5)
31023210232Jansen BV
41023310233De Wit BV
51023410234Bakker Metaal
Formula cell (D2)Input

Result: De Wit BV

=XLOOKUP(C2, A2:A5, B2:B5)
=XLOOKUP(C2; A2:A5; B2:B5)

What XLOOKUP does and when to use it

What it does: it finds a value in one column or row and returns the matching value from another, for example the customer that belongs to an invoice number.

When to use it: whenever you look something up in a table. It replaces VLOOKUP, HLOOKUP and most INDEX and MATCH combinations.

Three main gains:

  • Any direction: the answer column can sit left or right of the column you search, and you point at it instead of counting columns.
  • Exact by default: no FALSE to forget, and inserting a column in the table does not break the formula.
  • Its own not-found text: if_not_found shows your message instead of #N/A, without IFERROR.

XLOOKUP or VLOOKUP?

Compare with VLOOKUP
  • VLOOKUP: you count the column
    =VLOOKUP(E2, $A$2:$C$6, 3, FALSE)
    =VLOOKUP(E2; $A$2:$C$6; 3; FALSE)
  • XLOOKUP: you point at the column
    =XLOOKUP(E2, $A$2:$A$6, $C$2:$C$6)
    =XLOOKUP(E2; $A$2:$A$6; $C$2:$C$6)
How the VLOOKUP arguments become XLOOKUP arguments
  • col_index_num (the 3) becomes return_array: you point at $C$2:$C$6 instead of counting columns.
  • range_lookup FALSE (exact) becomes match_mode 0, which is the default, so you can leave it out.
  • range_lookup TRUE (approximate) becomes match_mode -1, and the data need not be sorted.
  • table_array shrinks to lookup_array: only the column you search.

Colleague on Excel 2019 or older

Excel 2016 and 2019 do not have XLOOKUP and show #NAME? once the file recalculates. For files that go to those versions, keep VLOOKUP or INDEX and MATCH.

XLOOKUP(lookup_value, lookup_array, return_array, [if_not_found], [match_mode], [search_mode])
XLOOKUP(lookup_value; lookup_array; return_array; [if_not_found]; [match_mode]; [search_mode])
Arguments
ArgumentTypeMeaningDefault
lookup_valueRequiredThe value you are looking for.
lookup_arrayRequiredThe one column or row to search in.
return_arrayRequiredThe range the answer comes from.
if_not_foundOptionalWhat to show when nothing matches.#N/A
match_modeOptionalExact, next smaller, next larger, wildcard or regex.
  • 0Only an exact match counts (the default)
  • -1Exact match, or else the next smaller value
  • 1Exact match, or else the next larger value
  • 2Wildcards count: * is any characters, ? is one
  • 3The lookup value is a regular expression pattern; case sensitive
0
search_modeOptionalSearch direction, or binary search (halving) on sorted data.
  • 1Search from the first row down (the default)
  • -1Search from the last row up, for the latest entry
1

Return value:The matching value from the column you return (return_array), or your own message when nothing is found.

Formulas use commas (,) between arguments, as in English Excel. Formulas use semicolons (;) between arguments, as in Dutch Excel. Formulas use commas (,) between arguments, as in English Excel; Dutch Excel uses semicolons (;).

Worked examples

Beginner

Look up a balance in the trial balance

You tie your working papers to the client's trial balance (saldibalans) and want the year-end balance of accounts 1300, 1800 and 1100 with one formula copied to three cells.

Sheet excerpt: F2:F4 holds the formula
RowABCDEFG
1AccountDescriptionBalance 31 Dec 2025AccountBalance
211001100Bank€84,250.50€ 84.250,5013001300€213,400.00€ 213.400,00=XLOOKUP(E2, $A$2:$A$6, $C$2:$C$6)=XLOOKUP(E2; $A$2:$A$6; $C$2:$C$6)
313001300Trade receivables€213,400.00€ 213.400,0018001800-€28,450.00€ -28.450,00=XLOOKUP(E3, $A$2:$A$6, $C$2:$C$6)=XLOOKUP(E3; $A$2:$A$6; $C$2:$C$6)
416001600Trade payables-€156,900.25€ -156.900,2511001100€84,250.50€ 84.250,50=XLOOKUP(E4, $A$2:$A$6, $C$2:$C$6)=XLOOKUP(E4; $A$2:$A$6; $C$2:$C$6)
518001800VAT payable-€28,450.00€ -28.450,00
680008000Revenue-€1,245,000.00€ -1.245.000,00
7
Formula cell (F2:F4)Input

Formula in F2

=XLOOKUP(E2, $A$2:$A$6, $C$2:$C$6)
=XLOOKUP(E2; $A$2:$A$6; $C$2:$C$6)

Result: €213,400.00€ 213.400,00

Step by step
  1. E2 holds 1300. The $ signs lock $A$2:$A$6 and $C$2:$C$6, so the ranges stay put when you copy the formula.
  2. Excel scans $A$2:$A$6 from the top: 1100, no; 1300, yes, in the second cell, A3.
  3. It returns the second cell of $C$2:$C$6, which is C3: €213,400.00€ 213.400,00 in F2.
  4. Copy F2 down to F4. Only the lookup cell moves: 1800 returns -€28,450.00€ -28.450,00 and 1100 returns €84,250.50€ 84.250,50.

Watch out: Leave out the $ signs and the ranges slide down as you copy: F4 searches A4:A8 instead of A2:A6, which no longer holds account 1100, so it returns #N/A.

Intermediate

Missing invoice in the subledger

You test whether booked invoices appear in the debtors subledger. A missing one must say “No match” instead of #N/A, so you can check it.

Sheet excerpt: F2:F3 holds the formula
RowABCDEFG
1Invoice no.CustomerOpen amountInvoice no.Open amount
2F-25-0391Hoekstra Bouw BV€12,100.00€ 12.100,00F-25-0394€8,750.00€ 8.750,00=XLOOKUP(E2, $A$2:$A$6, $C$2:$C$6, "No match")=XLOOKUP(E2; $A$2:$A$6; $C$2:$C$6; "No match")
3F-25-0392Smit Handel BV€4,235.50€ 4.235,50F-25-0398No match=XLOOKUP(E3, $A$2:$A$6, $C$2:$C$6, "No match")=XLOOKUP(E3; $A$2:$A$6; $C$2:$C$6; "No match")
4F-25-0394Van Dijk BV€8,750.00€ 8.750,00
5F-25-0395Hoekstra Bouw BV€3,025.00€ 3.025,00
6F-25-0397De Boer BV€15,640.25€ 15.640,25
7
Formula cell (F2:F3)Input

Formula in F2

=XLOOKUP(E2, $A$2:$A$6, $C$2:$C$6, "No match")
=XLOOKUP(E2; $A$2:$A$6; $C$2:$C$6; "No match")

Result: €8,750.00€ 8.750,00

Step by step
  1. E2 holds F-25-0394. Excel finds it in the third cell of $A$2:$A$6, A4.
  2. It returns the third cell of $C$2:$C$6: €8,750.00€ 8.750,00 in F2.
  3. Copy F2 down. E3 holds F-25-0398, and none of the five invoice numbers matches it.
  4. The fourth argument is filled in, so F3 shows the text No match instead of #N/A.

Watch out: The message is text: SUM ignores it, but a calculation with + gives #VALUE!. If the column feeds a calculation, return 0 instead.

More on this example: why it works, 2 variations

Why it works

A real problem such as #REF! still shows, because if_not_found catches only a missing value.

Variations

=XLOOKUP(E2, $A$2:$A$6, $B$2:$C$6, "No match")
=XLOOKUP(E2; $A$2:$A$6; $B$2:$C$6; "No match")

With a two-column return_array one formula returns the customer and the amount, in F2:G2.

=XLOOKUP(1, (B2:B6="Hoekstra Bouw BV")*(C2:C6=3025), A2:A6)
=XLOOKUP(1; (B2:B6="Hoekstra Bouw BV")*(C2:C6=3025); A2:A6)

Two conditions: multiplying TRUE/FALSE results leaves a 1 only where both hold. It returns F-25-0395.

Advanced

Two-way lookup by account and period

An overview from the XAF auditfile (the standard audit export of Dutch accounting software) lists accounts down the side and periods 10 to 12 across, and one cell returns the movement for the chosen account and period.

Sheet excerpt: G3 holds the formula
RowABCDEFGH
1AccountP10P11P12Account45004500
211001100€48,100.00€ 48.100,00€61,250.00€ 61.250,00€70,300.00€ 70.300,00PeriodP12
340004000€38,200.00€ 38.200,00€38,900.00€ 38.900,00€54,600.00€ 54.600,00Movement€18,750.00€ 18.750,00=XLOOKUP(G1, A2:A5, XLOOKUP(G2, B1:D1, B2:D5))=XLOOKUP(G1; A2:A5; XLOOKUP(G2; B1:D1; B2:D5))
445004500€12,500.00€ 12.500,00€12,500.00€ 12.500,00€18,750.00€ 18.750,00
580008000€91,900.00€ 91.900,00€88,300.00€ 88.300,00€98,800.00€ 98.800,00
6
Formula cell (G3)Input

Formula in G3

=XLOOKUP(G1, A2:A5, XLOOKUP(G2, B1:D1, B2:D5))
=XLOOKUP(G1; A2:A5; XLOOKUP(G2; B1:D1; B2:D5))

Result: €18,750.00€ 18.750,00

Step by step
  1. The inner XLOOKUP runs first: it finds G2 (P12) in the header row B1:D1, in the third cell, and returns the third column of B2:D5: D2:D5.
  2. That column is the return_array of the outer XLOOKUP, which finds G1 (4500) in A2:A5, in the third cell, A4.
  3. It returns the third cell of D2:D5, which is D4: €18,750.00€ 18.750,00.
  4. Change G1 to 1100 and G2 to P10, and the same formula returns €48,100.00€ 48.100,00.

Watch out: The period headers here are text (P10 to P12), so G2 must hold the text P12. If an export gives the periods as numbers (12), type the number 12 in G2 as well: a number never matches the same digits stored as text.

More on this example: 2 more pitfalls, 2 variations

More to watch out for

  • If people type the inputs by hand, add if_not_found to the outer XLOOKUP, or a typo gives #N/A.
  • match_mode 3 (the regex variation below) works only in Microsoft 365. In Excel 2021 or 2024 the same formula returns #VALUE!, so keep exact lookups in files that go to those versions.

Variations

=XLOOKUP(G2, B1:D1, XLOOKUP(G1, A2:A5, B2:D5))
=XLOOKUP(G2; B1:D1; XLOOKUP(G1; A2:A5; B2:D5))

Nest the other way round: find the account row first, then pick the period.

=XLOOKUP("^P1[12]$", B1:D1, XLOOKUP(G1, A2:A5, B2:D5), "No period", 3, -1)
=XLOOKUP("^P1[12]$"; B1:D1; XLOOKUP(G1; A2:A5; B2:D5); "No period"; 3; -1)

Find the period by pattern instead of by name (Microsoft 365). ^P1[12]$ fits P11 and P12 and nothing else: ^ and $ pin the pattern to the whole header, and [12] is one digit, 1 or 2. search_mode -1 searches from the right, so the last fit wins: P12. For account 4500 the formula returns €18,750.00€ 18.750,00.

Master

Latest receipt of a customer by name pattern (match_mode 3)

On the bank statement of Veldhuis Installatie BV, customer Brouwer Klimaat BV appears in the free text in different spellings: "SEPA Brouwer Klimaat BV", "BROUWER KLIM. BV" and "brouwer klimaat b.v.". The statement is in date order and you need the date and amount of the latest receipt for a cut-off check. A different company, Brouwer Klimaatgroep NV, is on the same statement and must not be picked up.

Sheet excerpt: E3 holds the formula
RowABCDEFG
1DescriptionDateAmountNameBrouwer
2SEPA Brouwer Klimaat BV14 Jan 2026€4,250.00€ 4.250,00WordKlimaat
3Kuipers Dakwerken BV21 Jan 2026€3,300.00€ 3.300,00Latest9 Mar 2026=LET( stem, E1, word, E2, pattern, "(?i)\b" & stem & "[ .]*" & LEFT(word, 4) & "[a-z.]*[ .]*b\.?v\b", XLOOKUP(pattern, $A$2:$A$9, $B$2:$C$9, "No receipt", 3, -1) )=LET( stem; E1; word; E2; pattern; "(?i)\b" & stem & "[ .]*" & LEFT(word; 4) & "[a-z.]*[ .]*b\.?v\b"; XLOOKUP(pattern; $A$2:$A$9; $B$2:$C$9; "No receipt"; 3; -1) )€5,775.00€ 5.775,00
4BROUWER KLIM. BV6 Feb 2026€6,120.50€ 6.120,50
5Willems Elektra VOF19 Feb 2026€2,480.00€ 2.480,00
6brouwer klimaat b.v. deelbetaling9 Mar 2026€5,775.00€ 5.775,00
7Brouwer Klimaatgroep NV24 Mar 2026€9,200.00€ 9.200,00
8Peters Tegelwerk BV27 Mar 2026€1,945.25€ 1.945,25
9Scholten Staalbouw BV30 Mar 2026€7,060.00€ 7.060,00
10
Formula cell (E3)InputSpilled result

Formula in E3

=LET(
  stem, E1,
  word, E2,
  pattern, "(?i)\b" & stem & "[ .]*" & LEFT(word, 4) & "[a-z.]*[ .]*b\.?v\b",
  XLOOKUP(pattern, $A$2:$A$9, $B$2:$C$9, "No receipt", 3, -1)
)
=LET(
  stem; E1;
  word; E2;
  pattern; "(?i)\b" & stem & "[ .]*" & LEFT(word; 4) & "[a-z.]*[ .]*b\.?v\b";
  XLOOKUP(pattern; $A$2:$A$9; $B$2:$C$9; "No receipt"; 3; -1)
)

Result: 9 Mar 2026 | €5,775.009 Mar 2026 | € 5.775,00

Step by step
  1. LET reads pairs of a name and a value: stem becomes Brouwer (from E1) and word becomes Klimaat (from E2). Nothing is searched yet.
  2. pattern is joined from cells and fixed parts: (?i)\bBrouwer[ .]*Klim[a-z.]*[ .]*b\.?v\b. LEFT(word, 4) gives Klim, which covers both KLIM. and klimaat.
  3. Read the pattern from left to right. (?i) ignores case. \b is a word boundary, so Brouwer must start a word. [ .]* is any number of spaces and dots, including none. [a-z.]* finishes the word Klim. b\.?v is the letters b and v with an optional dot between them. The last \b makes the v the end of a word.
  4. match_mode 3 treats the lookup value as a regex and tests every cell of $A$2:$A$9 for a match anywhere in the text. No ^ or $ is needed here, because the name sits inside a longer description. search_mode -1 starts at the bottom, A9, and works upward.
  5. A9 (Scholten Staalbouw) and A8 (Peters Tegelwerk) do not contain Brouwer. A7 is Brouwer Klimaatgroep NV: Brouwer and Klim fit, aatgroep fits [a-z.]*, but then the pattern needs a b and finds NV. No match, which is how the other company stays out. A6 is brouwer klimaat b.v. deelbetaling: brouwer, a space, klimaat, a space and b.v, followed by a dot, which is a word boundary after the v. First match from the bottom: A6.
  6. XLOOKUP returns the fifth row of $B$2:$C$9, two columns wide: B6 is 9 March 2026 and C6 is €5,775.00€ 5.775,00. The result spills into E3:F3.
  7. The two earlier receipts also fit (A2, €4,250.00€ 4.250,00 and A4, €6,120.50€ 6.120,50), but search_mode -1 stops at the last one. Change E1 to Peters and E2 to Tegelwerk and the same formula returns 27 March 2026 and €1,945.25€ 1.945,25. A name with no receipt shows No receipt.

Watch out: A pattern that is too loose gives a wrong answer without an error. (?i)Brouwer alone also fits A7, so the formula returns 24 March 2026 and €9,200.00€ 9.200,00 from Brouwer Klimaatgroep NV. Mode 3 tests anywhere in the cell, so the \b and the legal form carry the precision. The wildcard mode 2 with *Brouwer* makes the same mistake and cannot express the legal form at all.

More on this example: why it works, 2 more pitfalls, 3 variations

Why it works

The name is not an exact value in the statement, it is a family of spellings, and a pattern describes the family: case, optional dots and spaces, an abbreviated second word and the legal form. Building the pattern in LET from two cells makes it reusable for any customer, and keeping the legal form in the pattern is what separates Brouwer Klimaat BV from Brouwer Klimaatgroep NV. "Latest" means the last row, so the statement must be in date order; if it is not, sort it first or the formula returns the lowest row, not the newest date.

Do not use match_mode 3 when the bank file carries a reliable customer or IBAN column: an exact XLOOKUP on that key cannot misread a spelling. Mode 3 also tests every cell with the regex engine and cannot use binary search, so on a statement of 100,000100.000 lines it is slower. The alternative is a helper column that normalises the description once (for example with REGEXREPLACE) followed by an exact lookup: one extra column, but every step can be reviewed and the lookup stays fast.

More to watch out for

  • Mode 3 is case sensitive unless the pattern starts with (?i). Without it the pattern \bBrouwer[ .]*Klim[a-z.]*[ .]*b\.?v\b finds none of the three receipts (the b of BV and BROUWER are capitals) and the cell shows No receipt, although the money arrived.
  • match_mode 3 works only in Microsoft 365. In Excel 2021 or 2024 the same formula returns #VALUE!, so use the SEARCH variation below in files that go to those versions.

Variations

=XLOOKUP("(?i)\bBrouwer[ .]*Klim[a-z.]*[ .]*b\.?v\b", $A$2:$A$9, $B$2:$C$9, "No receipt", 3)
=XLOOKUP("(?i)\bBrouwer[ .]*Klim[a-z.]*[ .]*b\.?v\b"; $A$2:$A$9; $B$2:$C$9; "No receipt"; 3)

Leave out search_mode (or use 1) and the first receipt wins: 14 January 2026 and €4,250.00€ 4.250,00 from A2.

=XLOOKUP(TRUE, REGEXTEST($A$2:$A$9, "\bBrouwer[ .]*Klim[a-z.]*[ .]*b\.?v\b", 1), $B$2:$C$9, "No receipt", 0, -1)
=XLOOKUP(TRUE; REGEXTEST($A$2:$A$9; "\bBrouwer[ .]*Klim[a-z.]*[ .]*b\.?v\b"; 1); $B$2:$C$9; "No receipt"; 0; -1)

The same result without match_mode 3: REGEXTEST (also Microsoft 365) returns TRUE or FALSE per line, with case_sensitivity 1 instead of (?i). Use it when you want to multiply in a second condition, for example (C2:C9>5000).

=XLOOKUP(1, --ISNUMBER(SEARCH("brouwer*klim*b*v", $A$2:$A$9)), $B$2:$C$9, "No receipt", 0, -1)
=XLOOKUP(1; --ISNUMBER(SEARCH("brouwer*klim*b*v"; $A$2:$A$9)); $B$2:$C$9; "No receipt"; 0; -1)

Fallback for Excel 2021 and 2024: SEARCH ignores case and understands *, and gives the same row here. It has no word boundary and no optional dot, so Brouwer Klimaat Beheer BV would also fit. Accept that, or add a helper column.

Mode explorer

Type a lookup value, choose where to look and what to return, pick a match mode and a search mode, and see which row XLOOKUP lands on.

Sheet excerpt: E2 holds the formula
RowABCDE
1ReferenceAmountDays openResult
2CN-0412-€1,200.00€ -1.200,00120120INV-1003=XLOOKUP("x", $B$2:$B$8, $A$2:$A$8, "No match", 0, 1)=XLOOKUP("x"; $B$2:$B$8; $A$2:$A$8; "No match"; 0; 1)
3INV-1001€450.00€ 450,009595
4INV-1002€450.00€ 450,006464
5INV-1003€1,800.00€ 1.800,004141
6INV-1004€3,250.00€ 3.250,002727
7INV-1005€7,500.00€ 7.500,001212
8INV-1006€12,000.00€ 12.000,0055
Formula cell (E2)
  • Formula cell
  • Where the search lands
  • What it returns

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", 0, 1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; 0; 1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", 0, -1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; 0; -1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", -1, 1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; -1; 1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", -1, -1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; -1; -1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", 1, 1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; 1; 1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", 1, -1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; 1; -1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", 2, 1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; 2; 1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", 2, -1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; 2; -1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", 3, 1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; 3; 1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $A$2:$A$8, "No match", 3, -1)
=XLOOKUP(1800; $B$2:$B$8; $A$2:$A$8; "No match"; 3; -1)

Result: INV-1003

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", 0, 1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; 0; 1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", 0, -1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; 0; -1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", -1, 1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; -1; 1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", -1, -1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; -1; -1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", 1, 1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; 1; 1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", 1, -1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; 1; -1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", 2, 1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; 2; 1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", 2, -1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; 2; -1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", 3, 1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; 3; 1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $B$2:$B$8, "No match", 3, -1)
=XLOOKUP(1800; $B$2:$B$8; $B$2:$B$8; "No match"; 3; -1)

Result: 18001800

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", 0, 1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; 0; 1)

Result: 4141

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", 0, -1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; 0; -1)

Result: 4141

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", -1, 1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; -1; 1)

Result: 4141

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", -1, -1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; -1; -1)

Result: 4141

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", 1, 1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; 1; 1)

Result: 4141

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", 1, -1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; 1; -1)

Result: 4141

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", 2, 1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; 2; 1)

Result: 4141

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", 2, -1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; 2; -1)

Result: 4141

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", 3, 1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; 3; 1)

Result: 4141

=XLOOKUP(1800, $B$2:$B$8, $C$2:$C$8, "No match", 3, -1)
=XLOOKUP(1800; $B$2:$B$8; $C$2:$C$8; "No match"; 3; -1)

Result: 4141

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", 0, 1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; 0; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", 0, -1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; 0; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", -1, 1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; -1; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", -1, -1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; -1; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", 1, 1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; 1; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", 1, -1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; 1; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", 2, 1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; 2; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", 2, -1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; 2; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", 3, 1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; 3; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $A$2:$A$8, "No match", 3, -1)
=XLOOKUP(1800; $A$2:$A$8; $A$2:$A$8; "No match"; 3; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", 0, 1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; 0; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", 0, -1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; 0; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", -1, 1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; -1; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", -1, -1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; -1; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", 1, 1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; 1; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", 1, -1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; 1; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", 2, 1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; 2; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", 2, -1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; 2; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", 3, 1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; 3; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $B$2:$B$8, "No match", 3, -1)
=XLOOKUP(1800; $A$2:$A$8; $B$2:$B$8; "No match"; 3; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", 0, 1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; 0; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", 0, -1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; 0; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", -1, 1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; -1; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", -1, -1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; -1; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", 1, 1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; 1; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", 1, -1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; 1; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", 2, 1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; 2; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", 2, -1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; 2; -1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", 3, 1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; 3; 1)

Result: No match

=XLOOKUP(1800, $A$2:$A$8, $C$2:$C$8, "No match", 3, -1)
=XLOOKUP(1800; $A$2:$A$8; $C$2:$C$8; "No match"; 3; -1)

Result: No match

Common mistakes

Common mistakes
SymptomCauseFix
#N/A although the value is in the listThe lookup value has a trailing space, or it is text while the list holds numbers (or the other way round).If the list holds numbers, use VALUE(TRIM(E2)): it removes the spaces and turns the text into a number. If the list holds text, TRIM(E2) is enough.
#VALUE! in the resultlookup_array and return_array are not the same height, or lookup_array is more than one column wide.Select the same rows in both, for example A2:A50 and C2:C50, not C2:C51. Click in the formula and press F2: Excel outlines both ranges, so a difference in height shows at once.
#SPILL! instead of the resultThe answer has several columns or rows, and a cell it needs to fill is not empty.Clear the cells next to the formula, or make return_array one column wide.
A 75-day invoice gets the 91-day ratematch_mode is 1, which takes the next larger band, instead of -1.Use -1 for “from this value up” bands, and test with a value between two bands.
A wrong row or #N/A with search_mode 2 or -2A binary search trusts the sort order (low to high for 2, high to low for -2), and the list is no longer sorted, for example after rows were added at the bottom.Sort the list again, or leave search_mode out: the default search from the first row works on any order.

Used in combinations

  • Find the customer from a bank descriptionCut the invoice number out of a bank statement description with TEXTAFTER and TEXTBEFORE, then look up the customer in the receivables list with XLOOKUP.Excel 2024 or later (This combination needs Excel 2024 or later)
  • Find the customer with a regex lookupPull the invoice number out of a bank description with REGEXEXTRACT, turn it into a pattern, and let XLOOKUP match that pattern against an invoice list that is typed in different ways.Excel for Microsoft 365 (This combination needs Excel for Microsoft 365)
  • Receivables aging total per 30-day bandTurn every due date into a band with XLOOKUP and match_mode -1 on a band table, then let SUM add up the open amounts of one band.Excel 2021 or later (This combination needs Excel 2021 or later)
  • Two-way lookup with one XLOOKUP and TOCOLFind the value where a row label and a column header meet, by turning both conditions into one grid of 0s and 1s and flattening it with TOCOL.Excel 2024 or later (This combination needs Excel 2024 or later)