OFFSET
VERSCHUIVING in Dutch Excel
Returns a reference to the cell or block a set number of rows and columns from a start cell, optionally resized.
Last updated: 13 October 2026
| Row | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| 1 | Account | Description | Balance | Line no. | Balance | |
| 2 | 11001100 | Bank | €84,350.00€ 84.350,00 | 44 | €645,200.00€ 645.200,00=OFFSET(C1, E2, 0)=OFFSET(C1; E2; 0) | |
| 3 | 13001300 | Trade receivables | €212,480.00€ 212.480,00 | |||
| 4 | 16001600 | Trade payables | -€156,920.00€ -156.920,00 | |||
| 5 | 40004000 | Personnel costs | €645,200.00€ 645.200,00 | |||
| 6 | 45004500 | Housing costs | €230,400.00€ 230.400,00 | |||
| 7 | 80008000 | Revenue | -€1,482,600.00€ -1.482.600,00 |
Swipe sideways to see all columns
Result: €645,200.00€ 645.200,00
=OFFSET(C1,E2, 0)
=OFFSET(C1;E2; 0)
What OFFSET does and when to use it
What it does: it starts at a cell, moves a number of rows and columns, and returns a reference to what it finds there, for example the balance of the trial balance line you pick by number.
When to use it: for ranges that move or grow, such as the last three months or a rolling four-week total. Inside SUM or AVERAGE it hands over a range whose position and size are calculated. It is volatile, so in large workbooks INDEX is often the lighter choice.
How Excel evaluates it
Excel works from the top-left cell of reference:
- it moves rows down (or up when negative) and cols to the right (or left when negative)
- it marks out a block height rows tall and width columns wide from the cell it lands on, defaulting to the size of reference
- it returns a reference to that block, not a copy of the values, so the function around it works on the cells themselves
If any part of the block falls off the sheet, the result is #REF!.
Watch out: OFFSET is volatile, so Excel recalculates it after every change anywhere in the workbook. In large models INDEX is usually the better tool: INDEX(range, n):INDEX(range, m) builds the same moving range without being volatile.
Mental model
A picture frame you place on the grid: rows and cols say where to put its top-left corner relative to the anchor, height and width say how big the frame is, and the surrounding function reads whatever shows through it.
Terms used on this page: worksheet, reference, workbook, range, cell
OFFSET(reference,rows, cols, [height], [width])
OFFSET(reference;rows; cols; [height]; [width])
| Argument | Type | Meaning | Default |
|---|---|---|---|
reference | Required | The starting cell or range. | |
rows | Required | How many rows to move down; negative moves up. | |
cols | Required | How many columns to move right; negative moves left. | |
height | Optional | The number of rows in the result. | height of reference |
width | Optional | The number of columns in the result. | width of reference |
Return value:A reference to a cell or range, which shows as the value of that cell or feeds another function
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
Trial balance line chosen by number
You are tying a client's trial balance (saldibalans) to the general ledger. The list has one line per account, and Sanne de Vries, your senior, gives you the line numbers to check.
Type a line number and see that line's balance. Line 4 is account 4000, and it sits 4 rows below the header.
| Row | A | B | C | D | E | F | G |
|---|---|---|---|---|---|---|---|
| 1 | Account | Description | Balance | Line no. | Balance | ||
| 2 | 11001100 | Bank | €84,350.00€ 84.350,00 | 44 | €645,200.00€ 645.200,00=OFFSET(C1, E2, 0)=OFFSET(C1; E2; 0) | ||
| 3 | 13001300 | Trade receivables | €212,480.00€ 212.480,00 | ||||
| 4 | 16001600 | Trade payables | -€156,920.00€ -156.920,00 | ||||
| 5 | 40004000 | Personnel costs | €645,200.00€ 645.200,00 | ||||
| 6 | 45004500 | Housing costs | €230,400.00€ 230.400,00 | ||||
| 7 | 80008000 | Revenue | -€1,482,600.00€ -1.482.600,00 | ||||
| 8 |
Swipe sideways to see all columns
Formula in F2
=OFFSET(C1,E2, 0)
=OFFSET(C1;E2; 0)
Result: €645,200.00€ 645.200,00
Step by step
- Excel takes the anchor,
C1, the Balance header. - It reads
E2: 4. It moves 4 rows down fromC1:C2,C3,C4,C5. It lands onC5, the line for account 4000. - cols is 0, so it stays in column C. height and width are left out, so the result is one cell, the same size as
C1. - OFFSET returns a reference to
C5, and the cell shows its value: 645200, the balance of Personnel costs. - Type 6 in
E2and OFFSET moves 6 rows toC7, the Revenue line: -1482600.
Watch out: Type 0 in E2 and you get the header text, Balance. Type 7 and OFFSET points at the empty C8, which shows 0: a plausible balance for an account that is not on the list.
More on this example: why it works, 1 more pitfall
Why it works
Anchoring on the header means the line number and the number of rows to move are the same thing: line 1 is one row below the header. OFFSET only counts; it never checks which account is in the row, so the layout of the list is what makes the answer right.
More to watch out for
- The client sends a new version with a total line inserted between the header and account 1100. The accounts shift down while the anchor stays at
C1, so every line number now returns the account before it. INDEX(C2:C7, E2) moves its range along with the data.
Intermediate
Last four periods of payroll costs
You reconcile account 4000 (Personeelskosten) from the XAF auditfile to the client's payroll summary (loonjournaal) per period. Veldhuis Installatie BV has not booked period 5 yet, so that cell is blank. Type the last period and get the total of that period and the three before it, to compare with the specification.
| Row | A | B | C | D | E | F |
|---|---|---|---|---|---|---|
| 1 | Period | Debit 4000 | Last period | 77 | ||
| 2 | 11 | €118,400.00€ 118.400,00 | Total 4 periods | €374,900.00€ 374.900,00=SUM(OFFSET(B1, E1 - 3, 0, 4, 1))=SUM(OFFSET(B1; E1 - 3; 0; 4; 1)) | ||
| 3 | 22 | €121,050.00€ 121.050,00 | ||||
| 4 | 33 | €119,800.00€ 119.800,00 | ||||
| 5 | 44 | €123,300.00€ 123.300,00 | ||||
| 6 | 55 | |||||
| 7 | 66 | €126,900.00€ 126.900,00 | ||||
| 8 | 77 | €124,700.00€ 124.700,00 | ||||
| 9 | 88 | €125,350.00€ 125.350,00 | ||||
| 10 |
Swipe sideways to see all columns
Formula in E2
=SUM(OFFSET(B1,E1 - 3, 0, 4, 1))
=SUM(OFFSET(B1;E1 - 3; 0; 4; 1))
Result: €374,900.00€ 374.900,00
Step by step
- Excel calculates rows first: E1 - 3 = 7 - 3 = 4. The window must start three periods before period 7, at period 4.
- OFFSET moves 4 rows down from
B1and lands onB5, the period 4 row. - height is 4 and width is 1, so OFFSET stretches the result to
B5:B8: periods 4, 5, 6 and 7. - SUM adds the block.
B6(period 5) is blank and SUM skips it: 123300 + 126900 + 124700 = 374900. - Without height and width, OFFSET would return only
B5, the size of the anchor, and the result would be 123300. The two optional arguments turn one cell into a window. - Change
E1to 8: rows becomes 5, the window isB6:B9, and the total is 0 + 126900 + 124700 + 125350 = 376950.
Watch out: Enter period 2 or lower. rows becomes -1 or less, which points above row 1, and the result is #REF!. Period 3 gives rows 0: the window is B1:B4, the header is ignored by SUM, and you silently get periods 1 to 3: 359250.
More on this example: why it works, 1 more pitfall, 1 variation
Why it works
rows decides where the window starts and height decides how long it is, so moving the last period moves the whole window without changing its size. OFFSET hands SUM a real range, which is why the unbooked period is skipped instead of breaking the total.
More to watch out for
- The unbooked period counts as one of the four, so this total covers three periods of payroll. The difference with the loonjournaal is then a missing booking, not an error in the formula.
Variations
=SUM(INDEX(B2:B9,E1 - 3):INDEX(B2:B9, E1))
=SUM(INDEX(B2:B9;E1 - 3):INDEX(B2:B9; E1))
The non-volatile version: two INDEX functions mark the first and last cell of the window.
Advanced
Average of the last three month-end balances in a growing list
Your working paper on debtors (account 1300) takes the month-end balance from the receivables aging list (ouderdomsanalyse debiteuren) as the client delivers each month. The sheet is laid out for the whole year, but only the months delivered so far are filled in. A cell must always show the average of the three most recent month-ends, for your analytical review, without editing the formula each month.
| Row | A | B | C | D | E |
|---|---|---|---|---|---|
| 1 | Month | Debtors 1300 | Average last 3 | ||
| 2 | Jan | €198,500.00€ 198.500,00 | €219,300.00€ 219.300,00=AVERAGE(OFFSET(B1, COUNT(B2:B9) - 2, 0, 3, 1))=AVERAGE(OFFSET(B1; COUNT(B2:B9) - 2; 0; 3; 1)) | ||
| 3 | Feb | €205,300.00€ 205.300,00 | |||
| 4 | Mar | €214,800.00€ 214.800,00 | |||
| 5 | Apr | €209,600.00€ 209.600,00 | |||
| 6 | May | €221,400.00€ 221.400,00 | |||
| 7 | Jun | €226,900.00€ 226.900,00 | |||
| 8 | Jul | ||||
| 9 | Aug | ||||
| 10 |
Swipe sideways to see all columns
Formula in D2
=AVERAGE(OFFSET(B1,COUNT(B2:B9) - 2, 0, 3, 1))
=AVERAGE(OFFSET(B1;COUNT(B2:B9) - 2; 0; 3; 1))
Result: €219,300.00€ 219.300,00
Step by step
- Excel starts inside: COUNT(B2:B9) counts the cells that hold numbers. January to June are filled, July and August are blank, so COUNT returns 6.
- rows becomes 6 - 2 = 4. The last filled month is 6 rows below
B1, and a three-month window has to start two rows earlier. - OFFSET moves 4 rows down from
B1toB5(April) and, with height 3 and width 1, returnsB5:B7: April, May and June. - AVERAGE works on that range: (209600 + 221400 + 226900) / 3 = 657900 / 3 = 219300.
- Enter 231500 for July in
B8. COUNT becomes 7, rows becomes 5, the window moves toB6:B8, and the average becomes (221400 + 226900 + 231500) / 3 = 679800 / 3 = 226600.
Watch out: If a month is skipped, say March is left blank while July is filled, COUNT is still 6, but the last balance sits in B8. The window stays at B5:B7 and silently leaves out July.
More on this example: why it works, 2 more pitfalls, 2 variations
Why it works
COUNT turns 'how far has the list grown?' into a number, and OFFSET turns that number into a position. Because the balances are entered top to bottom without gaps, the count of numbers equals the row of the last balance, which is the assumption the whole formula rests on.
More to watch out for
- A balance pasted from the client's export as text, for example 226900 with a trailing space, is not counted by COUNT and not averaged. The window shifts and the average changes without an error.
- With fewer than 3 balances, rows drops to 0 or below and the window includes the header or falls off the sheet.
Variations
=AVERAGE(INDEX(B2:B9,COUNT(B2:B9) - 2):INDEX(B2:B9, COUNT(B2:B9)))
=AVERAGE(INDEX(B2:B9;COUNT(B2:B9) - 2):INDEX(B2:B9; COUNT(B2:B9)))
The same window built with INDEX: not volatile, so it recalculates only when the balances change.
=AVERAGE(TAKE(FILTER(B2:B9,B2:B9 <> ""), -3))
=AVERAGE(TAKE(FILTER(B2:B9;B2:B9 <> ""); -3))
Excel 2024 or Microsoft 365: FILTER drops the blanks and TAKE keeps the last three, so a skipped month no longer shifts the window.
MasterExcel 2021 or later (This example needs Excel 2021 or later)
Cost account movement over a chosen window of periods
You test the movement of cost accounts per period from the XAF auditfile against the client's specification. Pick an account, an end period and a number of periods, and get the total over that trailing window.
Early in the year the window may be longer than the periods available, and the formula must cope instead of reaching into the account column.
| Row | A | B | C | D | E | F | G | H | I | J |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Account | Jan | Feb | Mar | Apr | May | Account | 45004500 | ||
| 2 | 40004000 | €118,400.00€ 118.400,00 | €121,050.00€ 121.050,00 | €119,800.00€ 119.800,00 | €123,300.00€ 123.300,00 | €126,900.00€ 126.900,00 | End period | Apr | ||
| 3 | 45004500 | €18,500.00€ 18.500,00 | €18,500.00€ 18.500,00 | €18,500.00€ 18.500,00 | €19,200.00€ 19.200,00 | €19,200.00€ 19.200,00 | Periods | 33 | ||
| 4 | 46004600 | €6,240.00€ 6.240,00 | €5,890.00€ 5.890,00 | €7,120.00€ 7.120,00 | €6,480.00€ 6.480,00 | €6,955.00€ 6.955,00 | Total | €56,200.00€ 56.200,00=LET( accRow, MATCH(I1, A2:A5, 0), perCol, MATCH(I2, B1:F1, 0), span, MIN(I3, perCol), SUM(OFFSET(A1, accRow, perCol - span + 1, 1, span)) )=LET( accRow; MATCH(I1; A2:A5; 0); perCol; MATCH(I2; B1:F1; 0); span; MIN(I3; perCol); SUM(OFFSET(A1; accRow; perCol - span + 1; 1; span)) ) | ||
| 5 | 47004700 | €3,120.00€ 3.120,00 | €2,870.00€ 2.870,00 | €3,410.00€ 3.410,00 | €2,950.00€ 2.950,00 | €3,680.00€ 3.680,00 | ||||
| 6 |
Swipe sideways to see all columns
Formula in I4
=LET( accRow,MATCH(I1, A2:A5, 0), perCol, MATCH(I2, B1:F1, 0), span, MIN(I3, perCol), SUM(OFFSET(A1, accRow, perCol - span + 1, 1, span)) )
=LET( accRow;MATCH(I1; A2:A5; 0); perCol; MATCH(I2; B1:F1; 0); span; MIN(I3; perCol); SUM(OFFSET(A1; accRow; perCol - span + 1; 1; span)) )
Result: €56,200.00€ 56.200,00
Step by step
- accRow: MATCH finds 4500 in the second cell of
A2:A5, so accRow is 2. Counting fromA1, that is row 3 of the sheet. - perCol: MATCH finds
Aprin the fourth cell ofB1:F1, so perCol is 4. Counting from column A, that is column E. - span: MIN(3, 4) = 3. Three periods fit up to April, so the requested window is kept.
- OFFSET starts at
A1, moves accRow = 2 rows down and perCol - span + 1 = 4 - 3 + 1 = 2 columns right, landing onC3(February). With height 1 and width 3 it returnsC3:E3: February, March and April. - SUM adds the window: 18500 + 18500 + 19200 = 56200.
- Set
I3to 6. span becomes MIN(6, 4) = 4, the column offset becomes 4 - 4 + 1 = 1, the window isB3:E3, and the total is 18500 + 18500 + 18500 + 19200 = 74700. Without MIN, the offset would be -1, left of column A, and the result #REF!.
Watch out: The mirror-image mistake: swapping height and width, OFFSET(A1, accRow, perCol - span + 1, span, 1). It returns C3:C5, February for three different accounts: 18500 + 5890 + 2870 = 27260. A plausible number with the wrong meaning.
More on this example: why it works, 2 more pitfalls, 2 variations
Why it works
Anchoring on A1, the corner of the grid, makes both MATCH positions usable as offsets without any +1 or -1 corrections; only the window start needs the + 1. MIN caps the window at the periods that exist, an edge case OFFSET would otherwise turn into #REF! or, with a window one period too long, into a silent sum that includes the account column.
Do not use this construction in a large model with many such cells: OFFSET is volatile and recalculates after every edit in the workbook.
The alternative is SUM(INDEX(B2:F5, accRow, perCol - span + 1):INDEX(B2:F5, accRow, perCol)), which gives the same 56200 and recalculates only when its inputs change, at the cost of a longer formula.
More to watch out for
- Dropping the + 1 shifts the window one period back, to January through March: 18500 + 18500 + 18500 = 55500. Test with a window of 1 period, which must return the end period alone.
- A window of 0 periods makes span 0, and OFFSET with width 0 returns #REF!. Validate
I3with data validation if people type it by hand.
Variations
=SUM(OFFSET(A1,MATCH(I1, A2:A5, 0), MATCH(I2, B1:F1, 0) - I3 + 1, 1, I3))
=SUM(OFFSET(A1;MATCH(I1; A2:A5; 0); MATCH(I2; B1:F1; 0) - I3 + 1; 1; I3))
The same without LET and without the cap: shorter, and fine when the window can never be longer than the periods available.
=LET( accRow,MATCH(I1, A2:A5, 0), perCol, MATCH(I2, B1:F1, 0), span, MIN(I3, perCol), SUM(INDEX(B2:F5, accRow, perCol - span + 1):INDEX(B2:F5, accRow, perCol)) )
=LET( accRow;MATCH(I1; A2:A5; 0); perCol; MATCH(I2; B1:F1; 0); span; MIN(I3; perCol); SUM(INDEX(B2:F5; accRow; perCol - span + 1):INDEX(B2:F5; accRow; perCol)) )
The non-volatile INDEX version of the same logic, for large workbooks.
Common mistakes
| Symptom | Cause | Fix |
|---|---|---|
| Every result is one row off | Counting from the first data row instead of the anchor, so every result is one row off. | rows = 0 is the anchor itself. Anchor on the header cell when you want rows = 1 to mean the first data row. |
| The workbook pauses after every edit | The workbook becomes sluggish: every edit triggers a pause while Excel recalculates. | Replace OFFSET with INDEX:INDEX ranges, which recalculate only when their inputs change. |
| A plausible number from the wrong place | height and width are swapped with rows and cols, and the formula returns a number from the wrong place that still looks plausible. | Read the arguments as 'move rows, move columns, then size rows, size columns', and test with an input where you know the answer. |
| Three values spill, or only one | A cell with only =OFFSET(B1, 1, 0, 3, 1) shows three values spilling down. In versions before dynamic arrays it shows a single value instead: the one on the formula's own row, or #VALUE! when none lines up. | A multi-cell OFFSET needs a function around it, such as SUM or AVERAGE, when you want one number. |