Data Analysis

Google Sheets Cross-Row Formulas Break in Sorted Ranges

Marc SeanJune 23, 20265 min read

Why Google Sheets Cross-Row Formulas Break After Sort

Google Sheets evaluates formulas against physical cell addresses, not logical row positions within a dataset. When you sort a filtered range, the underlying row order in the sheet changes. A formula like ='Cash Flow'!C14-'Cash Flow'!C13 built to capture month-over-month change now references whatever data landed in rows 13 and 14 after the sort - which could be Q3 vs Q1, or two non-consecutive periods entirely.

This isn't a bug. It's how the reference model works. The trap is that the formula evaluates without complaint, the output looks plausible (it's still a dollar difference), and the error only surfaces when someone notices the numbers don't match the narrative. In a 48-period model, a single misaligned row reference cascades silently. A true 14.2% MoM growth rate becomes 8.7% or 19.4% depending on which two rows end up adjacent after the sort. Your board pack ships with the wrong trend line.

Three Cross-Row Formula Patterns That Break in Filtered Ranges

Pattern 1: Direct adjacent-row arithmetic

='P&L'!C5-'P&L'!C4

Built to calculate period delta, this assumes rows 4 and 5 are consecutive periods. Sort by any column and that assumption breaks.

Pattern 2: OFFSET with row-relative positioning

=OFFSET('Cash Flow'!C2, ROW()-ROW('Cash Flow'!$C$2), 0)
 - OFFSET('Cash Flow'!C2, ROW()-ROW('Cash Flow'!$C$2)-1, 0)

ROW() returns the physical row number of the formula cell. After a sort, ROW()-1 no longer points to the prior period - it points to whatever is physically one row above in the sheet.

Pattern 3: INDEX with a derived position offset

=INDEX('P&L'!C:C, MATCH(A5,'P&L'!A:A,0))
 - INDEX('P&L'!C:C, MATCH(A5,'P&L'!A:A,0)-1)

MATCH finds the correct row for A5's value, then subtracts 1 to get the "prior" row. After a sort, the prior row by position is not the prior period by sequence.

PatternBreaks on Sort?Breaks on Filter?Silently Wrong?
Adjacent-row arithmetic (C5-C4)YesYesYes
OFFSET + ROW()YesYesYes
INDEX with position offsetYesSometimesYes
SUMIFS with period keyNoNoNo
INDEX/MATCH with period keyNoNoNo

The Fixes That Hold

The root fix is the same across all three patterns: stop relying on physical row position to imply sequence. Use a period key instead.

Fix 1: SUMIFS with an explicit period key

Instead of referencing adjacent rows, look up the prior period explicitly by value:

=SUMIFS('P&L'!C:C, 'P&L'!A:A, Assumptions!$B$3)
 - SUMIFS('P&L'!C:C, 'P&L'!A:A, Assumptions!$B$3-1)

Column A on P&L is a period number (1 through 48, or a date). Assumptions!$B$3 holds the current period. This survives any sort or filter because it looks up by value, not position.

For a quarterly board pack pulling $4.2M monthly revenue at 38.5% gross margin across 12 periods, this structure means the CFO can sort the filtered view by variance without corrupting the delta calculations.

Fix 2: Helper column with a stable sequence key

Add a Period_Seq column to your data range - a simple integer 1, 2, 3... that never changes. Your cross-row formula then uses MATCH on that key:

=INDEX('P&L'!$C:$C, MATCH(D5-1, 'P&L'!$D:$D, 0))
 - INDEX('P&L'!$C:$C, MATCH(D5, 'P&L'!$D:$D, 0))

Column D is Period_Seq. The formula is sort-proof because MATCH hunts by value, not position. Even if someone sorts the P&L tab by region or entity, the sequence keys stay correct.

Fix 3: Push cross-row calculations off the filtered range

If your model has a filtered driver table and a separate output area, do period-over-period math only in the output area - where rows are never sorted. Reference the filtered table for point-in-time values, then compute deltas in a stable section.

This is the cleanest architecture for a bank syndicate DCF or a multi-SKU contribution margin model. The filtered range is read-only input; all arithmetic lives elsewhere and references the data tab by period key.

What About ARRAYFORMULA?

ARRAYFORMULA with a cross-row reference has the same problem. The array expands across physical rows, not logical sequence positions. Sorting the underlying range shifts which rows participate in each position of the array output.

As of June 2026, there's no Google Sheets native function that says "give me the value from the row with sequence key N-1 relative to this row's sequence key" without an explicit MATCH or VLOOKUP. You have to provide the lookup key yourself.

Auditing an Inherited Model for This Problem

If you've inherited a model with cross-row formulas inside a filtered range and you're not sure what's exposed, the fastest audit is three steps. Note the current output values of every cross-row formula. Sort the filtered range by any column other than the sequence column. Compare outputs - anything that changed is wrong.

A model carrying $62M in cumulative bookings with cross-row growth calculations in a filtered view has probably been sorted by someone at some point. Check before trusting the trend numbers.

ModelMonkey can speed up this audit considerably. Describe the model structure in the sidebar and ask it to flag formulas that reference relative row offsets within the active range. It cross-references formula patterns against the sheet's filter state, which cuts a manual scan from an hour to a few minutes on a complex multi-tab model.

Try ModelMonkey free for 14 days - it works in both Google Sheets and Excel.

Frequently Asked Questions