この記事で分かること

  • OFFSET・INDIRECT関数の正しい構文と、実務で使い道がある具体的な場面
  • 「揮発性関数」とは何か、OFFSET・INDIRECTがなぜ重い財務モデルで負荷になるのかという仕組み
  • INDEXを使った非揮発な代替設計、INDIRECTを使わずに済む集約テーブル設計への組み替え方
  • どうしてもOFFSET・INDIRECTが必要な場面の見極め方と、導入前に確認すべきチェックリスト

結論:OFFSET・INDIRECTは動的参照を作れるが、変更点と無関係に毎回再計算される

OFFSETとINDIRECTは、どちらも「参照先を数式の中で動的に組み立てる」ための関数です。基準セルからの移動量や、セルに入力された文字列をもとに、あらかじめ固定されていない参照を作れる点が最大の利点で、範囲が伸び縮みする集計や、シート名を可変にした集計を1つの数式でまかなえます。一方でこの2つの関数には、Excelの計算エンジンが「揮発性関数」として扱うという共通の性質があります。揮発性関数は、自分自身の参照先が実際に変わったかどうかに関係なく、Excelが再計算を行うたびに必ず再評価され、さらにその数式に依存するすべてのセルも連鎖して再計算されます。数式が数個程度なら気にする必要はありませんが、数百・数千のセルにOFFSETやINDIRECTが埋め込まれた大きな財務モデルでは、無関係なセルを1つ編集しただけでも、それらすべてが毎回再計算の対象になり、ファイルの応答が遅くなる原因になります。

結論として、OFFSET・INDIRECTは「動的参照を作れる万能ツール」ではなく、「揮発性というコストを払って動的参照を作る手段の1つ」だと捉えるのが実務的です。多くの場面では、INDEXを使った参照や、データ構造そのものを見直す設計に置き換えることで、同じ動的な挙動を非揮発のまま実現できます。以下では、まずOFFSETとINDIRECTそれぞれの正しい構文と使いどころを確認したうえで、揮発性関数が重いモデルで問題になる仕組みと、INDEXや集約テーブルへの具体的な置き換え方を、検算可能な仮設例の数値で確認していきます。なお、重い財務モデル全般の速度診断の進め方は重い財務モデルの高速化で扱っており、本記事はそこで「5大犯人」の1つとして触れられている揮発性関数、特にOFFSETとINDIRECTに絞って掘り下げます。

OFFSET関数の構文と正しい使い方

OFFSET関数は、基準セルから指定した行数・列数だけ移動した位置を起点に、指定した高さ・幅の範囲を返す関数です。構文は次のとおりです。

OFFSET関数の構文
OFFSET(基準, 行数, 列数, [高さ], [幅])
基準セルから「行数」「列数」だけ移動した位置を起点に、「高さ」行×「幅」列の範囲を返す。高さ・幅を省略すると基準(参照)と同じサイズの参照になる(本記事の設例のように基準が単一セルの場合は1行1列になる)。

以下は説明用の仮設例です。あるモデルの1行目に1月から12月までの月ラベル、2行目にその月の売上高(百万円)を入力しているとします。B列が1月、M列が12月に対応し、値は「100・108・112・120・115・130・128・135・140・138・150・160」(百万円)だとします。

セル売上高(百万円)
1月B2100
2月C2108
3月D2112
4月E2120
5月F2115
6月G2130
7月H2128
8月I2135
9月J2140
10月K2138
11月L2150
12月M2160

正しい使い方1:入力済みの月数だけ自動で伸びる累計範囲

以下は説明用の仮設例です。実際には1月から6月までしか実績が入力されておらず、7月以降のセル(H2:M2)はまだ空欄だとします。この状態で「入力済みの月数分だけ」を自動集計するには、次のようにOFFSETとCOUNTを組み合わせます。

累計範囲を自動で伸ばすOFFSET
=SUM(OFFSET($B$2,0,0,1,COUNT($B$2:$M$2)))

COUNT($B$2:$M$2)は数値が入力されているセルの個数を数えるため、1月から6月までしか値がない状態ではCOUNTは6を返します。したがってOFFSET($B$2,0,0,1,6)はB2からG2までの範囲(1月〜6月)を返し、SUMの計算結果は100+108+112+120+115+130=685(百万円)になります。ここで7月分の実績128(百万円)がH2に入力されると、COUNTは7に変わり、OFFSETが返す範囲は自動的にB2:H2(1月〜7月)に広がって、合計は685+128=813(百万円)に更新されます。数式そのものは1つも書き換えていない点がOFFSETの利点で、月次実績が積み上がっていくモデルで、累計欄の数式を毎月手作業で直す必要がなくなります。

正しい使い方2:window幅を可変にした移動平均

以下は説明用の仮設例です。前掲の12か月分の売上高データについて、直近の何か月分を平均するかを1つのセル(ここでは仮に$B$4とします)で切り替えられる、移動平均の仕組みを作るとします。$B$4には移動平均の対象月数(以下ではNと呼びます)を入力し、直近月は12月(M2)で固定します。

window幅が可変の移動平均
=AVERAGE(OFFSET($M$2,0,-($B$4-1),1,$B$4))

$B$4に3を入力した場合、-($B$4-1)は-2になるため、OFFSET($M$2,0,-2,1,3)はM2から2列左のK2を起点に、高さ1行・幅3列の範囲、つまりK2:M2(10月・11月・12月)を返します。K2:M2の値は138・150・160なので、平均は(138+150+160)÷3=448÷3で約149.3(百万円)です。$B$4を6に変更すると、-($B$4-1)は-5になり、OFFSET($M$2,0,-5,1,6)はH2:M2(7月〜12月)を返します。この6か月の値は128・135・140・138・150・160で、平均は(128+135+140+138+150+160)÷6=851÷6で約141.8(百万円)です。数式を書き換えることなく、パラメータのセルを変えるだけで集計対象の幅が切り替わる点が、OFFSETが移動平均の実装でよく紹介される理由です。

OFFSET関数の引数が指す範囲(移動平均の設例) 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 100 108 112 120 115 130 128 135 140 138 150 160 B2 C2 D2 E2 F2 G2 H2 I2 J2 K2 L2 M2 基準セル=M2、返す範囲=K2:M2(青枠)=OFFSET(M2,0,-2,1,3)
図:設例。OFFSET(M2,0,-2,1,3)は基準セルM2から2列左のK2を起点に、高さ1行・幅3列の範囲(K2:M2)を返す。

INDIRECT関数の構文と正しい使い方

INDIRECT関数は、文字列として与えられた参照を、実際のセル参照として解釈し直す関数です。構文は次のとおりです。

INDIRECT関数の構文
INDIRECT(参照文字列, [A1形式か])
「参照文字列」で指定した文字列を、通常のセル参照とみなして値を返す。文字列はセル参照そのものを直接書いてもよいし、文字列を組み立てる数式(文字列の連結など)でもよい。

以下は説明用の仮設例です。3つの事業部(A事業部・B事業部・C事業部)がそれぞれ別のシートに実績を持ち、各シートのC10セルに営業利益(百万円)が入力されているとします。A事業部C10=45、B事業部C10=62、C事業部C10=38です。集計用のシートには、A列に事業部名を文字列で並べておき(A1=”A事業部”、A2=”B事業部”、A3=”C事業部”)、B列に次の数式を入れて下方向にコピーします。

シート名を可変にする集計
=INDIRECT(“‘”&A1&”‘!C10”)

A1が「A事業部」であれば、この数式は’A事業部’!C10という参照文字列を組み立て、その値である45を返します。同様にA2・A3の行はそれぞれ62・38を返し、B1:B3の合計は45+62+38=145(百万円)になります。ここでINDIRECTを使う理由は、単に「シート名が可変だから」ではありません。通常のシート参照(=’A事業部’!C10のような直接参照)は、行をコピーしてもシート名まで自動で変わってはくれないため、事業部が増えるたびにシートごとに別の数式を1つずつ手で書く必要があります。INDIRECTを使えば、A列に並べた事業部名という文字列から、1つの数式を下にコピーするだけで全事業部分の参照を組み立てられる、という点が実務上の利点です。

揮発性関数が重い財務モデルで問題になる仕組み

Excelは、数式同士の依存関係を「依存ツリー」として管理し、あるセルの値が変わったときに、その変化の影響を受けるセルだけを再計算する仕組みを持っています。これによって、実際には変わっていない大量の数式を毎回すべて計算し直す無駄を省いています。ところが一部の関数は、この依存関係の仕組みの外側で扱われ、「揮発性関数」として、Excelが再計算を行うたびに、自分自身の参照先が変わったかどうかに関係なく必ず再評価されます。Microsoftの開発者向けドキュメントでも、揮発性関数について次のように説明されています。

「Excel supports the concept of a volatile function, that is, one whose value cannot be assumed to be the same from one moment to the next even if none of its arguments (if it takes any) has changed. Excel reevaluates cells that contain volatile functions, together with all dependents, every time that it recalculates.」(Excel Recalculation, Microsoft Learn)。同じページでは、揮発性関数としてNOW・TODAY・RANDBETWEEN・OFFSET・INDIRECT・INFO(引数による)・CELL(引数による)・SUMIF(引数による)が挙げられています。これに加えてRAND関数も、別のMicrosoftの解説(Excel performance – Improving calculation performance)で「obviously volatile」な関数として名前が挙がっています。つまり、日付・時刻を返すNOW・TODAY、乱数を返すRAND・RANDBETWEEN、そして参照を動的に組み立てるOFFSET・INDIRECTが、代表的な揮発性関数です。

ここで注意したいのが、INDEX関数の扱いです。INDEX関数も「参照(reference)を返す」関数であり、見た目にはOFFSETと似ていますが、揮発性関数ではありません。同じMicrosoftの解説では「Some functions that have previously been documented as volatile are not in fact volatile: INDEX(), ROWS(), COLUMNS(), AREAS().」と明記されており、INDEXは参照を返す関数でありながら、Excelの依存関係の仕組みの中で扱われるため、参照先が実際に変わったときだけ再計算されます。「参照を返す関数だから揮発性になる」という理解は誤りで、揮発性かどうかはExcelが個々の関数ごとに定めている性質であり、INDEXはその対象に含まれていません。この違いが、後述するINDEXへの置き換えが有効な理由の技術的な根拠になります。

大きな財務モデルでこの性質が問題になるのは、揮発性関数を含む数式が「その数式に依存するすべてのセル」と一緒に、毎回の再計算のたびに再評価されるためです。モデルの片隅にある無関係なセルを1つ編集しただけでも、ワークシート全体、あるいはブック全体に散らばったOFFSETやINDIRECTの数式が、対象の値が変わっていなくてもすべて再評価され、そこから連なる下流の数式も連鎖して再計算されます。同じ資料は「Avoid volatile functions such as INDIRECT and OFFSET where you can, unless they are significantly more efficient than the alternatives. (Well-designed use of OFFSET is often fast.)」とも述べており、揮発性であること自体が即座に「遅い」ことを意味するわけではなく、数式の設計や使用箇所の広さによって影響の大きさが変わる、という点も押さえておく必要があります。なお、モデル全体の再計算が遅くなる原因は揮発性関数だけではなく、参照範囲の肥大化や配列数式の多用など複数の要因が重なって起こることが一般的で、原因の切り分け方や診断の進め方は重い財務モデルの高速化で扱っています。

代替設計1:INDEXで動的参照を非揮発化する

OFFSETが返す範囲は、INDEX関数を使って「範囲の終点(または始点)をINDEXで指定する」という書き方に置き換えられることがよくあります。INDEXは指定した位置のセル参照を返すだけの関数で、それ自体は揮発性ではないため、同じ動的な範囲をExcelの依存関係の仕組みの中に戻すことができます。

累計範囲:SUMの終点をINDEXで指定する

OFFSET版
=SUM(OFFSET($B$2,0,0,1,COUNT($B$2:$M$2)))
INDEX版(非揮発)
=SUM($B$2:INDEX($B$2:$M$2,COUNT($B$2:$M$2)))

1月から6月まで入力済みの状態では、COUNT($B$2:$M$2)は6を返すため、INDEX($B$2:$M$2,6)はB2:M2の6番目のセル、つまりG2を返します。したがって$B$2:INDEX($B$2:$M$2,6)は$B$2:G2という範囲になり、SUMの結果は100+108+112+120+115+130=685(百万円)で、OFFSET版と完全に一致します。7月分の128(百万円)がH2に入力されると、COUNTは7に変わり、INDEX($B$2:$M$2,7)はH2を返すため、範囲は$B$2:H2に広がって合計は813(百万円)に更新されます。数式の見た目はOFFSET版より少し複雑になりますが、INDEXは参照先が実際に変わったときだけ再計算されるため、モデル全体の揮発性を増やさずに同じ「自動で伸びる累計」を実現できます。

移動平均:範囲の始点と終点を2つのINDEXで挟む

OFFSET版
=AVERAGE(OFFSET($M$2,0,-($B$4-1),1,$B$4))
INDEX版(非揮発)
=AVERAGE(INDEX($B$2:$M$2,12-$B$4+1):INDEX($B$2:$M$2,12))

12月(M2)はB2:M2の中で12番目のセルにあたるため、終点は常にINDEX($B$2:$M$2,12)、つまりM2で固定です。$B$4に3を入力した場合、始点は12-3+1=10番目のセル、つまりINDEX($B$2:$M$2,10)でK2になります。したがってINDEX($B$2:$M$2,10):INDEX($B$2:$M$2,12)はK2:M2という範囲を表し、AVERAGEの結果は(138+150+160)÷3で約149.3(百万円)となり、OFFSET版と一致します。$B$4を6に変更すると、始点は12-6+1=7番目のセル、つまりH2になり、範囲はH2:M2に広がって平均は(128+135+140+138+150+160)÷6で約141.8(百万円)になります。ここでもOFFSET版と結果は完全に一致しますが、INDEXは参照先の値が変わったときだけ再計算される非揮発な関数のため、この数式を大量の行にコピーしても、揮発性関数のように「無関係な編集のたびに全件が再計算される」ということが起こりません。なお、INDEXそのものの使い方や、VLOOKUPからの卒業という観点についてはINDEX/MATCHとXLOOKUP実践で詳しく扱っています。

代替設計2:INDIRECTをやめて集約テーブル+SUMIFSにする

INDIRECTの置き換えは、INDEXのような「関数を差し替えるだけ」では済まないことが多く、データの持ち方そのものを見直す必要があります。前掲の事業部別シートの例では、事業部が増えるたびにシートが増え、集計側もINDIRECTで文字列からシート参照を組み立てる、という設計になっていました。この設計を、1枚の集約テーブルに実績を並べる「縦持ち」の形に変えると、INDIRECTを使わずに同じ集計ができます。

以下は説明用の仮設例です。「実績データ」という1枚のシートに、事業部・科目・金額の3列で実績を並べ替えます。

事業部科目金額(百万円)
A事業部営業利益45
B事業部営業利益62
C事業部営業利益38

集計シート側のA列に事業部名(A1=”A事業部”など)を並べたまま、B列の数式だけを次のように変えます。

集約テーブル+SUMIFS(非揮発)
=SUMIFS(実績データ!$C:$C, 実績データ!$A:$A, A1, 実績データ!$B:$B, “営業利益”)

A1が「A事業部」であればSUMIFSは実績データの事業部列がA事業部、科目列が営業利益に一致する行の金額を合計し、45を返します。同様にA2「B事業部」で62、A3「C事業部」で38を返し、合計は45+62+38=145(百万円)となり、INDIRECT版と完全に一致します。この方式では、シート名を文字列から組み立てる必要がそもそもなくなるため、INDIRECTを使わずに済みます。事業部が増えても、実績データシートに行を追加するだけでよく、シートを新しく作る必要もありません。SUMIFS自体は揮発性関数ではありませんが、条件範囲を列全体($C:$Cなど)で指定すると使用セル数が増えて計算コストが上がるため、実際の運用では表として整形した範囲(構造化参照)に絞り込むと効率的です。表・構造化参照の使い方はExcelテーブル機能と構造化参照で解説しています。SUMIFSの条件指定やAND/OR条件の組み方についてはSUMIFS関数の使い方を参照してください。

下の表は、ここまでの2つの置き換えパターンを整理したものです。いずれも計算結果はもとのOFFSET・INDIRECT版と一致しており、非揮発の代替設計に置き換えても、モデルが返す数値そのものは変わらないことが確認できます。

用途揮発性関数版非揮発の代替結果
自動で伸びる累計範囲OFFSET+COUNTSUM($B$2:INDEX(…))685→813
window可変の移動平均OFFSETINDEX(…):INDEX(…)149.3
事業部別シート集計INDIRECT集約テーブル+SUMIFS145
揮発性関数はなぜ重いモデルで負荷になるのか ワークブックのどこかのセルを編集 (変更箇所と無関係でもよい) OFFSET・INDIRECTを含む数式 (他の変更と無関係に毎回再計算) INDEXなど非揮発関数を含む数式 (参照先が変わった時だけ再計算) 依存する全セルも連鎖して再計算 → 数式が多いほど毎回の負荷が増える 実際に変わった所だけ再計算 → 数式が多くても負荷が積み上がりにくい
図:Microsoft Learn「Excel Recalculation」等の解説に基づき大手町プレップ作成。揮発性関数は自身の変更点に関係なく毎回再計算され、依存するセルも連鎖して再計算される。

既存モデルのOFFSET・INDIRECTを棚卸ししたい方へ

自分が引き継いだモデルにOFFSETやINDIRECTがどれだけ埋め込まれているかは、数式バーの表示だけでは把握しづらいものです。数式監査の機能を使って参照関係を可視化し、置き換えの優先順位をつける進め方を体系的に確認したい場合は、以下の教材も参考にしてください。

→ Excel関数・モデリングの教材を見る

どうしてもOFFSET・INDIRECTが必要な場面と導入前チェックリスト

ここまでの内容は「OFFSETとINDIRECTを一切使うな」という趣旨ではありません。Microsoftの解説にも「Well-designed use of OFFSET is often fast.」とあるとおり、設計次第では実務上問題にならない使い方も存在します。おおむね次のような場面では、揮発性のコストを許容してOFFSET・INDIRECTを使う判断が合理的です。

1つ目は、ユーザーが操作する入力セル(移動平均のNなど)に応じて表示範囲を即座に切り替える、少数のダッシュボード用セルに限定して使う場面です。数式の個数が数十程度にとどまり、モデル全体の再計算時間に占める割合が小さいのであれば、揮発性のコストよりも数式のシンプルさを優先しても実務上支障はありません。2つ目は、グラフの参照範囲を自動で伸ばす目的で、名前定義とOFFSETを組み合わせる伝統的な手法です。ただしこの用途については、自動的に範囲が広がるExcelのテーブル機能(構造化参照)という非揮発の代替が存在するため、新規にモデルを作る場合はテーブル機能を優先し、OFFSETは既存モデルの制約でテーブル化が難しい場合の次善手と位置づけるのが実務的です。名前定義そのものの使いどころと乱用しない規律については名前定義と構造化参照で扱っています。3つ目は、数式監査や一時的な調査のために、担当者が入力したセル番地やシート名をもとに値を確認する、使用頻度の低いユーティリティ的なセルでINDIRECTを使う場面です。モデルの中核的な集計ロジックではなく、限られた範囲の補助的な確認用途であれば、揮発性のコストは限定的です。

逆に、次のような場面では非揮発の代替設計への置き換えを優先すべきです。同じ関数が数百行・数千行にわたってコピーされている場合、複数のシートにまたがって同種の数式が繰り返し使われている場合、そしてモデルの再計算時間そのものが既に業務上のボトルネックになっている場合です。導入・置き換えを判断する前に、次の点を確認することをおすすめします。

導入前チェックリスト

  • OFFSET・INDIRECTを使う数式は何個あり、モデル全体の何%程度を占めているか
  • 同じ動的参照を、INDEXの組み合わせや集約テーブル+SUMIFSで代替できないか検討したか
  • グラフ範囲の自動拡張が目的であれば、テーブル機能(構造化参照)で代替できないか確認したか
  • 置き換え後の数式が、置き換え前と同じ結果を返すことを実際の数値で検算したか
  • ダッシュボード用の少数セルなど、揮発性のコストを許容してよい範囲を明確にしたか

よくある質問(FAQ)

Q. OFFSETとINDIRECT、どちらがより重くなりやすいですか。
A. どちらも揮発性関数である点は共通ですが、Microsoftの解説では、INDIRECTはCELL(引数による)・GETPIVOTDATA・ADDRESS(シート名指定時)などと並んで「単一スレッドでしか計算できない関数」の1つとして挙げられています。複数コアを使った並列計算の恩恵を受けにくいという意味では、INDIRECTのほうが大規模なモデルで影響が出やすい場面があります。ただし実際の影響度は数式の個数や配置によって変わるため、一律に「INDIRECTの方が重い」と言い切ることはできません。

Q. SUMIFやCOUNTIFも揮発性関数なのですか。
A. Microsoftの資料では、SUMIFは「引数による」条件付きで揮発性関数の一覧に含まれています。常に揮発性というわけではありませんが、OFFSETやINDIRECTだけを警戒すればよいわけではない、という点は覚えておく価値があります。

Q. INDEXを使えば必ず非揮発になりますか。
A. Microsoftの解説では、INDEX・ROWS・COLUMNS・AREASは、かつて揮発性関数として説明されていたことがあるものの、実際には揮発性ではないと明記されています。INDEXは参照を返す関数ですが、Excelの依存関係の仕組みの中で通常どおり扱われ、参照先が実際に変わったときだけ再計算されます。

Q. 動的配列関数(FILTER・UNIQUEなど)はOFFSET・INDIRECTの代わりになりますか。
A. 一部の用途では有効な代替になります。条件に合う行だけを自動的に抜き出す、重複を除いた一覧を作るといった場面では、動的配列関数が結果を自動的に広がる形(スピル)で返してくれるため、OFFSETで無理に範囲を伸ばす必要がなくなります。ただし本記事で扱ったシート名をまたぐ集計のような用途は動的配列だけでは解決できず、集約テーブルへの設計変更が必要です。動的配列関数の詳細はExcel動的配列関数の実務を参照してください。

Q. 揮発性関数と循環参照は同じ問題ですか。
A. 別の概念です。循環参照は、あるセルが直接・間接に自分自身を参照してしまっている状態で、Excelが警告を出すエラー的な状況です。揮発性関数は、参照先が変わっていなくても毎回再評価されるという計算上の性質であり、それ自体はエラーではありません。両者は原因も対処方法も異なるため、混同せずに扱う必要があります。循環参照が実務上問題になりやすい場面についてはLBOモデルの循環参照問題で解説しています。

まとめ

OFFSETとINDIRECTは、基準セルからの移動や文字列から参照を組み立てることで、範囲が自動的に伸び縮みする集計や、シート名を可変にした集計を実現できる便利な関数です。一方で、この2つを含むNOW・TODAY・RAND・RANDBETWEENなどは揮発性関数として扱われ、参照先が変わっていなくてもExcelの再計算のたびに必ず再評価され、依存するセルも連鎖して再計算されます。数式が少数であれば実務上の影響は限定的ですが、大量にコピーされた数式が積み重なった大きな財務モデルでは、無関係な編集のたびに応答が遅くなる一因になります。多くの場面では、範囲の終点・始点をINDEXで指定する書き方や、シート分散型のデータをやめて1枚の集約テーブル+SUMIFSに置き換える設計変更によって、同じ動的な挙動を非揮発のまま実現できます。すべてを置き換える必要はなく、使用範囲が限定的なダッシュボード用セルなどでは、揮発性のコストを許容する判断も実務的です。重要なのは、どこにOFFSET・INDIRECTがあり、それがモデル全体にどの程度の影響を与えているかを把握したうえで、置き換えるかどうかを判断することです。

関数の使い分けを、体系的なモデリングの型として身につける

今回はOFFSET・INDIRECTとその非揮発な代替設計に絞って扱いましたが、実務の財務モデルでは、こうした関数選択の判断を、3ステートメントモデルやLBOモデルといった具体的な構築の中で数多く積み重ねることになります。関数の使い分けを実際のモデル構築の中で確認したい方は、まず無料会員登録のうえ関連する記事や演習で理解を確かめてみてください。

→ 無料会員登録をする

出典・参考(2026年9月確認)

※本記事は教育目的の一般的な解説であり、法務・税務・投資助言ではありません。設例は理解のための仮設例です。