Available in:All versions (Works in Excel 2007, every later version, Microsoft 365 and Excel for the web)Examples need Excel 2024 or laterCategory:Text

EXACT

GELIJK in Dutch Excel

Compares two texts character by character, including case, and returns TRUE only when they are identical.

Difficulty rating 1 of 5. Two arguments and a TRUE or FALSE answer; the one thing to learn is that it sees case, which = and almost every other Excel comparison do not.

Last updated: 13 October 2026

See the worked examples

Sheet excerpt: C3 holds the formula
RowABC
1Invoice no. in auditfileInvoice no. in specificationIdentical
2VRK25-0412aVRK25-0412a
3VRK25-0413bVRK25-0413BFALSE=EXACT(A3, B3)=EXACT(A3; B3)
4VRK25-0414VRK25-0414
5INK25-0877aINK25-0877A
6INK25-0878INK25-0878
Formula cell (C3)Input

Result: FALSE

=EXACT(A3, B3)
=EXACT(A3; B3)

What EXACT does and when to use it

What it does: it checks whether two texts are the same, character for character, and returns TRUE or FALSE, for example whether a retyped invoice number matches the ledger.

When to use it: when uppercase and lowercase matter, as in codes, tokens and exports you compare character for character. Unlike the = operator it sees Bakker and bakker as different. If case does not matter, = is shorter.

How Excel evaluates it

Excel reads both arguments:

  • a number is converted to text first, so 12 and "12" compare as equal
  • the two texts are compared character by character from the left: if the lengths differ, or any position holds a different character, the result is FALSE; only when every position matches, including the case of every letter, is the result TRUE
  • formatting is never part of the comparison, because EXACT sees the stored value, not how the cell displays it
  • given two ranges of the same size, it compares position by position and returns an array of TRUE and FALSE

Watch out: Only case separates EXACT from =: a trailing space or a different accent makes both of them return FALSE.

Mental model

Two printouts laid on top of each other against the light: the slightest difference in any letter, and the two do not line up.

Terms used on this page: operator, array, argument, range, cell

EXACT(text1, text2)
EXACT(text1; text2)
Arguments
ArgumentTypeMeaning
text1RequiredThe first text; a cell reference or text in quotes.
text2RequiredThe second text to compare with the first.

Return value:TRUE if both texts match exactly, including case, otherwise FALSE

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

Check a retyped invoice number against the ledger

Veldhuis Installatie BV numbers its invoices with a suffix letter: VRK25-0413b is the original, VRK25-0413B a re-issued version. Sanne de Vries retyped the invoice numbers of the debiteuren specification next to the numbers in the auditfile, and you want to see per line whether the two match exactly. A plain = would say yes to every line.

Sheet excerpt: C3 holds the formula
RowABCD
1Invoice no. in auditfileInvoice no. in specificationIdentical
2VRK25-0412aVRK25-0412a
3VRK25-0413bVRK25-0413BFALSE=EXACT(A3, B3)=EXACT(A3; B3)
4VRK25-0414VRK25-0414
5INK25-0877aINK25-0877A
6INK25-0878INK25-0878
7
Formula cell (C3)Input

Formula in C3

=EXACT(A3, B3)
=EXACT(A3; B3)

Result: FALSE

Step by step
  1. Excel reads A3, VRK25-0413b, and B3, VRK25-0413B. Both are text of 11 characters, so no conversion is needed.
  2. It compares position by position: V, R, K, 2, 5, hyphen, 0, 4, 1 and 3 are identical in both. Ten matches so far.
  3. Position 11: b in A3 against B in B3. Same letter, different case, and EXACT treats that as a difference. The result is FALSE.
  4. C3 shows FALSE. Put =A3=B3 in a spare cell and it shows TRUE for the same pair: the = operator does not look at case.
  5. Copy C3 to C2:C6. Rows 2, 4 and 6 give TRUE, row 5 gives FALSE for the same reason as row 3 (a against A). Two invoice numbers go back to the client for follow-up.

Watch out: An invoice number with a space at the end is also FALSE, for a different reason. If a FALSE surprises you, check LEN of both cells before blaming the case.

More on this example: why it works, 1 variation

Why it works

EXACT compares the stored characters and treats b and B as two different characters, which is what this numbering scheme needs when you match invoices between the subledger and the general ledger. Every other comparison in Excel folds case before comparing, so this is the only two-argument test that can tell the two versions apart.

Variations

=IF(EXACT(A3, B3), "Agreed", "Follow up")
=IF(EXACT(A3; B3); "Agreed"; "Follow up")

Readable words instead of TRUE and FALSE, for a column that the rest of the audit team will scan.

Intermediate

Match relation codes and ignore stray spaces

You reconcile the relation codes in the receivables and payables aging list with the codes in the auditfile. A difference in case, such as d1002 for D1002, points to a manual correction and you want to see it.

A trailing space is noise from the export and is not worth a query. You clean both sides with TRIM and let EXACT judge what is left, so that only meaningful differences show up.

Sheet excerpt: D2 holds the formula
RowABCDE
1Entry no.Relation in aging listRelation in auditfileSame
225-0501D1001D1001TRUE=EXACT(TRIM(B2), TRIM(C2))=EXACT(TRIM(B2); TRIM(C2))
325-0502D1002d1002
425-0503C2001C2001
525-0504D1003d1003
625-0505C2002C2002
7
Formula cell (D2)InputMarks: extra spaceNote: C2 and C5 end with a space; the export of the auditfile pads some fields.

Formula in D2

=EXACT(TRIM(B2), TRIM(C2))
=EXACT(TRIM(B2); TRIM(C2))

Result: TRUE

Step by step
  1. Excel evaluates the two TRIMs first. TRIM(B2) is D1001, 5 characters, unchanged. TRIM(C2) takes D1001 followed by a space, 6 characters, and removes the trailing space: D1001, 5 characters.
  2. EXACT compares the two cleaned texts position by position. All five characters match, case included. D2 shows TRUE.
  3. Without the TRIMs, EXACT(B2, C2) would compare 5 characters against 6 and return FALSE, flagging a difference that nobody needs to explain.
  4. Copy D2 down. Row 3: D1002 against d1002, both 5 characters after TRIM, but position 1 is D against d, so FALSE. That is a real difference to ask the client about.
  5. Row 5: D1003 against d1003 with a trailing space. TRIM removes the space, but the first letter still differs in case, so FALSE. Rows 4 and 6 are TRUE.

Watch out: A non-breaking space in one of the fields survives TRIM and makes EXACT return FALSE. If a FALSE makes no sense, replace CHAR(160) with a space on both sides.

More on this example: why it works, 1 more pitfall, 1 variation

Why it works

The two functions divide the work: TRIM removes the kind of difference you have decided is noise, and EXACT reports every difference that remains. Because both sides go through the same cleaning, the comparison is symmetric; it does not matter which file had the padding.

More to watch out for

  • TRIM also reduces repeated spaces inside a text to one, so D 1001 and D 1001 count as equal after cleaning. That is usually what you want, but it hides that difference.

Variations

=TRIM(B2) = TRIM(C2)
=TRIM(B2) = TRIM(C2)

The case-insensitive version: TRUE for all five rows here, because rows 3 and 5 differ only in case. Use it when case is also noise.

Advanced

Count manual MEM journal lines case-sensitively

For journal entry testing you need the number of manual lines in journal MEM. This client also has a journal mem for the automatic depreciation run, and an export artifact Mem. COUNTIF(A2:A8, "MEM") returns 5, because it folds case and counts all three spellings. EXACT inside SUMPRODUCT counts only the manual journal MEM.

Sheet excerpt: F2 holds the formula
RowABCDEFG
1JournalEntry no.AmountJournalLines
2MEM25-1101€4,500.00€ 4.500,00MEM33=SUMPRODUCT(--EXACT(A2:A8, E2))=SUMPRODUCT(--EXACT(A2:A8; E2))
3mem25-1102€1,200.00€ 1.200,00
4MEM25-1103€12,000.00€ 12.000,00
5INK25-1104€850.00€ 850,00
6Mem25-1105€300.00€ 300,00
7MEM25-1106€2,500.00€ 2.500,00
8VRK25-1107€7,200.00€ 7.200,00
9
Formula cell (F2)Input

Formula in F2

=SUMPRODUCT(--EXACT(A2:A8, E2))
=SUMPRODUCT(--EXACT(A2:A8; E2))

Result: 33

Step by step
  1. Excel evaluates EXACT with a range as text1 and a single cell as text2, so it compares each of the seven cells with E2, MEM, and returns an array of seven results.
  2. Excel compares each cell with MEM:

    • A2 MEM: TRUE
    • A3 mem: position 1 is m against M, FALSE
    • A4 MEM: TRUE
    • A5 INK: I against M, FALSE
    • A6 Mem: position 2 is e against E, FALSE
    • A7 MEM: TRUE
    • A8 VRK: V against M, FALSE

    The array is {TRUE;FALSE;TRUE;FALSE;FALSE;TRUE;FALSE}.

  3. The double minus converts TRUE to 1 and FALSE to 0: {1;0;1;0;0;1;0}. SUMPRODUCT cannot add TRUE and FALSE directly, which is why this step is needed.
  4. SUMPRODUCT adds the array: 1 + 0 + 1 + 0 + 0 + 1 + 0 = 3. F2 shows 3 manual MEM lines.
  5. =COUNTIF(A2:A8, E2) in a spare cell shows 5: the three MEM lines, the mem line and the Mem line, all folded to the same code. That is the count you did not want.
  6. Change E2 to mem and F2 becomes 1. Change it to Mem and F2 also becomes 1.

Watch out: Leave out the double minus and SUMPRODUCT returns 0, not an error: a lone array of booleans adds up to nothing. The formula looks right and the count is silently wrong.

More on this example: why it works, 1 more pitfall, 2 variations

Why it works

COUNTIF, COUNTIFS and SUMIFS compare with case folded in, and there is no switch to turn that off. EXACT is the one comparison that keeps case, and given a range it produces one TRUE or FALSE per cell. SUMPRODUCT then does what COUNTIF would have done, adding up the matches, once the booleans have been turned into numbers.

More to watch out for

  • In Excel 2019 or older, this works inside SUMPRODUCT without Ctrl+Shift+Enter, but the same EXACT(A2:A8, E2) in a plain cell shows only the comparison for its own row (implicit intersection). Keep it inside SUMPRODUCT or SUM with Ctrl+Shift+Enter.

Variations

=SUMPRODUCT(--EXACT(A2:A8, E2), C2:C8)
=SUMPRODUCT(--EXACT(A2:A8; E2); C2:C8)

The case-sensitive SUMIFS: multiplies each match by its amount. Here 4,5004.500 + 12,00012.000 + 2,5002.500 = 19,00019.000 in manual MEM entries.

=XLOOKUP(TRUE, EXACT(A2:A8, E2), C2:C8)
=XLOOKUP(TRUE; EXACT(A2:A8; E2); C2:C8)

The case-sensitive lookup: returns the amount of the first exact match, 4,5004.500. XLOOKUP looks for the value TRUE in the array EXACT produced.

MasterExcel 2024 or later (This example needs Excel 2024 or later)

Exact duplicate invoice numbers with BYROW and FILTER

In the payables list of supplier C2001 you look for duplicate invoice numbers as an indicator of double payments. This supplier issues F25-318a and F25-318A as two separate invoices, so only an identical spelling counts as a duplicate.

Remove Duplicates and UNIQUE both fold case and would wrongly merge those two. You want the invoice numbers that occur more than once in exact spelling, each listed once, as a spilled report that updates when the list changes.

Sheet excerpt: D2 holds the formula
RowABCDE
1Invoice no.Booking dateDuplicate invoice numbers
2F25-318a28 Nov 2025F25-318a=LET( invoices, A2:A8, hits, BYROW(invoices, LAMBDA(t, SUMPRODUCT(--EXACT(invoices, t)))), firstAt, BYROW(invoices, LAMBDA(t, XMATCH(TRUE, EXACT(invoices, t)))), isFirst, firstAt = SEQUENCE(ROWS(invoices)), FILTER(invoices, (hits > 1) * isFirst) )=LET( invoices; A2:A8; hits; BYROW(invoices; LAMBDA(t; SUMPRODUCT(--EXACT(invoices; t)))); firstAt; BYROW(invoices; LAMBDA(t; XMATCH(TRUE; EXACT(invoices; t)))); isFirst; firstAt = SEQUENCE(ROWS(invoices)); FILTER(invoices; (hits > 1) * isFirst) )
3F25-318A28 Nov 2025F25-318A
4KV-22172 Dec 2025KV-2217
5F25-318a5 Dec 2025
6kv-22175 Dec 2025
7KV-221712 Dec 2025
8F25-318A19 Dec 2025
9
Formula cell (D2)InputSpilled result

Formula in D2

=LET(
  invoices, A2:A8,
  hits, BYROW(invoices, LAMBDA(t, SUMPRODUCT(--EXACT(invoices, t)))),
  firstAt, BYROW(invoices, LAMBDA(t, XMATCH(TRUE, EXACT(invoices, t)))),
  isFirst, firstAt = SEQUENCE(ROWS(invoices)),
  FILTER(invoices, (hits > 1) * isFirst)
)
=LET(
  invoices; A2:A8;
  hits; BYROW(invoices; LAMBDA(t; SUMPRODUCT(--EXACT(invoices; t))));
  firstAt; BYROW(invoices; LAMBDA(t; XMATCH(TRUE; EXACT(invoices; t))));
  isFirst; firstAt = SEQUENCE(ROWS(invoices));
  FILTER(invoices; (hits > 1) * isFirst)
)

Result: F25-318a / F25-318A / KV-2217F25-318a / F25-318A / KV-2217

Step by step
  1. invoices is A2:A8, seven values. hits runs a LAMBDA once per row: for each invoice number t, EXACT(invoices, t) compares all seven with t, case-sensitively, and SUMPRODUCT with the double minus counts the TRUEs.

    For row 1, F25-318a, only A2 and A5 are exact matches; F25-318A in A3 and A8 differs in case and does not count. hits is {2;2;2;2;1;2;2}; the 1 is kv-2217 in row 5.

  2. firstAt runs a second LAMBDA per row: XMATCH looks for the value TRUE in EXACT(invoices, t) and returns the position of the first exact match. For F25-318a that is 1, for F25-318A it is 2, for KV-2217 it is 3. firstAt is {1;2;3;1;5;3;2}.
  3. isFirst compares firstAt with SEQUENCE(7), which is {1;2;3;4;5;6;7}. A row is a first occurrence when its own position equals the position of its first match: {TRUE;TRUE;TRUE;FALSE;TRUE;FALSE;FALSE}.
  4. FILTER keeps the rows where both conditions hold. Multiplying (hits > 1) by isFirst gives {1;1;1;0;0;0;0}: row 5 fails on hits, rows 4, 6 and 7 fail on isFirst.
  5. The report spills F25-318a, F25-318A and KV-2217 into D2:D4: three distinct spellings that each occur more than once. kv-2217 is absent because that lowercase spelling occurs only once, even though KV-2217 occurs twice.
  6. Change A8 to G25-007 and hits for row 2 becomes 1: F25-318A now occurs once, drops out, and the report shrinks to F25-318a and KV-2217.

Watch out: The mirror image, UNIQUE(FILTER(invoices, hits > 1)) instead of the isFirst test, looks shorter and is wrong: UNIQUE folds F25-318a and F25-318A into one, and the report shows two invoice numbers where there are three. No error appears.

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

Why it works

Every step that would normally fold case is replaced by one built on EXACT: the count uses EXACT inside SUMPRODUCT instead of COUNTIF, and the first-occurrence test uses XMATCH over an EXACT array instead of UNIQUE. BYROW runs those per invoice number without a helper column, and LET names the two intermediate arrays so the FILTER condition reads as the rule it implements. EXACT is the way to get a case-sensitive count or first-occurrence test here, because none of the counting or unique functions have a switch for it.

Do not use this construction on tens of thousands of rows: each invoice number is compared with every other, so the cost grows with the square of the list, and 20,00020.000 invoice lines means 400 million comparisons per recalculation.

The alternative at that scale is a helper column with =SUMPRODUCT(--EXACT(A$2:A$20001, A2)) copied down, which is still quadratic but calculates once and can be pasted as values, or Power Query, whose Group By is case-sensitive by default and refreshes on demand.

More to watch out for

  • Use MATCH instead of XMATCH and you get the same positions, but the default match_type 1 assumes sorted data; always pass 0 to MATCH. XMATCH defaults to exact.
  • D2:D4 must be empty, or the report shows #SPILL!. When there are no duplicates at all, FILTER returns #CALC!; add an if_empty argument to FILTER if the report must always display something.

Variations

=SUMPRODUCT(--EXACT(A$2:A$8, A2))
=SUMPRODUCT(--EXACT(A$2:A$8; A2))

The helper-column version, copied down next to the invoice numbers: 2 for every duplicate row, 1 for kv-2217. It works in Excel 2019, which has no BYROW or LET.

=FILTER(A2:A8, BYROW(A2:A8, LAMBDA(t, SUMPRODUCT(--EXACT(A2:A8, t)))) > 1, "No duplicates")
=FILTER(A2:A8; BYROW(A2:A8; LAMBDA(t; SUMPRODUCT(--EXACT(A2:A8; t)))) > 1; "No duplicates")

Without LET and without the first-occurrence test: every duplicate row listed as often as it occurs, with a message instead of #CALC! when the list is clean.

Common mistakes

Common mistakes
SymptomCauseFix
TRUE for abc and ABCYou used =A2=B2 to check whether two codes are identical and it says TRUE for abc and ABC.= ignores case. Use EXACT(A2, B2) when the difference between abc and ABC matters.
FALSE for cells that look identicalEXACT returns FALSE for two cells that look identical on screen.Something invisible differs: a trailing space, a non-breaking space, a curly versus straight apostrophe. Compare LEN of both, then CODE of the last character.
#N/A or a wrong row in XLOOKUPYou wrapped a lookup key in EXACT expecting XLOOKUP to become case-sensitive, and got #N/A or a wrong row.EXACT returns TRUE or FALSE, not a value to look up. Look up TRUE instead: XLOOKUP(TRUE, EXACT(A2:A50, E2), B2:B50). The Advanced example shows it.