Spill and dynamic arrays
A spill is what happens when one formula returns several values: they flow into the cells below and beside it. See which Excel does this, how to refer to the result with #, and what #SPILL! means.
Last updated: 14 October 2026
Explains: spill, dynamic array, array
What it is: Spilling is when one formula returns a list or table and Excel writes it into the cells below and beside it (the spill range): =UNIQUE(A2:A500) in one cell lists every distinct value downwards. It works in Microsoft 365 and Excel 2021 and later.
Why it matters: You meet it in client files whenever a colleague used FILTER, UNIQUE or a calculation on a whole column of amounts. To check such a file you need to know what is formula and what is spilled value, how to refer to the result, and why #SPILL! appears.
What spilling is
Normally one formula gives one value in one cell. A formula that returns several values, such as a column of 6 VAT amounts, now writes them out over the neighbouring cells below and to the right.
That is spilling, and the block of cells it fills is the spill range. A result that can change size like this is a dynamic array.
Only the top-left cell, where you typed the formula, contains it. The other cells hold values:
- select one and the formula bar shows the formula in grey; you cannot edit it
- a thin blue border marks the spill range
- delete the top-left formula and the whole spill disappears
- change the source data and the spill grows or shrinks by itself
An array is a set of values that Excel handles as one unit, in rows and columns. A range such as B2:B7 is an array, a typed list such as {1,2,3} is one, and so is the result of FILTER. Spilling is how Excel shows an array that has more than one value.
Which Excel can spill
Spilling arrived with the dynamic arrays of Microsoft 365 and Excel 2021.
Older versions do not spill: a formula for several cells has to be entered as an array formula with Ctrl+Shift+Enter over a block of cells you selected first, and Excel then shows it with {braces} in the formula bar. You cannot type those braces yourself.
Check the version before you send a workbook to a client or a colleague. A formula with FILTER or UNIQUE shows #NAME? in a version that does not have the function, and a spill formula opened in an older version is shown as an array formula over the old size of the spill, which no longer follows the data.
| Version | Several values from one formula |
|---|---|
| Microsoft 365, Excel 2024 | Spills. Includes TEXTSPLIT and VSTACK. |
| Excel 2021 | Spills. Has FILTER, SORT, UNIQUE, SEQUENCE and XLOOKUP, not TEXTSPLIT or VSTACK. |
| Excel 2019 and older | No spilling. Ctrl+Shift+Enter over a selected block gives an array formula with {braces} and a fixed size. |
The spill reference operator #
Watch out: A fixed range such as E2:E4 is right today. When a 4th supplier appears, the spill reaches E5 but E2:E4 still stops at E4, so the total is too low and Excel shows no warning.
To point at a whole spill, write the address of its top-left cell followed by #. E2# means everything the formula in E2 spills at this moment. Three examples:
- =SUM(E2#) adds it all
- =COUNTA(E2#) counts how many values there are
- in SUMIFS(C2:C9, A2:A9, E2#) the list is a set of criteria
E2# is always exactly as large as the spill, so you never count rows by hand and never miss one.
The operator works only on the cell that holds a spilling formula. Pointed at a cell that does not spill, it gives #REF!.
=SUM(E2#)
=SUM(E2#)
Adds every value of the spill that starts in E2.
=COUNTA(E2#)
=COUNTA(E2#)
Counts the values in the spill, whatever its size.
=SUMIFS(C2:C9,A2:A9, E2#)
=SUMIFS(C2:C9;A2:A9; E2#)
One total per name in the spill; the results spill too.
=SUM(E2:E4)
=SUM(E2:E4)
Fixed range: stops being right when the spill grows to E5.
What spills
Several functions are built to return many values. A plain formula spills too, whenever it gets a range or an array where it expects a single value: =A2:A10*1.21 gives 9 results, and so does =LEFT(A2:A10, 4). A function that already adds up a range, such as SUM, returns one value and does not spill.
Spilling formulas nest. =SORT(UNIQUE(A2:A9)) lists each value once and puts the list in order; the inner result is an array that the outer function reads in full.
| Formula | What spills | Available from |
|---|---|---|
FILTER | The rows that meet a condition | Excel 2021 |
SORT | The range in sorted order | Excel 2021 |
UNIQUE | Each value once | Excel 2021 |
SEQUENCE | A list of numbers in steps | Excel 2021 |
XLOOKUP | One result per lookup value, when you give it a range of lookup values | Excel 2021 |
TEXTSPLIT | The parts of one text, one per cell | Excel 2024, Microsoft 365 |
VSTACK | Several ranges below each other | Excel 2024, Microsoft 365 |
| =A2:A10*1.21 | A calculation on a range: one result per cell | Excel 2021 |
=UNIQUE(A2:A9)
=UNIQUE(A2:A9)
Lists each supplier once, in order of first appearance.
=A2:A10*1.21
=A2:A10*1,21
Nine results from one formula, one per cell of A2:A10.
=XLOOKUP(A2:A9,F2:F20, G2:G20)
=XLOOKUP(A2:A9;F2:F20; G2:G20)
Looks up all 8 values at once and spills 8 results.
=TEXTSPLIT(B2,"-")
=TEXTSPLIT(B2;"-")
Splits an entry number such as 25-0412 into 25 and 0412 across two cells.
When you get #SPILL!
#SPILL! means the formula is correct but its result has no room. The error appears only in the top-left cell. Select that cell and Excel names the cause in the warning menu. The four causes below are the most common ones.
Do not repair #SPILL! with IFERROR: it hides the message that tells you something is in the way, and the list stays empty.
| Cause | What is happening | Fix |
|---|---|---|
| Blocked cells | A cell in the spill range holds a value, a space, or is merged | Clear or move the obstructing cells, or unmerge them |
| Inside an Excel table | Tables cannot hold a formula that spills | Put the formula outside the table, or convert the table to a range |
| Too big | The result runs past the last row or column of the sheet, as with =B:B*1.21 | Refer to the exact range, such as B2:B500 |
| Size keeps changing | The number of results is different at every calculation, as with SEQUENCE(RANDBETWEEN(1, 5)) | Make the size depend on data that stays put, or type a fixed number |
The @ sign in older files
Before dynamic arrays a formula that got a range where it expected one value did not spill. Excel quietly took one value from the same row or column as the formula. That is implicit intersection: =A2:A10*1.21 typed in D4 meant A4*1.21.
When Microsoft 365 opens such a file it writes @ in front of the part that could return several values, as in =@A2:A10*1.21, so that the formula keeps giving the same single value.
Remove the @ and the formula spills. Do that on purpose and note it: the figures change from one value to a column, and the new spill can run into cells that already hold data.
=@A2:A10
=@A2:A10
Takes one value only: the one in the row of the formula.
Array constants
An array constant is a list of fixed values that you type between braces. With English settings a comma separates the columns and a semicolon the rows.
With Dutch settings a backslash separates the columns and a semicolon still separates the rows, because the comma is the decimal separator. Excel shows the constant in the style of the computer's regional settings.
A constant can hold numbers, text in quotes, TRUE and FALSE and error values, but no cell references and no functions.
Two arrays of different shapes combine into a grid, as {0.005,0.01} does with a column of revenues. Two columns of different length leave #N/A where there is no counterpart.
| Shape | English settings | Dutch settings |
|---|---|---|
| A row of 3 values | {1,2,3} | {1\2\3} |
| A column of 3 values | {1;2;3} | {1;2;3} |
| A grid of 2 rows and 3 columns | {1,2,3;4,5,6} | {1\2\3;4\5\6} |
| Decimals | {0.5,1.5} | {0,5\1,5} |
=B2:B4*{0.005,0.01}
=B2:B4*{0,005\0,01}
A column against a row gives a grid: the lower and upper materiality limits per year.
=XLOOKUP(C2:C7,{1, 2, 3}, {0.21, 0.09, 0})
=XLOOKUP(C2:C7;{1\ 2\ 3}; {0,21\ 0,09\ 0})
Turns 6 VAT codes into rates without a helper table; the 6 results spill.
=SUM(COUNTIF(B2:B100,{"MEM", "BNK"}))
=SUM(COUNTIF(B2:B100;{"MEM"\ "BNK"}))
Counts the entries of two journals; the array of 2 counts goes into SUM and works in every version.
Worked examples
Example1 of 4Beginner
Work back to the net amount on six purchase invoices at once
You are testing the net amounts that Veldhuis Installatie BV booked on its purchase invoices. The invoice list shows only the gross amount including 21% VAT.
Instead of filling a formula down the column, you enter one formula in C2 and let it spill, so the whole recalculation sits in a single cell that you can read and check.
| Row | A | B | C | D |
|---|---|---|---|---|
| 1 | Invoice no. | Gross amount (21% VAT) | Net amount | |
| 2 | 25-1301 | €1,512.50€ 1.512,50 | €1,250.00€ 1.250,00=ROUND(B2:B7/1.21, 2)=ROUND(B2:B7/1,21; 2) | |
| 3 | 25-1302 | €580.15€ 580,15 | €479.46€ 479,46 | |
| 4 | 25-1303 | €3,488.00€ 3.488,00 | €2,882.64€ 2.882,64 | |
| 5 | 25-1304 | €105.69€ 105,69 | €87.35€ 87,35 | |
| 6 | 25-1305 | €1,887.60€ 1.887,60 | €1,560.00€ 1.560,00 | |
| 7 | 25-1306 | €261.12€ 261,12 | €215.80€ 215,80 | |
| 8 |
Swipe sideways to see all columns
Formula in C2
=ROUND(B2:B7/1.21,2)
=ROUND(B2:B7/1,21;2)
Result: €1,250.00 / €479.46 / €2,882.64 / €87.35 / €1,560.00 / €215.80€ 1.250,00 / € 479,46 / € 2.882,64 / € 87,35 / € 1.560,00 / € 215,80
Step by step
B2:B7is a column of 6 gross amounts and 1.21 is a single number. Excel divides every cell of the range by 1.21, so the quotient is an array of 6 values, not one value.The six quotients are:
- 1,512.501.512,50 / 1.21 = 1,2501.250
- 580.15 / 1.21 = 479.4628
- 3,488.003.488,00 / 1.21 = 2,882.64462.882,6446
- 105.69 / 1.21 = 87.3471
- 1,887.601.887,60 / 1.21 = 1,5601.560
- 261.12 / 1.21 = 215.8017
- ROUND works on the whole array and rounds each quotient to 2 decimals: 1,250.001.250,00, 479.46, 2,882.642.882,64, 87.35, 1,560.001.560,00 and 215.80.
- Excel needs 6 cells for 6 results. It places the first in
C2and spills the other five intoC3:C7. OnlyC2contains the formula;C3:C7show values and appear grey in the formula bar. - The recalculated net amounts add up to 1,250.001.250,00 + 479.46 + 2,882.642.882,64 + 87.35 + 1,560.001.560,00 + 215.80 = 6,475.256.475,25. Compare that with the net amounts booked on these six invoices in the ledger.
Change the gross amount in
B3to 605 andC3becomes 500.00 at once.Add a 7th invoice in row 8 and the spill does not grow, because
B2:B7still ends at row 7. Put the data in an Excel table (see Named ranges and structured references) and refer to its column, so the range grows with the data.
Watch out: In Excel 2019 or older the same formula returns one value, for the row where you typed it, unless you confirm it with Ctrl+Shift+Enter over a selected block of 6 cells.
More on this example: why it works, 1 variation
Why it works
Excel evaluates a formula on whole arrays when you give it ranges where it expects single values. In Microsoft 365 and Excel 2021 and later the result of that evaluation is not cut down to one value: it is written out over as many cells as it has values. That is spilling.
Variations
=SUM(ROUND(B2:B7/1.21,2))
=SUM(ROUND(B2:B7/1,21;2))
Total net amount in one cell, 6,475.256.475,25. In Excel 2019 or older confirm it with Ctrl+Shift+Enter; in newer versions Enter is enough.
Example2 of 4Intermediate
Show the materiality range for three years side by side
For the file of Veldhuis Installatie BV you compare overall materiality with the previous years. The firm's benchmark is 0.5% to 1% of revenue.
You type the two percentages as an array constant, so that one formula returns the lower and the upper limit for all three years in a 3 by 2 block.
| Row | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| 1 | Year | Revenue | Lower (0.5%) | Upper (1%) | ||
| 2 | 20232023 | €7,980,000.00€ 7.980.000,00 | €39,900.00€ 39.900,00=B2:B4*{0.005,0.01}=B2:B4*{0,005\0,01} | €79,800.00€ 79.800,00 | ||
| 3 | 20242024 | €8,450,000.00€ 8.450.000,00 | €42,250.00€ 42.250,00 | €84,500.00€ 84.500,00 | ||
| 4 | 20252025 | €9,120,000.00€ 9.120.000,00 | €45,600.00€ 45.600,00 | €91,200.00€ 91.200,00 | ||
| 5 |
Swipe sideways to see all columns
Formula in D2
=B2:B4*{0.005,0.01}
=B2:B4*{0,005\0,01}
Result: €39,900.00 | €79,800.00 / €42,250.00 | €84,500.00 / €45,600.00 | €91,200.00€ 39.900,00 | € 79.800,00 / € 42.250,00 | € 84.500,00 / € 45.600,00 | € 91.200,00
Step by step
B2:B4is a column of 3 values: 7,980,0007.980.000, 8,450,0008.450.000 and 9,120,0009.120.000. The constant{0.005,0.01}is a row of 2 values: 0.005 and 0.01. The,between them means "next column" with English regional settings.- When a column meets a row, Excel stretches both to a 3 by 2 grid and multiplies every combination. Row 1 of the grid is 7,980,0007.980.000 × 0.005 = 39,90039.900 and 7,980,0007.980.000 × 0.01 = 79,80079.800.
- Row 2 is 8,450,0008.450.000 × 0.005 = 42,25042.250 and 8,450,0008.450.000 × 0.01 = 84,50084.500. Row 3 is 9,120,0009.120.000 × 0.005 = 45,60045.600 and 9,120,0009.120.000 × 0.01 = 91,20091.200.
- The 6 results need
D2:E4. They spill fromD2to the right and down; the lower limits land in column D and the upper limits in column E. - For 2025 the range is 45,60045.600 to 91,20091.200. The step from 2024 to 2025 is 45,60045.600 − 42,25042.250 = 3,3503.350 on the lower limit, which shows how much the benchmark moved with revenue.
Watch out: Typing {0.005;0.01} (semicolon) makes a column of 2 values. Against the column B2:B4 that gives #N/A in the cells without a counterpart, not a grid.
More on this example: why it works, 1 variation
Why it works
An array constant is a list of fixed values written between braces. Excel stretches a one-row array against a one-column array to a grid, with a cell for every combination, as in a multiplication table. The percentages stay visible in the formula, but if the firm changes them you must edit the formula.
Variations
=B2:B4*{0.005;0.01; 0.02}
=B2:B4*{0,005;0,01; 0,02}
Wrong shape on purpose: a column of 3 against a column of 3 multiplies pair by pair and returns a single column of 3 values, not a grid.
Example3 of 4Advanced
Total the purchases per supplier from a spilled list
You have the purchase ledger of Veldhuis Installatie BV with 8 invoices and want the total per supplier, to compare with the purchase volume per supplier in the supplier statements.
In E2 a UNIQUE formula lists each supplier once. The totals in F2 refer to that list with E2#, so they follow the list when a new supplier appears.
| Row | A | B | C | D | E | F | G |
|---|---|---|---|---|---|---|---|
| 1 | Supplier | Invoice no. | Amount | Supplier | Total | ||
| 2 | Bakker Elektro | 25-2101 | €1,850.00€ 1.850,00 | Bakker Elektro | €5,050.00€ 5.050,00=SUMIFS(C2:C9, A2:A9, E2#)=SUMIFS(C2:C9; A2:A9; E2#) | ||
| 3 | Van Dijk Groothandel | 25-2102 | €4,220.50€ 4.220,50 | Van Dijk Groothandel | €6,110.75€ 6.110,75 | ||
| 4 | Bakker Elektro | 25-2103 | €960.00€ 960,00 | Kuijpers Techniek | €3,880.75€ 3.880,75 | ||
| 5 | Kuijpers Techniek | 25-2104 | €3,100.00€ 3.100,00 | ||||
| 6 | Van Dijk Groothandel | 25-2105 | €1,375.25€ 1.375,25 | ||||
| 7 | Bakker Elektro | 25-2106 | €2,240.00€ 2.240,00 | ||||
| 8 | Kuijpers Techniek | 25-2107 | €780.75€ 780,75 | ||||
| 9 | Van Dijk Groothandel | 25-2108 | €515.00€ 515,00 | ||||
| 10 |
Swipe sideways to see all columns
Formula in F2
=SUMIFS(C2:C9,A2:A9, E2#)
=SUMIFS(C2:C9;A2:A9; E2#)
Result: €5,050.00 / €6,110.75 / €3,880.75€ 5.050,00 / € 6.110,75 / € 3.880,75
Step by step
E2#stands for the whole spill that starts inE2. UNIQUE put 3 names there: Bakker Elektro, Van Dijk Groothandel and Kuijpers Techniek, in order of first appearance.- The criterion is an array of 3 values, so SUMIFS runs three times, once per supplier, and returns an array of 3 totals.
- Bakker Elektro is in
A2,A4andA7, with amounts C2 + C4 + C7 = 1,850.001.850,00 + 960.00 + 2,240.002.240,00 = 5,050.005.050,00. - Van Dijk Groothandel is in
A3,A6andA9: C3 + C6 + C9 = 4,220.504.220,50 + 1,375.251.375,25 + 515.00 = 6,110.756.110,75. Kuijpers Techniek is inA5andA8: 3,100.003.100,00 + 780.75 = 3,880.753.880,75. - The 3 totals spill from
F2intoF3:F4, next to the supplier they belong to. OnlyF2holds the formula. - Reconcile: SUM(F2#) = 5,050.005.050,00 + 6,110.756.110,75 + 3,880.753.880,75 = 15,041.5015.041,50, which equals SUM(C2:C9). No invoice is left out. If a 4th supplier appears, UNIQUE spills 4 names, E2# grows to 4 cells and F gets a 4th total without you changing anything.
Watch out: Use E2# for the criteria, not a typed range: with E2:E4 the totals are right today but leave out any supplier added to the list later.
More on this example: why it works, 2 variations
Why it works
E2# is a reference that is the exact size of the spill, at every moment. Giving SUMIFS an array as criterion makes it return one total per element. Together they give a small report that updates itself: the list of suppliers and the totals can never get out of step.
Variations
=SUMIFS(C2:C9,A2:A9, UNIQUE(A2:A9))
=SUMIFS(C2:C9;A2:A9; UNIQUE(A2:A9))
All in one formula, without a list in E. Nothing refers to the names, so use it when you only need the totals.
=COUNTA(E2#)
=COUNTA(E2#)
Counts the suppliers: 3.
Example4 of 4Advanced
Find out why a list of accounts shows #SPILL!
In the journal extract of Veldhuis Installatie BV you list the accounts that were used, with =UNIQUE(B2:B9) in D2. A colleague had typed the word Checked in D4 earlier.
Instead of the list, D2 shows #SPILL!, and you want to know why and how to repair it.
| Row | A | B | C | D | E |
|---|---|---|---|---|---|
| 1 | Entry no. | Account | Accounts used | ||
| 2 | 25-0701 | 40004000 | #SPILL!=UNIQUE(B2:B9)=UNIQUE(B2:B9) | ||
| 3 | 25-0702 | 45004500 | |||
| 4 | 25-0703 | 40004000 | Checked | ||
| 5 | 25-0704 | 80008000 | |||
| 6 | 25-0705 | 45004500 | |||
| 7 | 25-0706 | 40004000 | |||
| 8 | 25-0707 | 80008000 | |||
| 9 | 25-0708 | 16001600 | |||
| 10 |
Swipe sideways to see all columns
Formula in D2
=UNIQUE(B2:B9)
=UNIQUE(B2:B9)
Result: #SPILL!
Step by step
- UNIQUE reads the 8 accounts in
B2:B9(4000, 4500, 4000, 8000, 4500, 4000, 8000, 1600) and keeps each once, in order of first appearance: 4000, 4500, 8000 and 1600. That is 4 values. - Excel needs 4 cells in a column for them:
D2,D3,D4andD5. - Before it writes anything, Excel checks that
D3,D4andD5are empty.D3andD5are.D4holds the textChecked. - Excel never overwrites a cell with a value, so it does not write any of the 4 results.
D2shows #SPILL! andD3andD5stay empty. The formula itself is correct; the result has no room. - Select
D2: the warning icon names the cause and offers to select the obstructing cells. Delete the text inD4, or move it, and the list appears at once: 4000, 4500, 8000, 1600 inD2:D5. - If
D4looks empty but the error stays, it can hold a space, an empty text from a formula or white text. Cells that are part of a merged cell block in the range also block the spill.
Watch out: Deleting the formula in D2 and typing the accounts by hand removes the error but also the connection with the extract. The list no longer follows new entries.
More on this example: why it works, 1 variation
Why it works
A spill range has to be clear before Excel fills it. Excel treats a typed value as the user's work and protects it, so it reports the problem in the formula cell. That is why the error appears in D2 and not in D4: it is the formula that cannot deliver.
Variations
=COUNTA(UNIQUE(B2:B9))
=COUNTA(UNIQUE(B2:B9))
Counts the distinct accounts, 4, in one cell. A single value never spills, so it cannot show #SPILL!.
Common mistakes
| Symptom | Cause | Fix |
|---|---|---|
| The total is too low after a new row was added | The total of a supplier list is too low after a new supplier was added: =SUM(E2:E4) still adds 3 cells. | The fixed range does not follow the spill. Write =SUM(E2#) so that the reference is as large as the spill, whatever its size. |
| #SPILL! although the formula is correct | D2 shows #SPILL! right after you typed =FILTER(A2:C9, C2:C9>1000), although the formula is correct. | The spill needs several columns and rows, and a cell in that block is not empty. Select D2, choose the obstructing cells in the warning menu and clear or move them. |
| #SPILL! on a formula that refers to a whole column | =B:B*0.21 in D2 gives #SPILL!. The wrong way: a whole column as source. | A whole column has more than a million cells, so the result runs off the sheet. Use the exact range, =B2:B500*0.21, or an Excel table and a normal formula per row. |
| #SPILL! on a dynamic formula typed inside a table | =UNIQUE(A2:A9) typed inside an Excel table gives #SPILL!. | Tables do not allow spilling formulas. Move the formula to a cell outside the table; if the list belongs in the table, convert the table to a range first. |
| An English array constant is not read as a row of values | You copy the English formula =B2:B4*{0.005,0.01} into a workbook on Dutch settings and Excel does not read it as a row of 2 values. | The separator inside the braces depends on the regional settings. On Dutch settings type =B2:B4*{0,005\0,01}, with a backslash between columns and a decimal comma. |
| #REF! on a reference to a spill range that is not there | =SUM(E3#) gives #REF!, although E2 holds a spilling formula. | # refers to the spill that starts in the cell you name. E3 is part of the spill but does not start it. Use the top-left cell: =SUM(E2#). |