๐ฏ What You'll Learn
- Explain the role of LET, LAMBDA, and MAP individually and together
- Write a "gold standard" formula that applies tiered logic across an entire column without dragging
- Use multi-array MAP to process two columns simultaneously row-by-row
- Apply the trio to real HR/sales scenarios: commissions, taxes, bonuses, retention risk, and more
- Distinguish when to use this pattern vs. traditional dragged formulas โ and why the modern way wins
๐ Before You Begin
- Basic Excel formula syntax (you can write an
IForSUM) - Familiarity with cell ranges (e.g.
A2:A10) - Excel 365 or Excel 2021 โ
LET,LAMBDA, andMAPare not available in older versions - Understanding of what "spill" means in dynamic array context (bonus, not required)
๐ Contents
The Trinity Explained
Think of building formulas like running a professional kitchen.
LET โ The Prep
Gather your ingredients and name them. Instead of typing 0.15 everywhere, you name it TaxRate once at the top.
MAP โ The Assembly Line
Tells Excel: "Go through this entire pile of data, one row at a time." It handles spilling automatically โ no fill handle needed.
LAMBDA โ The Recipe
The per-row logic. It says: "Take the current row's value, check it, and return X." This is where your IF, AND, OR logic lives.
The shift: This trio moves Excel from "old school" (dragging formulas, messy nested IFs) to modern functional programming โ faster workbooks, readable logic, and zero broken rows.
The Gold Standard Formula
A list of Sales in column A. Commission is 15% if Sales > $10,000, otherwise 10%.
=LET(
HighRate, 0.15, /* name the constant โ change once if rates change */
LowRate, 0.10, /* named for clarity โ no magic numbers */
Threshold, 10000, /* single source of truth for the tier boundary */
MAP(A2:A10, LAMBDA(row, /* MAP iterates; LAMBDA receives each cell as "row" */
IF(row > Threshold,
row * HighRate, /* high-tier branch */
row * LowRate) /* low-tier branch */
))
)
A spilled column of commissions โ one value per sales row, automatically. Change Threshold to 12000 in ONE place โ entire column recalculates instantly.
Breaking It Down
- LET: Defines
HighRate,LowRate, andThresholdonce. If the rate changes, update it in one place โ not in every row. - MAP: Points at
A2:A10and feeds each cell into the LAMBDA, one at a time, then collects all results into a spilled array. - LAMBDA: Creates a temporary variable
rowfor the current cell. Asks "Is this row greater than Threshold?" and returns the correct commission.
Why This Beats the Old Way
| Feature | โ Old School (Drag Formulas) | โ Modern (LET + MAP + LAMBDA) |
|---|---|---|
| Maintenance | Update logic, re-drag the whole column | Change logic in ONE cell โ entire column updates |
| Readability | Hard to know what 0.15 or $B$1 refers to |
HighRate and Threshold make intent obvious |
| Performance | Thousands of individual formulas slow the workbook | One single Dynamic Array calculation โ significantly faster |
| Safety | A user can delete a formula from the middle of a column | Formula lives in one top cell โ rows below cannot be broken |
The Master Dataset
All 10 examples below use this single table: Global Tech Solutions (Range A2:G6).
| A: EmpID | B: Name | C: Dept | D: Sales ($) | E: Region | F: Exp (Yrs) | G: Salary ($) |
|---|---|---|---|---|---|---|
| 101 | Jane Doe | Sales | 15,000 | North | 5 | 5,000 |
| 102 | John Smith | IT | 2,000 | South | 2 | 6,000 |
| 103 | Alice Wong | Sales | 22,000 | North | 8 | 5,500 |
| 104 | Bob Vance | Support | 8,000 | East | 1 | 4,000 |
| 105 | Charlie Day | Sales | 12,000 | West | 12 | 7,000 |
10 Practical Examples
Expand each accordion to see the goal, formula, and output for the master dataset above.
๐ฏ Goal: 15% commission if Sales > $10,000, otherwise 10%.
=LET(High, 0.15, Low, 0.1, Threshold, 10000,
MAP(D2:D6, LAMBDA(s,
IF(s > Threshold, s * High, s * Low)
))
)
2250 (Jane: 15,000 ร 15%) 200 (John: 2,000 ร 10%) 3300 (Alice: 22,000 ร 15%) 800 (Bob: 8,000 ร 10%) 1800 (Charlie: 12,000 ร 15%)
๐ฏ Goal: Categorize staff โ "Elite" (โฅ 20k), "Pro" (โฅ 10k), "Standard" (below 10k).
=LET(Elite, 20000, Pro, 10000,
MAP(D2:D6, LAMBDA(s,
IF(s >= Elite, "Elite",
IF(s >= Pro, "Pro", "Standard"))
))
)
Pro | Standard | Elite | Standard | Pro
๐ฏ Goal: $500 bonus per year of experience โ but ONLY for the Sales department. MAP processes two columns simultaneously.
=LET(BonusPerYear, 500, TargetDept, "Sales",
MAP(C2:C6, F2:F6, LAMBDA(dept, exp, /* two arrays fed in parallel */
IF(dept = TargetDept, exp * BonusPerYear, 0)
))
)
2500 | 0 | 4000 | 0 | 6000
๐ฏ Goal: North/South regions pay 20% tax on salary; all others pay 15%.
=LET(NorthSouthRate, 0.2, StandardRate, 0.15,
MAP(E2:E6, G2:G6, LAMBDA(reg, sal,
IF(OR(reg="North", reg="South"),
sal * NorthSouthRate,
sal * StandardRate)
))
)
1000 | 1200 | 1100 | 600 | 1050
๐ฏ Goal: How many years until 10 years experience? If already there, return "Senior".
=LET(SeniorGoal, 10,
MAP(F2:F6, LAMBDA(e,
IF(e >= SeniorGoal, "Senior",
SeniorGoal - e & " years left") /* & concatenates text + number */
))
)
5 years left | 8 years left | 2 years left | 9 years left | Senior
๐ฏ Goal: Convert "First Last" โ "LAST, First" format. Demonstrates LET nested inside LAMBDA for complex string work.
=MAP(B2:B6, LAMBDA(name,
LET(parts, TEXTSPLIT(name, " "), /* LET inside LAMBDA โ a pro move */
INDEX(parts, 2) & ", " & INDEX(parts, 1)
)
))
Doe, Jane | Smith, John | Wong, Alice | Vance, Bob | Day, Charlie
๐ฏ Goal: Subtract a flat 5% healthcare fee and a 15% tax from each salary.
=LET(HealthFee, 0.05,
MAP(G2:G6, LAMBDA(sal,
sal - (sal * HealthFee) - (sal * 0.15) /* total deductions = 20% */
))
)
4000 | 4800 | 4400 | 3200 | 5600
๐ฏ Goal: Sales รท Salary, rounded to 2 decimals. Return "N/A" if Sales = 0 to avoid division errors.
=MAP(D2:D6, G2:G6, LAMBDA(s, sal,
IF(s = 0, "N/A", /* guard against division by zero */
ROUND(s / sal, 2))
))
3 | 0.33 | 4 | 2 | 1.71
๐ฏ Goal: Flag "High Risk" if an employee has more than 5 years experience but earns less than $6,000.
=LET(ExpMin, 5, SalMax, 6000,
MAP(F2:F6, G2:G6, LAMBDA(e, s,
IF(AND(e > ExpMin, s < SalMax), /* AND requires BOTH conditions true */
"High Risk", "Stable")
))
)
High Risk | Stable | High Risk | Stable | Stable
๐ฏ Goal: 5% raise for Sales department, 3% raise for everyone else.
=LET(SalesRaise, 1.05, StandardRaise, 1.03,
MAP(C2:C6, G2:G6, LAMBDA(dept, sal,
IF(dept = "Sales",
sal * SalesRaise, /* 5% raise for Sales */
sal * StandardRaise) /* 3% raise for all others */
))
)
5250 | 6180 | 5775 | 4120 | 7350
Why This Beats Everything Else
- Single Source of Truth: In Example 1,
10000is defined once asThreshold. Changing it to12000requires a single edit โ not a Find-and-Replace across 500 rows. - Multi-Array Power: Example 3 passes two columns (
C2:C6andF2:F6) into MAP simultaneously โ processed in sync, row by row. Standard array formulas would need messyOFFSETorINDEXworkarounds for this. - Spill Magic: Type the formula once in the top cell. It spills down automatically. No one can accidentally delete a row's formula, because there are no individual row formulas to delete.
๐ Key Takeaways
- Use LET to name constants โ eliminates magic numbers and makes intent readable
- Use MAP to iterate over a range (or multiple ranges in parallel) automatically
- Use LAMBDA to define your per-row logic โ
IF,AND,OR,ROUND, anything goes - You can nest LET inside LAMBDA for complex multi-step row calculations (see Example 6)
- This pattern is ideal for: commissions, tax calculations, labelling, bonuses, risk scoring, and unit conversions
๐ง Practice Quiz
Test your understanding. Select an answer and click Submit.
Q1. Which function defines named constants like HighRate = 0.15 at the top of a formula?
Q2. What does MAP do in =MAP(A2:A10, LAMBDA(row, row*2))?
Q3. In Example 3 (Experience-Based Bonus), what is the key advantage of passing TWO arrays to MAP?
Q4. Why is LAMBDA more powerful than a standard nested IF for row logic?
Q5. In Example 6 (Name Formatting), what is the "pro move" used inside the LAMBDA?