Lookup and reference functions
MATCH
Matches all 156 recorded answers
Recorded: 13 in the answer bank and 143 workbook cells. How we measure this · See the Rust code
Local names in 40 languages
| Language | Name in Excel |
|---|---|
| Arabic | MATCH |
| Bulgarian | MATCH |
| Czech | MATCH |
| Danish | MATCH |
| German | MATCH |
| Greek | MATCH |
| English (Australia) | MATCH |
| English (United Kingdom) | MATCH |
| English (United States) | MATCH |
| Spanish | MATCH |
| Estonian | MATCH |
| Finnish | VASTINE |
| French | MATCH |
| Hebrew | MATCH |
| Croatian | MATCH |
| Hungarian | MATCH |
| Indonesian | MATCH |
| Italian | CONFRONTA |
| Japanese | MATCH |
| Korean | MATCH |
| Lithuanian | MATCH |
| Latvian | MATCH |
| Norwegian | MATCH |
| Dutch | MATCH |
| Polish | MATCH |
| Portuguese (Brazil) | MATCH |
| Portuguese (Portugal) | MATCH |
| Romanian | MATCH |
| Russian | MATCH |
| Slovak | MATCH |
| Slovenian | MATCH |
| Serbian (Latin) | MATCH |
| Swedish | MATCH |
| Thai | MATCH |
| Turkish | KAÇINCI |
| Ukrainian | MATCH |
| Vietnamese | MATCH |
| Chinese (Simplified) | MATCH |
| Chinese (Hong Kong) | MATCH |
| Chinese (Traditional) | MATCH |
Names from Microsoft's support site.
What it does
MATCH(lookup_value, lookup_array, [match_type])
MATCH returns a position, not a value. Given a lookup value v and a one-dimensional
lookup array L with entries L[1] … L[n], it returns an index i ∈ 1..n chosen by the
match_type rule, or #N/A.
The three rules, as Microsoft documents them:
match_type | Rule | Sort requirement |
|---|---|---|
1 (default) | the largest value that is less than or equal to v | L ascending |
0 | the first value exactly equal to v | none |
-1 | the smallest value that is greater than or equal to v | L descending |
Two of the three rules therefore carry a caller obligation that Excel does not check. The
1 and -1 rules are ordered searches: they are only meaningful over a sorted array, and
Excel raises no error when the array is not sorted — it returns a deterministic index computed
under a false premise.
Microsoft's documentation also states the sort order it means, which is unusually explicit and
worth quoting structurally rather than paraphrasing: ascending order is given as
-2, -1, 0, 1, 2, …, A-Z, FALSE, TRUE. That is a cross-type total order: all numbers
precede all text, text precedes FALSE, and FALSE precedes TRUE. This is the ordering an
ordered MATCH compares against when the array mixes types, and it is the same ordering that
governs the older approximate lookups.
The index returned is relative to L, not to the worksheet. MATCH(v, A5:A9, 0) returning
2 means A6 — the caller adds the offset. That is why MATCH is almost always seen inside
INDEX, which does the arithmetic.
Arguments
lookup_value — the value to find. May be a number, text, a logical, or a reference to
one. In exact mode (match_type 0) a text lookup value may contain wildcards: ? matches
any single character, * matches any run of characters, and ~ escapes a literal ?, * or
~. Wildcards are documented only for match_type 0.
lookup_array — the sequence to search. Conventionally a single row or single column.
What MATCH does with a genuinely two-dimensional array is not stated in the documentation
and is not asserted here.
match_type — optional, defaults to 1. This default deserves the same suspicion as
VLOOKUP's omitted fourth argument, for the same reason: omitting it selects an ordered
search whose failure on unsorted data is a plausible wrong index rather than an error. A
reader who writes MATCH(v, L) meaning "where is v" has written "where is the last entry not
exceeding v, assuming L is sorted ascending". Pass 0 explicitly when you mean exact.
Try it
Quirks
Result and edge cases
The return kind is a number: a 1-based index into lookup_array.
- Case-insensitivity. Microsoft states plainly that
MATCHdoes not distinguish uppercase from lowercase. Exact mode is therefore not string identity. - Errors, empty cells and omitted arguments follow the shared rules in coercion and lifting.
Errors
Documented: #N/A when no match is found. Under match_type 1 that includes the case where
v is smaller than every entry; under -1, where v is larger than every entry.
How to implement
Notes for implementers
- Three
match_typevalues are two different algorithms: an unordered scan for0, and an ordered search for±1. Sharing one code path between them is how implementations acquire the wrong behaviour on unsorted input. - Exact mode is case-insensitive but numerically strict. Those two facts pull in opposite directions and are easy to implement inconsistently.
- Wildcard handling belongs to exact mode only, and
~escaping has to be handled before pattern compilation, not after. lookup_valuemust admit arrays and spill elementwise.
Rust code
Show the CalcFunc source of this function
Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.
MATCH · 11 lines · calc-func/src/catalogue/lookup.rs on GitHubeager(
MATCH,
"MATCH",
CallableArityShape::range(2, 3),
&[
Parameter::value("lookup_value"),
Parameter::value_or_reference("lookup_array"),
Parameter::value("match_type"),
],
match_,
)
walk_descending · 28 lines · calc-func/src/catalogue/lookup.rs on GitHub/// MATCH's walk for match_type -1: see the module documentation.
fn walk_descending(
site: &Site<'_>,
services: &mut EvalServices<'_>,
line: Line<'_>,
key: Item<'_>,
) -> Step<Option<u64>> {
let mut best = None;
line.scan(site, services, &mut |at, value| {
let cell = item(site, 1, value)?;
if cell.rank() != key.rank() {
return Ok(ControlFlow::Continue(()));
}
Ok(match order(site, cell, key)? {
Ordering::Equal => {
best = Some(at);
ControlFlow::Break(())
}
Ordering::Greater => {
best = Some(at);
ControlFlow::Continue(())
}
Ordering::Less => ControlFlow::Break(()),
})
})?;
// An equal cell ends the walk as the result; a smaller one ends it with the last larger.
Ok(best)
}
match_ · 13 lines · calc-func/src/catalogue/lookup.rs on GitHub/// MATCH(lookup_value, lookup_array, [match_type]): the 1-based position of the lookup value in a
/// row or a column. match_type is read as a number and only its sign counts: 0 an exact match
/// (with wildcards), positive (the default) the bisection, negative the descending walk; an
/// omitted or blank match_type is 0. A lookup array that is not one row or one column, a
/// reference of several areas, and a lookup array that is a single value and not a reference are
/// #N/A, as is no match.
fn match_(
arguments: &[CalcValue],
services: &mut EvalServices<'_>,
) -> Result<CalcValue, FunctionFault> {
let site = Site::new(MATCH, services);
Site::finish(matched(&site, arguments, services))
}
matched · 35 lines · calc-func/src/catalogue/lookup.rs on GitHubfn matched(
site: &Site<'_>,
arguments: &[CalcValue],
services: &mut EvalServices<'_>,
) -> Step<CalcValue> {
let key = lookup_key(site, &arguments[0], BlankKey::Zero)?;
let grid = match shape(&arguments[1], 1) {
Shape::Error(code) => return Err(Exit::Error(code)),
Shape::Grid(grid) => Some(grid),
Shape::Areas | Shape::Blank => None,
};
let sign = match arguments.get(2) {
None => 1.0,
Some(value) if value.is_missing() || value.is_empty() => 0.0,
Some(value) => index_number(site, 2, value)?,
};
text_limit(key)?;
let not_found = Exit::Error(WorksheetErrorCode::NA);
let line = match grid {
// A single value given directly is not searched.
Some(Grid::One(_)) | None => return Err(not_found),
Some(grid) => grid.line().ok_or(not_found)?,
};
let found = if sign == 0.0 {
first_hit(site, services, line, &Target::new(key, true))?
} else if sign > 0.0 {
bisect(site, &line.held(site, services)?, key)?
} else {
walk_descending(site, services, line, key)?
};
match found {
Some(at) => position(site, at),
None => Err(Exit::Error(WorksheetErrorCode::NA)),
}
}
Kernels shared with other functions
textscatalogue/comparisoncomparecatalogue/comparison/collationweighedcatalogue/comparison/collationmeasured_iteration_extensioncatalogue/comparison/collationtablecatalogue/comparison/sort_keydecode64catalogue/comparison/sort_keyReader::bytecatalogue/comparison/sort_keyReader::varintcatalogue/comparison/sort_keyReader::donecatalogue/comparison/sort_keyin_rangescatalogue/comparison/sort_keybuildcatalogue/comparison/sort_keyhan_basecatalogue/comparison/sort_keyderivecatalogue/comparison/sort_keyshared_jamo_tailscatalogue/comparison/sort_keyordinary_jamo_prefixcatalogue/comparison/sort_keyindependent_jamo_suffixcatalogue/comparison/sort_keyjamo_leading_primarycatalogue/comparison/sort_keyleading_ordercatalogue/comparison/sort_keyBefore::separate_specialcatalogue/comparison/sort_keyGathered::kanacatalogue/comparison/sort_keyGathered::unitcatalogue/comparison/sort_keypartscatalogue/comparison/sort_keydiacritic_ordercatalogue/comparison/sort_keydiacriticscatalogue/comparison/sort_keyeagercatalogue/lookupItem::rankcatalogue/lookupitemcatalogue/lookuplookup_keycatalogue/lookuptext_limitcatalogue/lookupequalcatalogue/lookuperror_rankcatalogue/lookupordercatalogue/lookuppatterncatalogue/lookupmatchescatalogue/lookuphitscatalogue/lookupLine::lencatalogue/lookupLine::scancatalogue/lookupLine::heldcatalogue/lookupreadercatalogue/lookupcell_valuecatalogue/lookuprowscatalogue/lookupcolumnscatalogue/lookuprow_linecatalogue/lookupcolumn_linecatalogue/lookuplinecatalogue/lookupvaluecatalogue/lookupspancatalogue/lookupshapecatalogue/lookupfirst_hitcatalogue/lookupbisectcatalogue/lookupindex_numbercatalogue/lookuppositioncatalogue/lookupindexcatalogue/lookupselectorcatalogue/lookupindexedcatalogue/lookupselectcatalogue/lookuprowcatalogue/lookupcolumncatalogue/lookupposition_ofcatalogue/lookupareascatalogue/lookup
Argument and result plumbing
Parameter::valuecatalogueParameter::value_or_referencecatalogueoperandcoerce
No implementation has been published with a Handbook test suite for this function.
Version differences
No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.
Alternatives
Relationships
XMATCHsupersedesMATCH.XMATCHkeeps the position-returning shape but splits the singlematch_typeflag into an explicitmatch_modeandsearch_mode, defaults to exact match rather than ordered match, and adds reverse and binary search. For new workXMATCHis the better choice. Microsoft has not deprecatedMATCH; it remains supported and remains what existing workbooks contain.INDEXisMATCH's usual partner:INDEX(R, MATCH(v, L, 0))is the classic exact-lookup composition, and it is whatXLOOKUPpackages into one call.LOOKUPshares the ordered-search rule withmatch_type1and has no exact mode.- Readers confuse
MATCHwithFINDandSEARCH(which locate a substring inside one text value, not a value inside a list).
Named variants
No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents