LET
LET in Dutch Excel
Gives a value or an intermediate result a name inside one formula, so you can reuse it by name and Excel calculates it only once.
Last updated: 13 October 2026
| Row | A | B | C | D |
|---|---|---|---|---|
| 1 | Invoice | Net amount | VAT rate | |
| 2 | 25-2041 | €18,250.00€ 18.250,00 | 21%21% | €22,082.50€ 22.082,50=LET(net, B2, vat, net * C2, net + vat)=LET(net; B2; vat; net * C2; net + vat) |
| 3 | 25-2042 | €6,400.00€ 6.400,00 | 9%9% | |
| 4 | 25-2043 | €3,100.00€ 3.100,00 | 21%21% |
Swipe sideways to see all columns
Result: €22,082.50€ 22.082,50
=LET(net,B2, vat, net * C2, net + vat)
=LET(net;B2; vat; net * C2; net + vat)
What LET does and when to use it
What it does: it gives names to parts of a calculation inside one formula, for example the net amount and the VAT of an invoice, and then combines them in a final line.
When to use it: when a formula repeats the same range or sub-calculation, when a reviewer has to read it a month later, or when a slow SUMIFS feeds several places. It replaces helper columns that only hold an intermediate result. For a formula that uses each piece once, names only add length.
Three main gains:
- Calculated once: a slow sub-calculation runs one time, however often you use its name.
- Readable: names such as
netandvattell the reader what each step is. - No helper columns: intermediate results stay inside the formula, so nothing in the sheet can break or be deleted by mistake.
How Excel evaluates it
Excel reads the arguments in pairs from the left. For each pair it calculates the value, using only the names defined earlier, and stores it under the name. When it reaches the last argument, which has no partner, it calculates that expression with all the stored names and returns it as the result of the whole formula.
A few rules about names:
- a name can hold a single value, a range or a whole array; if the final calculation returns an array, the formula spills
- the names disappear when the formula ends
- a LET name overrides a Name Manager name of the same name inside that formula
- you choose the names yourself; Dutch names work too
Watch out: A name that looks like a cell reference, such as INV1, is rejected.
Mental model
A recipe with a mise en place: you weigh and chop everything first and give each bowl a label, then the last line says what to do with the bowls.
Terms used on this page: worksheet, spill, array, argument, range
LET(name1,name_value1, calculation_or_name2, [name_value2], [calculation_or_name3], ...)
LET(name1;name_value1; calculation_or_name2; [name_value2]; [calculation_or_name3]; ...)
| Argument | Type | Meaning |
|---|---|---|
name1 | Required | The name you give the first value. Must start with a letter. |
name_value1 | Required | The value or expression that name1 stands for. |
calculation_or_name2 | Required | The final calculation, or the next name to define. |
name_value2 | Optional | The value bound to the previous name. |
calculation_or_name3 | Optional | The final calculation, or another name; pairs may continue. |
Return value:The result of the last argument, calculated with all the names defined before it
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
Recalculate VAT and gross amount of a sales invoice
You recalculate the VAT on sales invoices of Veldhuis Installatie BV and compare the gross amount with what the customer paid. The net amount and the VAT rate are in each row. The net amount is needed twice, once to work out the VAT and once as the amount the VAT is added to, so you give it a name, and the VAT amount gets a name too so the last step reads as net + vat.
| Row | A | B | C | D | E |
|---|---|---|---|---|---|
| 1 | Invoice | Net amount | VAT rate | ||
| 2 | 25-2041 | €18,250.00€ 18.250,00 | 21%21% | €22,082.50€ 22.082,50=LET(net, B2, vat, net * C2, net + vat)=LET(net; B2; vat; net * C2; net + vat) | |
| 3 | 25-2042 | €6,400.00€ 6.400,00 | 9%9% | ||
| 4 | 25-2043 | €3,100.00€ 3.100,00 | 21%21% | ||
| 5 |
Swipe sideways to see all columns
Formula in D2
=LET(net,B2, vat, net * C2, net + vat)
=LET(net;B2; vat; net * C2; net + vat)
Result: €22,082.50€ 22.082,50
Step by step
- Excel reads the first pair: the name net and its value
B2.B2holds 18,25018.250, so net is now 18,25018.250. - The second pair is vat with the value net * C2. Excel replaces net by its stored 18,25018.250 and reads
C2, which is 21%: 18,25018.250 × 0.21 = 3,832.503.832,50. vat is now 3,832.503.832,50. - The last argument, net + vat, has no partner, so it is the result: 18,25018.250 + 3,832.503.832,50 = 22,082.5022.082,50.
- Copy
D2down.D3becomes 6,4006.400 + (6,4006.400 × 0.09 = 576) = 6,9766.976 andD4becomes 3,1003.100 + (3,1003.100 × 0.21 = 651) = 3,7513.751, because net and vat are worked out again for each row.
Watch out: A formula that ends on a pair, such as =LET(net, B2, vat, net * C2), has no calculation to return and Excel rejects it. Always finish with the expression you want to see.
More on this example: why it works, 1 variation
Why it works
Each name is a label on a stored value, and later pairs can read the labels of earlier pairs. The last argument is the only one that is not a pair, which is how Excel knows it is the answer.
Variations
=B2 * (1 + C2)
=B2 * (1 + C2)
For this single calculation the plain formula is shorter; LET starts to pay off when a piece is used more than once or needs a label for the reader.
Intermediate
Flag ledger differences above a percentage threshold
You reconcile three ledger balances of Veldhuis Installatie BV to the client's specifications. For each account you work out the difference and its share of the specification, and flag the account when that share is above the threshold in G1.
The share gets its own step and a name next to the difference, so the test reads as share compared with the threshold. One difference is negative, because the ledger is lower than the specification.
| Row | A | B | C | D | E | F | G | H |
|---|---|---|---|---|---|---|---|---|
| 1 | Account | Ledger | Specification | Threshold | 0.5%0,5% | |||
| 2 | 13001300 | €482,615.40€ 482.615,40 | €480,115.40€ 480.115,40 | Investigate=LET(diff, B2 - C2, share, diff / C2, IF(share > $G$1, "Investigate", "Within threshold"))=LET(diff; B2 - C2; share; diff / C2; IF(share > $G$1; "Investigate"; "Within threshold")) | ||||
| 3 | 16001600 | €215,840.00€ 215.840,00 | €215,840.00€ 215.840,00 | |||||
| 4 | 40004000 | €94,250.00€ 94.250,00 | €94,300.00€ 94.300,00 | |||||
| 5 |
Swipe sideways to see all columns
Formula in D2
=LET(diff,B2 - C2, share, diff / C2, IF(share > $G$1, "Investigate", "Within threshold"))
=LET(diff;B2 - C2; share; diff / C2; IF(share > $G$1; "Investigate"; "Within threshold"))
Result: Investigate
Step by step
- The first pair names the difference: diff = B2 - C2 = 482,615.40482.615,40 - 480,115.40480.115,40 = 2,500.002.500,00.
- The second pair uses diff: share = diff / C2 = 2,5002.500 / 480,115.40480.115,40 = 0.005207, which is 0.52%.
- The last argument is IF. Excel reads
G1(0.5%) and tests 0.52% > 0.5%: TRUE. IF returnsInvestigate. - Copied to
D3the difference is 215,840215.840 - 215,840215.840 = 0 and the share 0, so IF returnsWithin threshold. InD4the difference is 94,25094.250 - 94,30094.300 = -50 and the share -50 / 94,30094.300 = -0.053%; that is not above 0.5% either, so the answer isWithin threshold. - Without LET you would write (B2 - C2) / C2 in the test and again anywhere else the share is needed. With the name, a change in how the share is defined is made in one place.
Watch out: Ledger lower than the specification gives a negative share, and a negative share is never above 0.5%, so a large shortfall such as -20,00020.000 passes as Within threshold. Test the absolute value to catch both directions.
More on this example: why it works, 1 more pitfall, 1 variation
Why it works
The names turn the formula into three readable lines: the difference, the share, and the decision. IF is the only other function, and it sees share as one stored number, not as a calculation it has to repeat.
More to watch out for
- A specification balance of 0 makes diff / C2 a #DIV/0! error. Decide up front how a zero balance should be treated.
Variations
=LET(diff,B2 - C2, share, ABS(diff) / C2, IF(share > $G$1, "Investigate", "Within threshold"))
=LET(diff;B2 - C2; share; ABS(diff) / C2; IF(share > $G$1; "Investigate"; "Within threshold"))
Use ABS on the share so shortfalls and excesses are both flagged.
Advanced
Find purchase invoices booked twice
In the purchase journal of Veldhuis Installatie BV you look for invoices booked twice, as a duplicate means a possible double payment. The same invoice number may legitimately come from two different suppliers, so a duplicate is the same invoice number from the same supplier. You want the duplicate lines on a list.
| Row | A | B | C | D | E | F | G | H |
|---|---|---|---|---|---|---|---|---|
| 1 | Invoice | Supplier | Amount | |||||
| 2 | INV-3301 | Bakker Staal BV | €4,235.00€ 4.235,00 | INV-3302=LET(invoice, A2:A8, supplier, B2:B8, FILTER(A2:C8, COUNTIFS(invoice, invoice, supplier, supplier) > 1, "No duplicates"))=LET(invoice; A2:A8; supplier; B2:B8; FILTER(A2:C8; COUNTIFS(invoice; invoice; supplier; supplier) > 1; "No duplicates")) | Jansen Logistiek BV | €1,512.50€ 1.512,50 | ||
| 3 | INV-3302 | Jansen Logistiek BV | €1,512.50€ 1.512,50 | INV-3303 | Bakker Staal BV | €7,260.00€ 7.260,00 | ||
| 4 | INV-3301 | Hofman Kantoor BV | €980.00€ 980,00 | INV-3302 | Jansen Logistiek BV | €1,512.50€ 1.512,50 | ||
| 5 | INV-3303 | Bakker Staal BV | €7,260.00€ 7.260,00 | INV-3303 | Bakker Staal BV | €7,260.00€ 7.260,00 | ||
| 6 | INV-3302 | Jansen Logistiek BV | €1,512.50€ 1.512,50 | |||||
| 7 | INV-3304 | De Wit Schoonmaak BV | €640.20€ 640,20 | |||||
| 8 | INV-3303 | Bakker Staal BV | €7,260.00€ 7.260,00 | |||||
| 9 |
Swipe sideways to see all columns
Formula in E2
=LET(invoice,A2:A8, supplier, B2:B8, FILTER(A2:C8, COUNTIFS(invoice, invoice, supplier, supplier) > 1, "No duplicates"))
=LET(invoice;A2:A8; supplier; B2:B8; FILTER(A2:C8; COUNTIFS(invoice; invoice; supplier; supplier) > 1; "No duplicates"))
Result: INV-3302 | Jansen Logistiek BV | €1,512.50 / INV-3303 | Bakker Staal BV | €7,260.00 / INV-3302 | Jansen Logistiek BV | €1,512.50 / INV-3303 | Bakker Staal BV | €7,260.00INV-3302 | Jansen Logistiek BV | € 1.512,50 / INV-3303 | Bakker Staal BV | € 7.260,00 / INV-3302 | Jansen Logistiek BV | € 1.512,50 / INV-3303 | Bakker Staal BV | € 7.260,00
Step by step
- The first two pairs store ranges: invoice is
A2:A8and supplier isB2:B8. No values are calculated yet; the names are labels on the two ranges. - The final FILTER starts with its include argument. COUNTIFS(invoice, invoice, supplier, supplier) counts, for each of the 7 rows, how many rows share both the invoice number and the supplier: 1, 2, 1, 2, 2, 1, 2. The third entry (row 4,
INV-3301from Hofman Kantoor BV) counts only itself, because the otherINV-3301is from Bakker Staal BV. - Comparing with > 1 gives FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE.
- FILTER keeps the 2nd, 4th, 5th and 7th row of
A2:C8in source order:INV-3302(1,512.501.512,50),INV-3303(7,260.007.260,00),INV-3302(1,512.501.512,50) andINV-3303(7,260.007.260,00). - The block of 4 rows by 3 columns spills from
E2toG5. Delete the secondINV-3302and the secondINV-3303from the source and FILTER finds no row above 1, soE2showsNo duplicates.
Watch out: Testing the invoice number alone, COUNTIF(invoice, invoice) > 1, silently adds INV-3301 twice, because two different suppliers used the same number. The list looks plausible but 2 of its lines are not duplicates.
More on this example: why it works, 2 more pitfalls, 1 variation
Why it works
invoice and supplier are each used twice inside COUNTIFS, once as the range to look in and once as the criteria to look for. Passing a whole range as criteria makes COUNTIFS return one count per row, which is exactly the array FILTER needs.
More to watch out for
- Both invoice rows are returned, including the first booking. If you need only the later booking, the first one has to be left out with a different test.
- A supplier typed as 'Bakker Staal BV ' with a trailing space counts as a different supplier and hides a real duplicate. Run TRIM over the supplier column first.
Variations
=FILTER(A2:C8,COUNTIFS(A2:A8, A2:A8, B2:B8, B2:B8) > 1, "No duplicates")
=FILTER(A2:C8;COUNTIFS(A2:A8; A2:A8; B2:B8; B2:B8) > 1; "No duplicates")
Without LET: the same result, but both ranges are written twice. Fine for two ranges; with four or five conditions the names keep it readable.
Master
Allowance for doubtful debts from aging bands in one formula
You test the allowance for doubtful debts at Veldhuis Installatie BV at the balance date of 31 December 2025. The client applies these percentages:
- 0% to invoices not yet due
- 1% up to 30 days overdue
- 5% for 31 to 60 days
- 20% for 61 to 90 days
- 50% above 90 days
You recalculate the total allowance to compare with the booked amount. The formula must be readable for the reviewer and let you check each step.
| Row | A | B | C | D | E | F | G |
|---|---|---|---|---|---|---|---|
| 1 | Invoice | Open amount | Due date | Balance date | 31 Dec 2025 | ||
| 2 | 25-1101 | €12,000.00€ 12.000,00 | 15 Dec 2025 | ||||
| 3 | 25-1102 | €8,500.00€ 8.500,00 | 20 Nov 2025 | Allowance | €16,787.50€ 16.787,50=LET( balance_date, F1, open_amount, B2:B8, due_date, C2:C8, days_over, balance_date - due_date, rate, IF(days_over > 90, 0.5, IF(days_over > 60, 0.2, IF(days_over > 30, 0.05, IF(days_over > 0, 0.01, 0)))), allowance, open_amount * rate, ROUND(SUM(allowance), 2) )=LET( balance_date; F1; open_amount; B2:B8; due_date; C2:C8; days_over; balance_date - due_date; rate; IF(days_over > 90; 0,5; IF(days_over > 60; 0,2; IF(days_over > 30; 0,05; IF(days_over > 0; 0,01; 0)))); allowance; open_amount * rate; ROUND(SUM(allowance); 2) ) | ||
| 4 | 25-1103 | €15,000.00€ 15.000,00 | 25 Oct 2025 | ||||
| 5 | 25-1104 | €6,400.00€ 6.400,00 | 1 Sep 2025 | ||||
| 6 | 25-1105 | €9,800.00€ 9.800,00 | 14 Jan 2026 | ||||
| 7 | 25-1106 | €4,250.00€ 4.250,00 | 1 Dec 2025 | ||||
| 8 | 25-1107 | €20,000.00€ 20.000,00 | 31 Jul 2025 | ||||
| 9 |
Swipe sideways to see all columns
Formula in F3
=LET( balance_date,F1, open_amount, B2:B8, due_date, C2:C8, days_over, balance_date - due_date, rate, IF(days_over > 90, 0.5, IF(days_over > 60, 0.2, IF(days_over > 30, 0.05, IF(days_over > 0, 0.01, 0)))), allowance, open_amount * rate, ROUND(SUM(allowance), 2) )
=LET( balance_date;F1; open_amount; B2:B8; due_date; C2:C8; days_over; balance_date - due_date; rate; IF(days_over > 90; 0,5; IF(days_over > 60; 0,2; IF(days_over > 30; 0,05; IF(days_over > 0; 0,01; 0)))); allowance; open_amount * rate; ROUND(SUM(allowance); 2) )
Result: €16,787.50€ 16.787,50
Step by step
- The first three pairs store inputs: balance_date is 31 Dec 2025, open_amount is
B2:B8and due_date isC2:C8. Nothing is calculated yet. - days_over subtracts each due date from the balance date: 16, 41, 67, 121, -14, 30, 153 days. The negative -14 is invoice
25-1105, which falls due on 14 Jan 2026 and is not overdue yet. - rate maps each number of days to a percentage with nested IFs: 0.01, 0.05, 0.2, 0.5, 0, 0.01, 0.5. Invoice
25-1106is exactly 30 days overdue, and 30 > 30 is FALSE, so it stays in the 1% band. - allowance multiplies amounts by rates, row by row: 12,00012.000 × 0.01 = 120; 8,5008.500 × 0.05 = 425; 15,00015.000 × 0.2 = 3,0003.000; 6,4006.400 × 0.5 = 3,2003.200; 9,8009.800 × 0 = 0; 4,2504.250 × 0.01 = 42.50; 20,00020.000 × 0.5 = 10,00010.000.
- The last argument adds them: 120 + 425 + 3,0003.000 + 3,2003.200 + 0 + 42.50 + 10,00010.000 = 16,787.5016.787,50. ROUND to 2 decimals leaves 16,787.5016.787,50 in
F3. - Debugging tip: replace the last argument by days_over, rate or allowance and the formula spills that stage so you can check it row by row against the aging list. Put the final calculation back when you are done.
Watch out: The mirror-image mistake is using >= where the band says 'up to 30 days'. With days_over >= 30 invoice 25-1106 moves to the 5% band: 4,2504.250 × 0.05 = 212.50 instead of 42.50, and the total becomes 16,957.5016.957,50. The result still looks reasonable.
More on this example: why it works, 2 more pitfalls, 1 variation
Why it works
Every name holds a whole array, so rate and allowance are calculated for all 7 invoices at once and each is calculated once, however often it is read later.
Do not use this construction for a one-off sum, or when the rates live in a table the client keeps updating: a rate table with a helper column and SUMPRODUCT is simpler to maintain, because the percentages sit in cells and not inside the formula.
More to watch out for
- Leaving out the last IF level (days_over > 0) gives 1% to invoices that are not yet due: 9,8009.800 × 0.01 = 98 extra. Keep the not-yet-due case explicit.
- A due date stored as text, such as '2025-12-15' typed with a leading apostrophe, can give a #VALUE! error or a wrong number of days in days_over, depending on the regional settings. Check one cell with ISNUMBER before you blame the formula.
Variations
=LET( balance_date,F1, open_amount, B2:B8, due_date, C2:C8, days_over, balance_date - due_date, rate, IF(days_over > 90, 0.5, IF(days_over > 60, 0.2, IF(days_over > 30, 0.05, IF(days_over > 0, 0.01, 0)))), rate )
=LET( balance_date;F1; open_amount; B2:B8; due_date; C2:C8; days_over; balance_date - due_date; rate; IF(days_over > 90; 0,5; IF(days_over > 60; 0,2; IF(days_over > 30; 0,05; IF(days_over > 0; 0,01; 0)))); rate )
Debugging version: the last argument returns the rate array, so you can see the band chosen for each invoice.
Common mistakes
| Symptom | Cause | Fix |
|---|---|---|
| #NAME? for a name like inv1 or tax2 | Excel answers #NAME? or refuses the formula after you typed a name such as inv1 or tax2. | A column from A to XFD followed by digits reads as a cell address and cannot be a name. Use invoice1, inv_1 or a descriptive word. |
| Formula rejected: no final calculation | The formula is rejected because it ends with a name and its value, with no final calculation. | The argument count must be odd: pairs, plus one last calculation. After the last pair, write the expression that should be returned, or the name you want to see. |
| #NAME? on a correctly spelled name | A name returns #NAME? even though it is spelled right: it is used in a pair that comes before its own definition. | Names only see the names to their left. Reorder the pairs so every value is defined before the pair that uses it. |
| #NAME? in another cell | You try to use a name from one cell's LET in another cell and get #NAME?. | LET names live only inside their own formula. For a value shared across the workbook, create a named range in Name Manager, or wrap the logic in a LAMBDA. |
Used in combinations
- Differences above the reporting threshold with LET, FILTER, HSTACK and ABSReconcile the ledger to the client's specification per customer and list only the differences above the reporting threshold: LET names the differences once, HSTACK pairs them with the customer, FILTER keeps the rows where ABS exceeds the threshold.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)
- Journal entries where debit does not equal creditList the entries whose debit and credit totals differ: take the unique entry numbers, total debit and credit per entry with SUMIFS, and keep the unequal ones with FILTER over HSTACK, all named in one LET.Excel 2024 or later (This combination needs Excel 2024 or later)