Available in:Excel 2024 or later (Works in Excel 2024, every later version, Microsoft 365 and Excel for the web)Category:Dynamic arrays

TOCOL

NAAR.KOLOM in Dutch Excel

Turns a block of cells into one single column, optionally leaving out blanks and errors, so other functions can work on a flat list.

Difficulty rating 3 of 5. The formula itself is short, but the order in which cells are read and the ignore codes decide what ends up in the column, and the result only pays off when combined with other array functions.

Last updated: 13 October 2026

See the worked examples

Sheet excerpt: D2 holds the formula
RowABCD
1Round 1Round 2
225-110125-110825-1101=TOCOL(A2:B4)=TOCOL(A2:B4)
325-111525-112225-1108
425-113025-113725-1115
525-1122
625-1130
725-1137
Formula cell (D2)Spilled result
=TOCOL(A2:B4)
=TOCOL(A2:B4)

What TOCOL does and when to use it

What it does: it puts every value of a block of cells under each other in one column, for example the invoices sampled in two rounds.

When to use it: when data sits in a grid but the next step needs a list: counting or de-duplicating values over several columns, comparing two grids cell by cell, or looking up a value in a block. The list spills downward. It replaces copy and paste routines and the old INDEX and MOD constructions that numbered every cell.

Two main gains:

  • One formula for any grid: no numbering of cells with INDEX and MOD.
  • Skips blanks and errors: ignore leaves out empty cells, errors or both while the grid is flattened.

How Excel evaluates it

TOCOL works through the grid in order:

  • Excel first evaluates array, so a comparison such as C2:D6>=G1 is turned into a grid of TRUE and FALSE before TOCOL sees it
  • it walks through the grid in the order set by scan_by_column: row by row by default, column by column when TRUE
  • each cell is checked against ignore; blanks and errors that are skipped never enter the result
  • the remaining values are written under each other, starting in the formula cell, and the column spills downward

If a cell in the spill area is occupied, you get #SPILL!.

Watch out: TOCOL keeps empty cells by default and turns them into 0, which inflates any count. Set the ignore argument to skip them.

Mental model

Unrolling a carpet: the grid is rolled out into one long strip, row by row unless you tell Excel to unroll it by column.

Terms used on this page: spill, array, cell

TOCOL(array, [ignore], [scan_by_column])
TOCOL(array; [ignore]; [scan_by_column])
Arguments
ArgumentTypeMeaningDefault
arrayRequiredThe range or array to flatten into one column.
ignoreOptionalWhich cells to skip: 0 none, 1 blanks, 2 errors, 3 both.0
scan_by_columnOptionalFALSE reads row by row (default), TRUE reads column by column.FALSE

Return value:One column holding every value of the array, in reading order

Formulas use commas (,) between arguments, as in English Excel. Formulas use semicolons (;) between arguments, as in Dutch Excel. Formulas use commas (,) between arguments, as in English Excel; Dutch Excel uses semicolons (;).

Worked examples

Beginner

Put the sampled invoices of two rounds in one column

You drew a sample of sales invoices at Veldhuis Installatie BV in two rounds. The invoice numbers sit in a small grid, three per round. For the working paper you want one list with every number under each other, in the order of the grid.

Sheet excerpt: D2 holds the formula
RowABCDE
1Round 1Round 2
225-110125-110825-1101=TOCOL(A2:B4)=TOCOL(A2:B4)
325-111525-112225-1108
425-113025-113725-1115
525-1122
625-1130
725-1137
8
Formula cell (D2)Spilled result

Formula in D2

=TOCOL(A2:B4)
=TOCOL(A2:B4)

Result: 25-1101 / 25-1108 / 25-1115 / 25-1122 / 25-1130 / 25-113725-1101 / 25-1108 / 25-1115 / 25-1122 / 25-1130 / 25-1137

Step by step
  1. The only argument is A2:B4: 3 rows and 2 columns, so 6 cells. ignore and scan_by_column are left out, so both use their defaults: 0 (keep everything) and FALSE (read row by row).
  2. Row 1 of the grid is read from left to right: A2 is 25-1101, then B2 is 25-1108.
  3. Row 2 follows: A3 is 25-1115, B3 is 25-1122. Row 3 closes the list: A4 is 25-1130, B4 is 25-1137.
  4. No cell is blank, so nothing is skipped. All 6 numbers are written under each other and the column spills from D2 to D7.
  5. Change B3 to 25-1199 and D5 changes with it, because the list follows the grid.

Watch out: The numbers come out row by row, not per round. If you expected all of round 1 first, you need the third argument TRUE.

More on this example: why it works, 1 variation

Why it works

TOCOL always visits a block in a fixed order, and with the default that order is row by row. The result is a live copy of the grid, shaped as a column, so it needs no copy and paste and never goes stale.

Variations

=TOCOL(A2:B4, 0, TRUE)
=TOCOL(A2:B4; 0; TRUE)

Column by column: first the three numbers of round 1, then those of round 2.

Intermediate

List unreconciled bank items, skipping the empty cells

In the bank reconciliation of Veldhuis Installatie BV the client lists open items per week and per bank account. Most weeks an account has nothing open, so many cells are empty. You want one list of the amounts that are open, without zeros for the empty cells, to check them against the bank statement.

Sheet excerpt: E2 holds the formula
RowABCDEF
1Current accountSavings accountForeign currency account
2€1,250.00€ 1.250,00€480.00€ 480,00€1,250.00€ 1.250,00=TOCOL(A2:C5, 1)=TOCOL(A2:C5; 1)
3€2,100.00€ 2.100,00€480.00€ 480,00
4€760.00€ 760,00€315.00€ 315,00€2,100.00€ 2.100,00
5€4,400.00€ 4.400,00€760.00€ 760,00
6€315.00€ 315,00
7€4,400.00€ 4.400,00
8
Formula cell (E2)Spilled result

Formula in E2

=TOCOL(A2:C5, 1)
=TOCOL(A2:C5; 1)

Result: €1,250.00 / €480.00 / €2,100.00 / €760.00 / €315.00 / €4,400.00€ 1.250,00 / € 480,00 / € 2.100,00 / € 760,00 / € 315,00 / € 4.400,00

Step by step
  1. array is A2:C5: 4 weeks by 3 accounts, 12 cells. The second argument is 1, so blank cells are skipped. scan_by_column is left out, so Excel reads row by row.
  2. Week 1: A2 is 1,2501.250, B2 is blank and skipped, C2 is 480. Week 2: A3 and B3 are blank and skipped, C3 is 2,1002.100.
  3. Week 3: A4 is 760, B4 is 315, C4 is blank and skipped. Week 4: A5 is blank and skipped, B5 is 4,4004.400, C5 is blank and skipped.
  4. 6 amounts remain and spill from E2 to E7: 1,2501.250, 480, 2,1002.100, 760, 315 and 4,4004.400. Together they are 1,2501.250 + 480 + 2,1002.100 + 760 + 315 + 4,4004.400 = 9,3059.305.
  5. Without the 1 the list has 12 rows: the 6 empty cells come back as 0, and a count of the list would say 12 open items instead of 6.

Watch out: A cell that contains an empty text from a formula ("") is not blank, so ignore 1 keeps it. If an empty-looking gap survives, test the cell with ISBLANK.

More on this example: why it works, 1 more pitfall, 1 variation

Why it works

The ignore argument filters while flattening, so the empty cells are gone before any other function sees the list. A grid is a convenient layout for a person; a list is what COUNT, SUM, SORT and UNIQUE want.

More to watch out for

  • Amounts of exactly 0 are not blank and stay in the list; only ignore codes 1 and 3 remove empty cells, never zeros.

Variations

=TOCOL(A2:C5, 3)
=TOCOL(A2:C5; 3)

Skip blanks and error values together, useful when a grid comes from formulas that can return #N/A.

Advanced

Find the first invoice at or above performance materiality in a grid

For a payment test at Veldhuis Installatie BV the client gave two matching grids: the invoice numbers and, in the same positions, the amounts. You want the first invoice whose amount is at or above performance materiality, which sits in G1, and not search for it by eye. The grids have two columns and five rows.

Sheet excerpt: F3 holds the formula
RowABCDEFGH
1Invoice 1Invoice 2Amount 1Amount 2Performance materiality€12,000.00€ 12.000,00
225-200125-2002€4,200.00€ 4.200,00€8,900.00€ 8.900,00
325-200325-2004€3,100.00€ 3.100,00€15,400.00€ 15.400,0025-2004=XLOOKUP(TRUE, TOCOL(C2:D6>=G1), TOCOL(A2:B6), "No invoice at or above materiality")=XLOOKUP(TRUE; TOCOL(C2:D6>=G1); TOCOL(A2:B6); "No invoice at or above materiality")
425-200525-2006€9,750.00€ 9.750,00€21,000.00€ 21.000,00
525-200725-2008€6,100.00€ 6.100,00€12,800.00€ 12.800,00
625-200925-2010€18,200.00€ 18.200,00€3,900.00€ 3.900,00
7
Formula cell (F3)Input

Formula in F3

=XLOOKUP(TRUE, TOCOL(C2:D6>=G1), TOCOL(A2:B6), "No invoice at or above materiality")
=XLOOKUP(TRUE; TOCOL(C2:D6>=G1); TOCOL(A2:B6); "No invoice at or above materiality")

Result: 25-2004

Step by step
  1. Inside out, the condition grid first. C2:D6>=G1 compares each of the 10 amounts with 12,00012.000, row by row:

    • 4,2004.200 FALSE, 8,9008.900 FALSE
    • 3,1003.100 FALSE, 15,40015.400 TRUE
    • 9,7509.750 FALSE, 21,00021.000 TRUE
    • 6,1006.100 FALSE, 12,80012.800 TRUE
    • 18,20018.200 TRUE, 3,9003.900 FALSE
  2. TOCOL on that grid reads row by row: FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE. The first TRUE is in position 4.
  3. TOCOL(A2:B6) flattens the invoice numbers in the same order: 25-2001, 25-2002, 25-2003, 25-2004, 25-2005, 25-2006, 25-2007, 25-2008, 25-2009, 25-2010. Both lists have 10 entries, so position 4 belongs to the same cell pair.
  4. XLOOKUP searches the first list for TRUE and finds it at position 4, so it returns the 4th item of the second list: 25-2004, which is B3 with an amount of 15,40015.400.
  5. Set G1 to 30000: no amount qualifies, the lookup finds no TRUE, and F3 shows the text from the fourth argument instead of #N/A.

Watch out: If one TOCOL reads by column and the other by row, the lists no longer line up. With the amounts read by column and the invoices by row, position 5 is TRUE and the formula returns 25-2005, a real invoice number that is wrong, with no error.

More on this example: why it works, 1 more pitfall, 2 variations

Why it works

XLOOKUP only understands lists, not grids, so TOCOL turns the condition grid and the answer grid into two lists of equal length with the same order. A TRUE in position n of the condition list then points to the n-th invoice of the answer list, which gives a two-dimensional lookup in one formula.

More to watch out for

  • XLOOKUP returns the first match only. Four amounts reach 12,00012.000; this formula shows one invoice, not the other three. Use FILTER when you need them all.

Variations

=XLOOKUP(TRUE, TOCOL(C2:D6>=G1, 0, TRUE), TOCOL(A2:B6, 0, TRUE), "No invoice at or above materiality")
=XLOOKUP(TRUE; TOCOL(C2:D6>=G1; 0; TRUE); TOCOL(A2:B6; 0; TRUE); "No invoice at or above materiality")

Read both grids by column: the first TRUE is then C6 (18,20018.200) and the result is 25-2009. Use this when the grid is ordered per client or per month in columns.

=FILTER(TOCOL(A2:B6), TOCOL(C2:D6>=G1))
=FILTER(TOCOL(A2:B6); TOCOL(C2:D6>=G1))

All qualifying invoices instead of the first: 25-2004, 25-2006, 25-2008 and 25-2009.

Master

Invoices paid more than once across bank runs

The payment files of three bank runs at Veldhuis Installatie BV are pasted next to each other, one column per run, with different numbers of invoices so the lower cells are empty.

You test for duplicate payments: which invoice numbers appear more than once anywhere in the three runs? The reviewer wants the result ordered by run and the formula readable.

Sheet excerpt: E2 holds the formula
RowABCDEF
1Run 1Run 2Run 3
2F25-3101F25-3105F25-3106F25-3102=LET( paid, TOCOL(A2:C6, 1, TRUE), times, COUNTIF(A2:C6, paid), repeated, FILTER(paid, times > 1, "No invoice paid twice"), UNIQUE(repeated) )=LET( paid; TOCOL(A2:C6; 1; TRUE); times; COUNTIF(A2:C6; paid); repeated; FILTER(paid; times > 1; "No invoice paid twice"); UNIQUE(repeated) )
3F25-3102F25-3102F25-3109F25-3105
4F25-3103F25-3107F25-3107F25-3107
5F25-3104F25-3105
6F25-3102
7
Formula cell (E2)Spilled result

Formula in E2

=LET(
  paid, TOCOL(A2:C6, 1, TRUE),
  times, COUNTIF(A2:C6, paid),
  repeated, FILTER(paid, times > 1, "No invoice paid twice"),
  UNIQUE(repeated)
)
=LET(
  paid; TOCOL(A2:C6; 1; TRUE);
  times; COUNTIF(A2:C6; paid);
  repeated; FILTER(paid; times > 1; "No invoice paid twice");
  UNIQUE(repeated)
)

Result: F25-3102 / F25-3105 / F25-3107F25-3102 / F25-3105 / F25-3107

Step by step
  1. LET stores paid: TOCOL reads A2:C6 column by column (third argument TRUE) and skips blanks (ignore 1). That gives 12 payments:

    • run 1: F25-3101, F25-3102, F25-3103, F25-3104
    • run 2: F25-3105, F25-3102, F25-3107
    • run 3: F25-3106, F25-3109, F25-3107, F25-3105, F25-3102
  2. times counts each of the 12 entries in the original grid A2:C6: F25-3101 1, F25-3102 3, F25-3103 1, F25-3104 1, F25-3105 2, F25-3102 3, F25-3107 2, F25-3106 1, F25-3109 1, F25-3107 2, F25-3105 2, F25-3102 3.
  3. repeated keeps the entries where times > 1: F25-3102, F25-3105, F25-3102, F25-3107, F25-3107, F25-3105, F25-3102. That is 7 entries, because every extra payment brings the number back.
  4. UNIQUE removes the repeats of repeated and keeps the first appearance: F25-3102, F25-3105, F25-3107. The result spills from E2 to E4.
  5. Clear B3 and C6: F25-3102 then occurs once, so only F25-3105 and F25-3107 remain in the result. Clear their second occurrences as well and FILTER shows No invoice paid twice.
  6. Debug by ending the formula on a name instead of UNIQUE(repeated): type paid, or times, as the last argument to see that intermediate result in the cells.

Watch out: The mirror-image mistake is ignore 3 'to be safe'. It also drops error cells, such as #N/A from a broken link in the export, so a payment that failed to load disappears from the test without a trace. Use 1 and look at errors first.

More on this example: why it works, 2 more pitfalls, 1 variation

Why it works

TOCOL with ignore 1 gives one list of real payments, and COUNTIF counts each against the grid, which is why its first argument must stay a range: COUNTIF refuses an array there. Scanning by column puts the findings in run order for the reviewer.

Do not use this when you must report where each duplicate sits (run and row): TOCOL throws the positions away, so use a helper column next to each run, or the Duplicate Values rule in conditional formatting, which marks the cells in place. It also needs Excel 2024 or Microsoft 365.

More to watch out for

  • Writing COUNTIF(paid, paid) gives #VALUE!, because COUNTIF needs a range as its first argument. Count against A2:C6 and use the flattened list as the criteria.
  • Leaving out ignore keeps 3 blanks as 0. Here they do no harm, because no cell equals 0, but a count of paid would say 15 instead of 12.

Variations

=LET(
  paid, TOCOL(A2:C6, 1),
  UNIQUE(FILTER(paid, COUNTIF(A2:C6, paid) > 1, "No invoice paid twice"))
)
=LET(
  paid; TOCOL(A2:C6; 1);
  UNIQUE(FILTER(paid; COUNTIF(A2:C6; paid) > 1; "No invoice paid twice"))
)

Row-wise and without the extra names: shorter, but the findings come out as F25-3105, F25-3102, F25-3107, in the order of the grid rows.

Common mistakes

Common mistakes
SymptomCauseFix
The order differs from what you expectedThe list comes out in a different order than you expected: the second row appears before the second column.The default reads row by row. Set the third argument to TRUE to read column by column, for example to list the values per bank account or per month.
Empty cells appear as 0 in the listEmpty cells show up as 0 in the list and inflate a count.The default keeps blanks and turns them into 0. Use ignore 1 to skip them, or 3 to skip errors as well.
A lookup returns a plausible but wrong valueA lookup over two TOCOL results returns a plausible but wrong value.Both TOCOL calls must use the same ignore and scan_by_column settings, otherwise position 4 in one list is not position 4 in the other.
#SPILL! although the formula is correctThe result is #SPILL! while the formula is correct.Something already sits in the cells below the formula. Clear them, or choose Select Obstructing Cells from the error menu.
#NAME? on a colleague's computerThe workbook shows #NAME? on a colleague's computer.TOCOL exists only in Excel 2024 and Microsoft 365. Older versions do not know it; check which version the file has to open in.

Used in combinations

  • Split a pasted list into a clean columnSplit a list of invoice numbers pasted into one cell on the commas, strip the stray spaces with TRIM and stack the pieces into one column with TOCOL, ready for matching.Excel 2024 or later (This combination needs Excel 2024 or later)
  • Two-way lookup with one XLOOKUP and TOCOLFind the value where a row label and a column header meet, by turning both conditions into one grid of 0s and 1s and flattening it with TOCOL.Excel 2024 or later (This combination needs Excel 2024 or later)