EXACT
GELIJK in Dutch Excel
Compares two texts character by character, including case, and returns TRUE only when they are identical.
Last updated: 13 October 2026
| Row | A | B | C |
|---|---|---|---|
| 1 | Invoice no. in auditfile | Invoice no. in specification | Identical |
| 2 | VRK25-0412a | VRK25-0412a | |
| 3 | VRK25-0413b | VRK25-0413B | FALSE=EXACT(A3, B3)=EXACT(A3; B3) |
| 4 | VRK25-0414 | VRK25-0414 | |
| 5 | INK25-0877a | INK25-0877A | |
| 6 | INK25-0878 | INK25-0878 |
Swipe sideways to see all columns
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)
| Argument | Type | Meaning |
|---|---|---|
text1 | Required | The first text; a cell reference or text in quotes. |
text2 | Required | The 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.
| Row | A | B | C | D |
|---|---|---|---|---|
| 1 | Invoice no. in auditfile | Invoice no. in specification | Identical | |
| 2 | VRK25-0412a | VRK25-0412a | ||
| 3 | VRK25-0413b | VRK25-0413B | FALSE=EXACT(A3, B3)=EXACT(A3; B3) | |
| 4 | VRK25-0414 | VRK25-0414 | ||
| 5 | INK25-0877a | INK25-0877A | ||
| 6 | INK25-0878 | INK25-0878 | ||
| 7 |
Swipe sideways to see all columns
Formula in C3
=EXACT(A3,B3)
=EXACT(A3;B3)
Result: FALSE
Step by step
- Excel reads
A3,VRK25-0413b, andB3,VRK25-0413B. Both are text of 11 characters, so no conversion is needed. - It compares position by position: V, R, K, 2, 5, hyphen, 0, 4, 1 and 3 are identical in both. Ten matches so far.
- Position 11:
binA3againstBinB3. Same letter, different case, and EXACT treats that as a difference. The result is FALSE. C3shows FALSE. Put =A3=B3 in a spare cell and it shows TRUE for the same pair: the = operator does not look at case.- Copy
C3toC2:C6. Rows 2, 4 and 6 give TRUE, row 5 gives FALSE for the same reason as row 3 (aagainstA). 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.
| Row | A | B | C | D | E |
|---|---|---|---|---|---|
| 1 | Entry no. | Relation in aging list | Relation in auditfile | Same | |
| 2 | 25-0501 | D1001 | D1001 | TRUE=EXACT(TRIM(B2), TRIM(C2))=EXACT(TRIM(B2); TRIM(C2)) | |
| 3 | 25-0502 | D1002 | d1002 | ||
| 4 | 25-0503 | C2001 | C2001 | ||
| 5 | 25-0504 | D1003 | d1003 | ||
| 6 | 25-0505 | C2002 | C2002 | ||
| 7 |
Swipe sideways to see all columns
Formula in D2
=EXACT(TRIM(B2),TRIM(C2))
=EXACT(TRIM(B2);TRIM(C2))
Result: TRUE
Step by step
- Excel evaluates the two TRIMs first. TRIM(B2) is
D1001, 5 characters, unchanged. TRIM(C2) takesD1001followed by a space, 6 characters, and removes the trailing space:D1001, 5 characters. - EXACT compares the two cleaned texts position by position. All five characters match, case included.
D2shows TRUE. - Without the TRIMs, EXACT(B2, C2) would compare 5 characters against 6 and return FALSE, flagging a difference that nobody needs to explain.
- Copy
D2down. Row 3:D1002againstd1002, both 5 characters after TRIM, but position 1 isDagainstd, so FALSE. That is a real difference to ask the client about. - Row 5:
D1003againstd1003with 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.
| Row | A | B | C | D | E | F | G |
|---|---|---|---|---|---|---|---|
| 1 | Journal | Entry no. | Amount | Journal | Lines | ||
| 2 | MEM | 25-1101 | €4,500.00€ 4.500,00 | MEM | 33=SUMPRODUCT(--EXACT(A2:A8, E2))=SUMPRODUCT(--EXACT(A2:A8; E2)) | ||
| 3 | mem | 25-1102 | €1,200.00€ 1.200,00 | ||||
| 4 | MEM | 25-1103 | €12,000.00€ 12.000,00 | ||||
| 5 | INK | 25-1104 | €850.00€ 850,00 | ||||
| 6 | Mem | 25-1105 | €300.00€ 300,00 | ||||
| 7 | MEM | 25-1106 | €2,500.00€ 2.500,00 | ||||
| 8 | VRK | 25-1107 | €7,200.00€ 7.200,00 | ||||
| 9 |
Swipe sideways to see all columns
Formula in F2
=SUMPRODUCT(--EXACT(A2:A8,E2))
=SUMPRODUCT(--EXACT(A2:A8;E2))
Result: 33
Step by step
- 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. Excel compares each cell with
MEM:A2MEM: TRUEA3mem: position 1 ismagainstM, FALSEA4MEM: TRUEA5INK:IagainstM, FALSEA6Mem: position 2 iseagainstE, FALSEA7MEM: TRUEA8VRK:VagainstM, FALSE
The array is {TRUE;FALSE;TRUE;FALSE;FALSE;TRUE;FALSE}.
- 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.
- SUMPRODUCT adds the array: 1 + 0 + 1 + 0 + 0 + 1 + 0 = 3.
F2shows 3 manualMEMlines. - =COUNTIF(A2:A8, E2) in a spare cell shows 5: the three
MEMlines, thememline and theMemline, all folded to the same code. That is the count you did not want. - Change
E2tomemandF2becomes 1. Change it toMemandF2also 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.
| Row | A | B | C | D | E |
|---|---|---|---|---|---|
| 1 | Invoice no. | Booking date | Duplicate invoice numbers | ||
| 2 | F25-318a | 28 Nov 2025 | F25-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) ) | ||
| 3 | F25-318A | 28 Nov 2025 | F25-318A | ||
| 4 | KV-2217 | 2 Dec 2025 | KV-2217 | ||
| 5 | F25-318a | 5 Dec 2025 | |||
| 6 | kv-2217 | 5 Dec 2025 | |||
| 7 | KV-2217 | 12 Dec 2025 | |||
| 8 | F25-318A | 19 Dec 2025 | |||
| 9 |
Swipe sideways to see all columns
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
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, onlyA2andA5are exact matches;F25-318AinA3andA8differs in case and does not count. hits is {2;2;2;2;1;2;2}; the 1 iskv-2217in row 5.- 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-318athat is 1, forF25-318Ait is 2, forKV-2217it is 3. firstAt is {1;2;3;1;5;3;2}. - 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}.
- 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.
- The report spills
F25-318a,F25-318AandKV-2217intoD2:D4: three distinct spellings that each occur more than once.kv-2217is absent because that lowercase spelling occurs only once, even thoughKV-2217occurs twice. - Change
A8toG25-007and hits for row 2 becomes 1:F25-318Anow occurs once, drops out, and the report shrinks toF25-318aandKV-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:D4must 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
| Symptom | Cause | Fix |
|---|---|---|
| TRUE for abc and ABC | You 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 identical | EXACT 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 XLOOKUP | You 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. |