Ravindra BagaleCourses & study guides मराठी Track your progress

9. Dynamic Arrays

9.20 Recursive LAMBDA and a Small Reusable Function Library

Example first. Rani receives amounts typed in many styles: "Rs. 1,299/-", "Rs 64", "1,299/-". She wants one function that removes a list of unwanted characters, one character at a time, until nothing is left to remove. A function that calls itself with a smaller job each time is called recursive. In Excel, a LAMBDA can call itself only when it has a name in Name Manager. We will build STRIPCHARS, then collect the functions from this chapter into a small library workbook.

Recursive LAMBDA — in 30 seconds

What: A recursive LAMBDA is a named LAMBDA that calls itself. Each call does one small step and passes a smaller problem to the next call, until a stop condition is reached.

Why: Some jobs are naturally "repeat until done": remove characters one by one, grow a number week by week until it reaches a target. Recursion does this without VBA.

Tiny example: =STRIPCHARS("Rs. 1,299/-","Rs.,/- ") removes R, s, the dot, the comma, the slash, the dash and the space one by one and returns 1299.

First look at the data (before → after):

Recursive LAMBDA: before and after tables, fictional Blinkit Maharashtra data

Expected result — Column B after filling down

A: Typed B: Clean number
Rs. 1,299/- 1299
Rs 64 64
1,299/- 1299
Before table and formula as text

Before — Amounts typed in different styles (A2:A4)

Row A: Typed amount
2 Rs. 1,299/-
3 Rs 64
4 1,299/-

Formula / click path

Name: STRIPCHARS
Refers to: =LAMBDA(text,chars,IF(chars="",TRIM(text),STRIPCHARS(SUBSTITUTE(text,LEFT(chars),""),MID(chars,2,999))))
B2: =VALUE(STRIPCHARS(A2,"Rs.,/- "))   (fill down)

Do it step by step:

  1. Open Formulas › Defined Names › Name Manager and click New….
  2. Type the name STRIPCHARS. Recursion needs the name, because the formula refers to STRIPCHARS inside itself.
  3. In Refers to paste =LAMBDA(text,chars,IF(chars="",TRIM(text),STRIPCHARS(SUBSTITUTE(text,LEFT(chars),""),MID(chars,2,999)))) and click OK.
  4. In B2 type =VALUE(STRIPCHARS(A2,"Rs.,/- ")) and fill down to B4.
  5. Read the stop condition: when chars becomes empty, the function stops calling itself and returns the trimmed text.
  6. Test a bad case on purpose: a function with no stop condition returns #NUM! because Excel limits how deep recursion can go.

Version note

Recursive LAMBDA needs a named LAMBDA (Excel for Microsoft 365 or Excel 2024). Microsoft's LAMBDA page says Excel returns #NUM! when there are too many recursive calls. It does not promise a fixed depth, so keep recursion for small jobs like these.

Tracing STRIPCHARS by hand (this is the best way to understand recursion)

Call text chars What happens
1 Rs. 1,299/- "Rs.,/- " remove "R", call again with the rest of chars
2 s. 1,299/- "s.,/- " remove "s"
3 . 1,299/- ".,/- " remove "."
4 1,299/- ",/- " remove ","
5 1299/- "/- " remove "/"
6 1299- "- " remove "-"
7 1299 " " remove the space
8 1299 "" (empty) stop: return TRIM(text) = 1299

Every recursive function needs two parts:

  1. A stop condition that returns an answer without calling itself: IF(chars="",TRIM(text), …).
  2. A smaller job passed to the next call: MID(chars,2,999) is chars without its first character, so it gets shorter every time and the stop condition is sure to be reached.

Note: SUBSTITUTE is case-sensitive, so "R" removes only the capital R. Be careful with letters: removing "s" also removes every small s in the text. For text with words in it, the REDUCE method from lesson 9.19 or REGEXREPLACE from lesson 9.12 is often safer.

A second example: weeks to reach a target. Pune sells ₹520 thousand a week (fictional). If sales grow 5% a week, after how many weeks do they reach ₹700 thousand?

WEEKSTOTARGET = LAMBDA(sales,target,growth,IF(sales>=target,0,1+WEEKSTOTARGET(sales*(1+growth),target,growth)))

=WEEKSTOTARGET(520,700,5%) returns 7. The sales path is 520.0, 546.0, 573.3, 602.0, 632.1, 663.7, 696.8, 731.7. Check without recursion: =ROUNDUP(LN(700/520)/LN(1.05),0) also gives 7.

Your reusable function library

Make one workbook called My Functions.xlsx with these names (all from this chapter), a Tests sheet with the calls below, and a short note in each name's Comment box:

Name Refers to Test call Expected
LATEFLAG =LAMBDA(mins,[limit],IF(mins>IF(ISOMITTED(limit),15,limit),"Late","On time")) =LATEFLAG(18) Late
WITHGST =LAMBDA(amount,[rate],amount*(1+IF(ISOMITTED(rate),18%,rate))) =WITHGST(500) 590
PCTCHANGE =LAMBDA(old,new,IF(old=0,"",(new-old)/old)) =PCTCHANGE(300,330) 10%
CITYTOTAL =LAMBDA(city,SUMIFS(tblOrders[Amount],tblOrders[City],city)) =CITYTOTAL("Pune") 544
RUNNINGTOTAL =LAMBDA(values,SCAN(0,values,LAMBDA(acc,v,acc+v))) =RUNNINGTOTAL(G2:G4) 64, 334, 444
STRIPCHARS =LAMBDA(text,chars,IF(chars="",TRIM(text),STRIPCHARS(SUBSTITUTE(text,LEFT(chars),""),MID(chars,2,999)))) =STRIPCHARS("Rs. 1,299/-","Rs.,/- ") 1299
WEEKSTOTARGET =LAMBDA(sales,target,growth,IF(sales>=target,0,1+WEEKSTOTARGET(sales*(1+growth),target,growth))) =WEEKSTOTARGET(520,700,5%) 7

CITYTOTAL uses a Table named tblOrders (chapter 6), so it keeps working when rows are added.

How to reuse the library in another workbook

  1. Open My Functions.xlsx and the target workbook.
  2. Right-click the Tests sheet tab › Move or Copy… › choose the target workbook › tick Create a copy › OK.
  3. The names used on that sheet come with it. Check Formulas › Name Manager in the target workbook.
  4. Delete the copied Tests sheet if you do not want it; the names stay.

(Microsoft also offers a free add-in called Excel Labs with an "Advanced formula environment" for writing and importing LAMBDA libraries. It is optional; everything above works with Name Manager alone.)

Common problems

What you see Why Fix
#NAME? inside the recursive call The LAMBDA was typed in a cell, not saved with a name. Recursion only works for named LAMBDAs: save it in Name Manager.
#NUM! Too many recursive calls (often a stop condition that is never reached). Check that each call makes the job smaller.
Wrong letters removed SUBSTITUTE removed every copy of a letter. Remove only symbols, or use REGEXREPLACE with a precise pattern.

How these results were checked: LAMBDA helper functions do not run in LibreOffice, so each expected value was computed in Python and the totals were cross-checked in LibreOffice with classic formulas (SUMIF, running SUM, SUMPRODUCT). Microsoft reference: LAMBDA function.

Practice task (try it before you open the answer):

  1. Create a recursive named LAMBDA REPEATTEXT(text,n) that returns the text n times joined with a space, stopping when n = 1 (for example "Pune Pune Pune").
  2. How many weeks does Nashik need to grow from 330 to 400 at 4% a week? Use WEEKSTOTARGET.
  3. Check your answer to step 2 with ROUNDUP and LN.
Answer
  1. =LAMBDA(text,n,IF(n<=1,text,text&" "&REPEATTEXT(text,n-1))); =REPEATTEXT("Pune",3) returns Pune Pune Pune. (REPT does a similar job without recursion.)
  2. =WEEKSTOTARGET(330,400,4%) returns 5.
  3. =ROUNDUP(LN(400/330)/LN(1.04),0) returns 5.

Ravindra Bagale's Tip

Before you save a recursive LAMBDA, write down its stop condition in one sentence. If you cannot, the function will probably end in #NUM!.