Business Professionals
Power BI | Power Pivot | Power Query | DAX
Cloud Flows | RPA | AI Builder | Copilot
60+ Formulas | Data Stories | Advanced Reporting & Modeling
VB Programming | Report Automation |
MS-Office Automation
Techno-Business Professionals
Power BI | Power Query | Advanced DAX | SQL - Query &
Programming
Microsoft Fabric | Power BI | Power Query | Advanced DAX |
SQL - Query & Programming
Power BI | Power Apps | Power Automate | Copilot Studio | Power Pages | Dataverse
Microsoft Power Apps | Microsoft Power Automate
Power BI | Adv. DAX | SQL (Query & Programming) |
VBA | Python | Web Scrapping | API Integration
Power BI | Power Apps | Power Automate |
SQL (Query & Programming)
Power BI | Adv. DAX | Power Apps | Power Automate |
SQL (Query & Programming) | VBA | Python | Web Scrapping | API Integration
Power Apps | Power Automate | SQL | VBA | Python |
Web Scraping | RPA | API Integration
Technology Professionals
Power BI | DAX | SQL | ETL with SSIS | SSAS | VBA | Python
Power BI | SQL | Azure Data Lake | Synapse Analytics |
Data Factory | Databricks | Power Apps | Power Automate |
Azure Analysis Services
Microsoft Fabric | Power BI | SQL | Lakehouse |
Data Factory (Pipelines) | Dataflows Gen2 | KQL | Delta Tables | Power Apps | Power Automate
Power BI | Power Apps | Power Automate | SQL | VBA | Python | API Integration
Power BI | Advanced DAX | Databricks | SQL | Lakehouse Architecture
Business Professionals
Power BI | Power Pivot | Power Query | DAX
Cloud Flows | RPA | AI Builder | Copilot
60+ Formulas | Data Stories | Advanced Reporting & Modeling
VB Programming | Report Automation |
MS-Office Automation
Techno-Business Professionals
Power BI | Power Query | Advanced DAX | SQL - Query &
Programming
Microsoft Fabric | Power BI | Power Query | Advanced DAX |
SQL - Query & Programming
Power BI | Power Apps | Power Automate | Copilot Studio | Power Pages | Dataverse
Microsoft Power Apps | Microsoft Power Automate
Power BI | Adv. DAX | SQL (Query & Programming) |
VBA | Web Scrapping | API Integration
Power BI | Power Apps | Power Automate |
SQL (Query & Programming)
Power BI | Adv. DAX | Power Apps | Power Automate |
SQL (Query & Programming) | VBA | Web Scrapping | API Integration
Power Apps | Power Automate | SQL | VBA |
Web Scraping | RPA | API Integration
Technology Professionals
Power BI | DAX | SQL | ETL with SSIS | SSAS | VBA
Power BI | SQL | Azure Data Lake | Synapse Analytics |
Data Factory | Azure Analysis Services
Microsoft Fabric | Power BI | SQL | Lakehouse |
Data Factory (Pipelines) | Dataflows Gen2 | KQL | Delta Tables
Power BI | Power Apps | Power Automate | SQL | VBA | API Integration
Power BI | Advanced DAX | Databricks | SQL | Lakehouse Architecture
If your workbooks feel sluggish or randomly recalc for no obvious reason, volatile formulas are usually involved. This guide shows how to replace volatile OFFSET and INDIRECT with stable INDEX and XMATCH patterns so your Excel models stay fast, predictable, and easier to audit.
We’ll walk through concrete refactors you can apply today, and when you’re ready to systematise this across all your files, it’s worth investing in stronger formula modelling habits through something like a focused advanced Excel reporting workflow.
Volatile functions recalculate whenever anything changes in the workbook, not just when their precedents change.
Key volatile functions include:
OFFSETINDIRECTTODAY, NOW, RAND, RANDBETWEENCELL, INFO, AREASIn large models, this means:
OFFSET and INDIRECT are the usual suspects when a model is both “clever” and painfully slow.
You often use OFFSET or INDIRECT for two reasons:
INDEX and XMATCH can handle both, without volatility:
INDEX returns a reference to a cell or range.XMATCH finds positions (like MATCH, but more powerful and easier to read).Together, they give you:
Typical OFFSET pattern (sum last 12 months):
=SUM(OFFSET(B2,COUNTA(B:B)-12,0,12,1))
Issues:
OFFSET.COUNTA(B:B) over a whole column.INDEX-based alternative:
Assume dates or values in B2:B1000, no blanks in the middle.
=LET(
rng, B2:B1000,
lastRow, MATCH(9.99999999999999E+307,rng),
SUM(INDEX(rng,lastRow-11):INDEX(rng,lastRow))
)
Explanation:
MATCH(9.9999E+307,rng) finds the last numeric value.INDEX(rng,lastRow-11) and INDEX(rng,lastRow) return start and end cells.: between them builds a standard range – non-volatile.If you don’t have LET, you can inline the logic:
=SUM(INDEX(B2:B1000,MATCH(9.99999999999999E+307,B2:B1000)-11):
INDEX(B2:B1000,MATCH(9.99999999999999E+307,B2:B1000)))
OFFSET version (sum from B2 down N rows):
=SUM(OFFSET(B2,0,0,$E$1,1))
Where E1 holds the number of rows.
INDEX version:
=SUM(B2:INDEX(B:B,ROW(B2)-1+$E$1))
Explanation:
ROW(B2)-1+$E$1 gives the ending row number.INDEX(B:B, … ) returns the bottom cell.B2:that_cell is entirely non-volatile.OFFSET version (get a cell r rows down and c columns right from B2):
=OFFSET($B$2,$E$1,$F$1)
INDEX version:
=INDEX($B$2:$Z$100, $E$1+1, $F$1+1)
Why +1?
E1=0, we want the first row of the block starting at B2, which is row 1 within B2:Z100.This is faster and explicit: you see the whole area (B2:Z100) instead of an opaque OFFSET.
INDIRECT turns text into a reference. That’s powerful, but:
INDIRECT version:
=SUM(INDIRECT("Sales!" & $B$1 & "2:" & $B$1 & "100"))
Where B1 contains a column letter like "D".
INDEX/XMATCH version – no column letters, just headers:
=LET(
hdrs, Sales!$A$1:$Z$1,
data, Sales!$A$2:$Z$100,
colPos, XMATCH($B$1, hdrs),
SUM(INDEX(data,,colPos))
)
Benefits:
XMATCH finds the correct column position.INDEX(data,,colPos) returns the whole column as a range.Without LET:
=SUM(INDEX(Sales!$A$2:$Z$100,, XMATCH($B$1, Sales!$A$1:$Z$1)))
This is the one use case where INDIRECT seems unavoidable:
=SUM(INDIRECT($A$1 & "!B2:B100"))
Where A1 contains the sheet name.
There is no non-volatile formula that directly swaps sheet names. Instead, consider these design alternatives:
FILTER/SUMIFS instead of jumping across sheets.Example with consolidated table tblData:
Scenario, Month, AmountA1 holds the selected scenario.=SUMIFS(tblData[Amount], tblData[Scenario], $A$1)
This replaces the need to point to different sheets and is more robust for reporting and Power BI.
INDIRECT version:
=SUM(INDIRECT($B$1))
Where B1 contains the name of a named range.
Better pattern: avoid storing names as text; store the range directly.
Example using CHOOSE to map options to ranges:
B1 contains an index: 1 = Sales, 2 = Costs, 3 = Margin.=LET(
choice, $B$1,
rng, CHOOSE(choice, SalesRange, CostsRange, MarginRange),
SUM(rng)
)
You’ve removed INDIRECT entirely, and Excel can now trace the precedent ranges properly.
Instead of INDEX(MATCH(),MATCH()) with manual ranges, use named ranges and XMATCH.
Assume:
hdrs = header rowkeys = key columndata = full data block=LET(
r, XMATCH($A$2, keys),
c, XMATCH($B$2, hdrs),
INDEX(data, r, c)
)
This replaces many INDIRECT-based constructions used to simulate dynamic tables.
If you’re on 365, you can spill the last N values without OFFSET:
=LET(
rng, B2:B1000,
n, $E$1,
lastRow, XMATCH(9.99999999999999E+307, rng),
startRow, MAX(1, lastRow - n + 1),
INDEX(rng, SEQUENCE(n,1,startRow))
)
SEQUENCE generates the row offsets.INDEX returns a spilled array of the last n values.Again, no volatile functions involved.
You don’t have to refactor everything at once. Prioritise the worst offenders.
Find volatile formulas
Formulas → Name Manager to inspect named ranges using OFFSET/INDIRECT.Find & Select → Find for OFFSET( and INDIRECT(.Start with named ranges
OFFSET-based names with INDEX-based definitions.Refactor repeated patterns
Test with manual calculation
Formulas → Calculation Options → Manual.F9 and watch calculation time before/after refactors.Document the patterns
INDEX/XMATCH patterns.OFFSET/INDIRECT.Whenever you reach for OFFSET or INDIRECT, pause and ask:
Can I express this as a normal range built from
INDEX+XMATCH(and maybeSEQUENCE/CHOOSE)?
If the answer is yes, use the non-volatile pattern. Over time, your models will:
Start by refactoring just one high-impact OFFSET or INDIRECT block in your busiest workbook today. The performance gain will usually be enough to justify doing the rest.
Excel Formulas
New
Next Batches Now Live
Power BI
SQL
Power Apps
Power Automate
Microsoft Fabrics
Azure Data Engineering