Excel Dynamic Arrays LAMBDA LET Intermediate

BYROW + LAMBDA + LET

Write clean, professional-grade dynamic array formulas that treat each row like a tiny script — readable, scalable, and impossible to break.

🕐 ~20 min read 📊 12 formula examples ⚡ Intermediate 🧪 Quiz included
✦ What You'll Learn
📋 Prerequisites
1

Why This Pattern Exists

Beginner ⏱ 3 min

In traditional Excel, if you want to calculate Price × Qty for every row, you write =B2*C2 in one cell, then drag the formula down 500 rows. Three months later, someone edits row 47 and breaks the whole column.

The BYROW + LAMBDA + LET pattern solves this with a single formula that governs the entire column.

Old Excel (per-cell formulas)
=B2*C2      ← Row 2
=B3*C3      ← Row 3 (drag-copied)
=B4*C4      ← Row 4 (drag-copied)
... repeat 500 times ...
← ONE typo breaks the whole column
New Way (single formula, whole column)
=BYROW(C2:D5, LAMBDA(r,
  LET(
    Price, INDEX(r,1,1),
    Qty,   INDEX(r,1,2),
    Price * Qty
  )
))
{ 6000; 1250; 3000; 1600 } — one result per row, automatically
💡 Aha! This formula lives in exactly one cell. It fills the results downward automatically. You can never accidentally edit "row 47" — there is no row 47 formula.
2

The 3 Building Blocks

Beginner ⏱ 4 min

BYROW(range, function)

Loops over your data one row at a time. You tell it what range to loop over, and what to do on each row. Think of it as a "for each row" instruction.

LAMBDA(r, ...)

Gives the current row a name — in this pattern, we call it r. Now instead of saying "B3" you can say "the first column of r". It also lets you package the logic so BYROW can call it once per row.

LET(A, value, B, value, result)

Assigns readable names to columns inside your row. Instead of writing INDEX(r,1,1)*INDEX(r,1,2), you write Price*Qty. The last value you list is what gets displayed in the cell.

3

The Master Pattern (Blueprint)

Intermediate ⏱ 3 min

Every formula in this tutorial follows this exact structure. Memorise the shape — swap in your range, column names, and logic.

=BYROW(Range, LAMBDA(r, LET( A, INDEX(r,1,1), B, INDEX(r,1,2), C, [Your Logic], C )))

BYROW — loops row by row
Range — your data table
LAMBDA — names the current row "r"
LET — assigns readable names
A, B — your column variables
C — the result (always listed last)
💡 Pro Tip: You can name variables anything! LET(Price, INDEX(r,1,1), Qty, INDEX(r,1,2), Price * Qty) is perfectly valid — and even easier to read.
4

The Master Data Table

Beginner ⏱ 2 min

All 12 examples below use this table (Range B2:E5). Set it up in your spreadsheet to follow along.

RowB — ProductC — PriceD — QtyE — Discount
2Laptop12005100
3Mouse25500
4Monitor3001020
5Keyboard80205
⚠️ Column Counting Rule: When you select C2:E5, INDEX(r,1,1) = Price (col C). When you select B2:E5, INDEX(r,1,1) = Product name (col B). Always count from the left of your highlight.
5

12 Formula Examples

Intermediate ⏱ 8 min

Click any example to expand the full formula and what it calculates. Paste into a cell — the C at the end of each LET is your display value.

Goal: Calculate the raw total revenue per product (before discounts).

Example 1 — Gross Total
=BYROW(C2:D5, LAMBDA(r, LET(
  A, INDEX(r,1,1),  ← Price
  B, INDEX(r,1,2),  ← Qty
  C, A * B,         ← Price × Qty
  C
)))
{ 6000; 1250; 3000; 1600 }

Goal: Subtract the per-product discount from gross total.

Example 2 — Net Revenue
=BYROW(C2:E5, LAMBDA(r, LET(
  A, INDEX(r,1,1)*INDEX(r,1,2),  ← Total
  B, INDEX(r,1,3),              ← Discount
  C, A - B,
  C
)))
{ 5900; 1250; 2980; 1595 }

Goal: Find the effective per-unit cost after applying the discount to price.

Example 3 — Unit Cost
=BYROW(C2:E5, LAMBDA(r, LET(
  A, INDEX(r,1,1),  ← Price
  B, INDEX(r,1,3),  ← Discount
  C, A - B,
  C
)))
{ 1100; 25; 280; 75 }

Goal: Calculate the 7% tax amount for each line item.

Example 4 — Sales Tax
=BYROW(C2:D5, LAMBDA(r, LET(
  A, INDEX(r,1,1)*INDEX(r,1,2),  ← Gross Total
  B, 0.07,                        ← Tax rate (hardcoded)
  C, A * B,
  C
)))
{ 420; 87.5; 210; 112 }

Goal: Label each order "Bulk" if quantity exceeds 15, otherwise "Small".

Example 5 — Bulk Status
=BYROW(D2:D5, LAMBDA(r, LET(
  A, INDEX(r,1,1),  ← Qty
  B, 15,              ← Threshold
  C, IF(A > B, "Bulk", "Small"),
  C
)))
{ "Small"; "Bulk"; "Small"; "Bulk" }

Goal: Apply a 10% price markup, then subtract the discount — a realistic retail pricing formula.

Example 6 — Final Price
=BYROW(C2:E5, LAMBDA(r, LET(
  A, INDEX(r,1,1)*1.1,  ← Price + 10%
  B, INDEX(r,1,3),       ← Discount
  C, A - B,
  C
)))
{ 1220; 27.5; 310; 83 }

Goal: Confirm the average price-per-unit (should equal Price — useful as a sanity check).

Example 7 — Avg Per Item
=BYROW(C2:D5, LAMBDA(r, LET(
  A, INDEX(r,1,1),  ← Price
  B, INDEX(r,1,2),  ← Qty
  C, (A*B)/B,        ← = A (sanity check)
  C
)))
{ 1200; 25; 300; 80 } — equals Price column ✓

Goal: Create a compact product-price label using the first 3 letters of the name.

Example 8 — Short Label
=BYROW(B2:C5, LAMBDA(r, LET(
  A, INDEX(r,1,1),  ← Product name
  B, INDEX(r,1,2),  ← Price
  C, LEFT(A,3) & "-" & B,
  C
)))
{ "Lap-1200"; "Mou-25"; "Mon-300"; "Key-80" }

Goal: Flag any product with 10 or fewer units as needing reorder.

Example 9 — Stock Alert
=BYROW(D2:D5, LAMBDA(r, LET(
  A, INDEX(r,1,1),  ← Qty
  B, 10,              ← Threshold
  C, IF(A <= B, "REORDER", "OK"),
  C
)))
{ "REORDER"; "OK"; "REORDER"; "OK" }

Goal: Calculate what percentage of the price the discount represents.

Example 10 — Margin %
=BYROW(C2:E5, LAMBDA(r, LET(
  A, INDEX(r,1,1),  ← Price
  B, INDEX(r,1,3),  ← Discount
  C, B / A,          ← Discount ÷ Price
  C
)))
{ 8.3%; 0%; 6.7%; 6.25% } — format as % in Excel

Goal: Generate a quick promo code by concatenating the name with a year.

Example 11 — Promo Code
=BYROW(B2:B5, LAMBDA(r, LET(
  A, INDEX(r,1,1),  ← Product name
  B, "2024",          ← Year suffix
  C, A & B,
  C
)))
{ "Laptop2024"; "Mouse2024"; "Monitor2024"; "Keyboard2024" }

Goal: Flag products whose discount exceeds 10% of the unit price for review.

Example 12 — Logic Test / Audit Flag
=BYROW(C2:E5, LAMBDA(r, LET(
  A, INDEX(r,1,1),  ← Price
  B, INDEX(r,1,3),  ← Discount
  C, IF(B > (A*0.1), "High Disc", "-"),
  C
)))
{ "High Disc"; "-"; "-"; "-" } — Laptop flagged (100 > 120)
6

Write Your Own — 4-Step Method

Intermediate ⏱ 3 min

Define your Map

Decide which columns you need. If you need Price (col B) and Qty (col C), your BYROW range is B2:C100. Only include the columns you'll use.

Assign your Variables (LET)

Name each column inside LET. Column 1 of your range → INDEX(r,1,1). Column 2 → INDEX(r,1,2). Use descriptive names like Price, Qty.

Write the Logic (C)

Use your variable names to write the math or logic just like you would on paper: Price * Qty, IF(Qty > 10, "Bulk", "Small"), etc.

End with the Display Variable

The very last item in your LET must be the name of the result you want to see. In our examples that's always C. Don't forget this — it's the most common mistake.

7

The 3 Rules of Success

Beginner ⏱ 2 min
🎯

Selection Matters

INDEX(r,1,1) always means the first column of your highlighted range. Select C2:E5 → col 1 is Price. Select B2:E5 → col 1 is Product.

🏷️

Define Names First

Always assign A and B (or better: Price, Qty) at the top of your LET. Keep the math part clean and readable.

📺

The Display Variable

The very last word in your formula must be the variable you want to show in the cell. It's usually C in these examples. Forgetting this returns the wrong value.

8

Test Your Understanding

Intermediate ⏱ 5 min

🧪 Apply What You've Learned

1. You highlight the range D2:F10 in your BYROW formula. What does INDEX(r,1,2) refer to?

2. A colleague's formula returns all zeros. You notice it ends with LET(A, ..., B, ..., C, A*B) — the last item is the logic expression, not a variable name. What's wrong?

3. You want a formula that applies a "Bulk" discount of 20% if quantity exceeds 50, otherwise charges full price. Which pattern fits best?

4. Your product table just grew from 100 rows to 5,000 rows. What do you need to change in your BYROW formula?