Excel Lesson 18 – Dynamic Arrays | Dataplexa
Lesson 18 · Intermediate Practical

Dynamic Arrays

Before Microsoft 365, a formula always returned exactly one value into exactly one cell. If you wanted results in multiple cells, you wrote multiple formulas. Dynamic arrays changed that completely. A single formula can now return a whole range of results — automatically expanding to fill as many rows and columns as the data requires. This is called spilling, and it is the engine behind FILTER, SORT, UNIQUE, and several other modern Excel functions that we cover in the next few lessons.

What Spilling Means

When a dynamic array formula returns multiple values, Excel spills those values into the cells below (or beside) the cell where the formula lives. You only type the formula in one cell — Excel fills in the rest automatically. If the data changes and the result grows or shrinks, the spill range adjusts to match.

Static Formula vs Spilling Dynamic Array Formula
❌ Old way — one formula per cell
=A2*1.2
=A3*1.2
=A4*1.2
=A5*1.2
=A6*1.2
5 separate formulas — fragile, easy to miss a row
✅ New way — one spilling formula
=A2:A6*1.2 ← typed here
spilled automatically
spilled automatically
spilled automatically
spilled automatically
1 formula — updates automatically as data changes

The Spill Range and the # Operator

When a dynamic array formula spills, Excel treats the entire filled area as a single unit called the spill range. You can refer to the entire spill range in other formulas using the # (hash) operator after the cell address of the formula cell.

Formula entered in E2:
=A2:A6*1.2

This spills results into E2:E6.

Refer to the entire spill range in another formula:
=SUM(E2#)           →  Sums all spilled values in E2:E6
=AVERAGE(E2#)       →  Average of the spill range
=SORT(E2#)          →  Sorts the spill range

If the source data in A2:A6 grows to A2:A8,
the spill range expands to E2:E8 automatically —
and =SUM(E2#) updates to include the new rows too.
E2# refers to the entire spill range — updates automatically as data grows

The # operator is one of the most useful things to learn when working with dynamic arrays. Any formula that references a spill range using # will automatically include all spilled values — even if new rows are added later. This makes dashboards and summaries that reference dynamic output self-maintaining.

The #SPILL! Error

If something is already in the cells where a dynamic array formula wants to spill its results, Excel cannot complete the spill and shows a #SPILL! error. This is the most common dynamic array error and the fix is always the same — clear the cells in the spill range.

#SPILL! — Something is blocking
=FILTER(A2:C10,B2:B10="North") → #SPILL!
← blocked by existing data here
← blocked
Cells below the formula are occupied — Excel cannot spill
Fixed — cells cleared
=FILTER(A2:C10,B2:B10="North")
spilled row 2
spilled row 3
Cells cleared — formula spills correctly

FILTER — Extract Rows That Match a Condition

FILTER is the dynamic array function you will reach for most often. It returns all rows from a table where a specified condition is true — automatically, in one formula, with no helper columns and no manual filtering. The output spills into as many rows as there are matches.

=FILTER(array, include, [if_empty])

  array      →  The range to return (can be multiple columns)
  include    →  A TRUE/FALSE condition — which rows to include
  if_empty   →  What to show if no rows match (optional)
FILTER — Extracting North Region Sales
Source Data
Rep Region Sales
Priya North 119,000
James East 117,000
Sarah North 93,000
Maria South 82,000
David North 47,000
FILTER Result — North only
=FILTER(A2:C6, B2:B6="North", "No results")
Rep Region Sales
Priya North 119,000
Sarah North 93,000
David North 47,000
Solid border = formula cell  ·  Dashed = spilled
Multiple conditions — North region AND sales over 100,000:
=FILTER(A2:C6, (B2:B6="North") * (C2:C6>100000), "No results")

OR condition — North OR East region:
=FILTER(A2:C6, (B2:B6="North") + (B2:B6="East"), "No results")

Multiply (*) for AND logic — both conditions must be true
Add (+) for OR logic — either condition can be true
North AND sales >100K → Priya: 119,000 only

The multiplication trick for AND, and addition for OR, is a powerful pattern that works across all dynamic array functions. It comes from the fact that TRUE = 1 and FALSE = 0 — multiplying two conditions means both must be 1, adding them means at least one must be non-zero.

SORT — Sort a Range With a Formula

SORT returns a sorted copy of a range as a spilled result. The original data is untouched. You can sort by any column, in either direction, without modifying the source table — ideal for dashboards where the raw data needs to stay in its original order.

=SORT(array, [sort_index], [sort_order], [by_col])

  sort_index   →  Column number to sort by (default: 1)
  sort_order   →  1 = ascending (default),  -1 = descending
  by_col       →  FALSE = sort rows (default),  TRUE = sort columns

=SORT(A2:C6)                 →  Sort by column 1, ascending
=SORT(A2:C6, 3, -1)          →  Sort by column 3 (Sales), descending
=SORT(A2:C6, 2)              →  Sort by column 2 (Region), A–Z
SORT — Leaderboard Ranked by Sales (Descending)
Unsorted source
Rep Sales
Priya119,000
James117,000
Sarah93,000
Maria82,000
David47,000
=SORT(A2:B6, 2, -1)
Rep Sales
🥇 Priya119,000
🥈 James117,000
🥉 Sarah93,000
Maria82,000
David47,000

Notice the source data is unchanged — SORT just returns a sorted copy. This is exactly what you want for a dashboard leaderboard: the raw data stays in entry order, and the sorted view updates automatically whenever new figures come in.

UNIQUE — Extract a Deduplicated List

UNIQUE returns a list with duplicate values removed. Give it a column of region names, customer IDs, or product categories and it returns only the distinct values — automatically, as a spilled list. No manual deduplication, no Remove Duplicates button needed.

=UNIQUE(array, [by_col], [exactly_once])

  by_col        →  FALSE = deduplicate rows (default),  TRUE = deduplicate columns
  exactly_once  →  FALSE = one of each (default),  TRUE = only values appearing once

Regions column B2:B6: North, East, North, South, North

=UNIQUE(B2:B6)         →  North, East, South   (one of each)
=UNIQUE(B2:B6,,TRUE)   →  East, South          (only values appearing exactly once)
UNIQUE(B2:B6) → North / East / South (3 distinct values spilled)

UNIQUE is most powerful when combined with SORT: =SORT(UNIQUE(B2:B6)) produces an alphabetically sorted list of unique values. This is the standard way to build dynamic dropdown lists and report category headers that update automatically as new data is added.

Combining Dynamic Array Functions

The real power emerges when you nest dynamic array functions together. Because each function returns an array, the output of one can feed directly into another — building complex filtered, sorted, and deduplicated results in a single formula.

Sort filtered results — North region, sorted by sales descending:
=SORT(FILTER(A2:C6, B2:B6="North"), 3, -1)

Unique sorted list of regions:
=SORT(UNIQUE(B2:B6))

Unique regions with sales over 80,000:
=UNIQUE(FILTER(B2:B6, C2:C6>80000))

Count unique values in a range:
=COUNTA(UNIQUE(B2:B6))
SORT(FILTER()) — North Region, Ranked by Sales
=SORT(FILTER(A2:C6, B2:B6="North"), 3, -1)
Rep Region Sales ↓
Priya North 119,000
Sarah North 93,000
David North 47,000
FILTER extracted the North rows · SORT ranked them highest to lowest · Both in one formula

Dynamic Arrays and Excel Tables

Dynamic array formulas work best when the source data is formatted as an Excel Table (Insert → Table, or Ctrl+T). When the lookup array is a Table, adding new rows to the table automatically extends the ranges used in your dynamic array formulas — so FILTER, SORT, and UNIQUE results all update without any formula changes.

Source data formatted as Table named "SalesData"

=FILTER(SalesData, SalesData[Region]="North")
=SORT(UNIQUE(SalesData[Region]))
=SORT(SalesData, XMATCH("Sales", SalesData[#Headers]), -1)

When new rows are added to SalesData,
all three formulas update automatically — no range editing needed.
New sales rep added to SalesData table → appears in FILTER/SORT/UNIQUE output immediately
💡 Teacher's Note
The biggest adjustment when first using dynamic arrays is remembering to leave empty cells below your formula. The most common beginner mistake is entering a FILTER or SORT formula without realising there is data just a few rows down — then wondering why everything shows #SPILL!. Before entering a dynamic array formula, always glance at the cells below and to the right of where you are typing. Clear them first if needed, and leave generous space. Over time this becomes automatic.

🟠 Practice

Q1. Data is in A2:C20. Column B contains regions. Write a FILTER formula that returns all rows where column B equals "South".




Q2. Column B contains a long list of product categories with many duplicates. Write a formula that returns a sorted list of unique categories.




Q3. A dynamic array formula in E2 spills results into E2:E8. Write the reference that always points to the entire spill range, no matter how many rows it covers.



🟣 Quiz

Q1. You enter a FILTER formula but it shows #SPILL!. What is the most likely cause?







Q2. In FILTER, you write (B2:B10="North") * (C2:C10>100000) as the include argument. What does the multiplication achieve?







Q3. What does =SORT(A2:C6, 3, -1) do?






Next up — TEXTSPLIT, where you will learn how to split text into multiple cells using any delimiter, and how dynamic arrays make text splitting more powerful than ever.