この問題は規模が大きくなると顕著になります。銀行団融資用のDCFで、Assumptions(前提条件)、P&L(損益計算書)、Balance Sheet(貸借対照表)、Cash Flow(キャッシュフロー)、FCFF、Returns(リターン)、Sensitivity(感度分析)、Coverage の8つのシートをつなぎ合わせると、セルの総数は5万を超えます。この規模では、不適切に選ばれた数式が複合的に影響し、稟議書の直前に誰の目にも明らかな問題を生み出します。
シート数式の4つのパターン一覧
| パターン | 数式の例 | シート名変更で破損 | 計算タイプ | 最適な用途 |
|---|---|---|---|---|
| 直接参照 | ='P&L'!C12 | する | 非揮発性 | 単一セルの参照、ハードコード済みリンク |
| INDIRECT | =INDIRECT("'"&TabName&"'!C12") | しない | 揮発性 | 動的なシート選択、シナリオ切り替え |
| 名前付き範囲 | =Revenue_FY26 | しない | 非揮発性 | 監査証跡の確保、再利用可能な前提条件 |
| QUERY | =QUERY('P&L'!A:G,"SELECT C WHERE B='"&Assumptions!$B$3&"'") | する | 非揮発性 | 複数行の参照、フィルター付き集約 |
揮発性関数とは、ワークブック内のあらゆるセルが変更されるたびに再計算される関数です。この違いが、ほとんどのパフォーマンス問題の起点となります。
直接参照:高速だが脆弱
直接参照(='P&L'!C12)は非揮発性で、ほぼ瞬時に解決します。単一セルを参照する場合、たとえばReturnsシートにEBITDAラインを引き込むケースでは、最も適した方法です。
ただし脆弱性は現実的な問題です。「P&L」を「Income Statement」に名前変更すると、'P&L'!を指すすべての数式が#REF!エラーで破損します。四半期決算資料の準備期間にシート名が頻繁に変更されるモデルでは、これは実際のリスクになります。
より実務的には、直接参照は動的なロジックと相性が悪いということです。シナリオ切り替えに応じて異なるシートから同じ行を参照したい場合、複数バージョンの数式を用意しなければなりません。ここでINDIRECTが魅力的に見え始めますが、同時にトレードオフが鮮明になる地点でもあります。
INDIRECT:強力だが揮発性コストが高い
INDIRECTでは、文字列から参照を構築できるため、前提条件シートのセルを使ってシート選択を制御できます:
=INDIRECT("'"&Assumptions!$B$2&"'!C"&MATCH("Revenue",'P&L'!$A:$A,0))
これはシート名変更に対応でき(前提条件シートの文字列を更新すれば)、シナリオ切り替えを簡潔に実装できます。1つのドロップダウンメニューを変更するだけで、モデル全体の参照元シートが切り替わります。
ただしコストがあります。Google SheetsのドキュメントではINDIRECTを揮発性関数として明示しています。ワークブック内のあらゆるセルが変更されるたびに再計算されます。5万セルのモデルでは、数個のINDIRECT数式が再計算時間を1キー入力ごとに4秒を超える水準に押し上げることがあります。これは理論的な問題ではなく、アナリストが別ファイルを開いてコピペを始めてしまう(それはもっと悪い)という現実の問題です。
局所化が鉄則です。 1つのルックアップテーブルでシート名を値に解決し、その後のすべての下流数式はその表を直接参照経由で参照する。揮発性のコストは局所化されます。INDIRECTをモデル全体に散らばせれば、INDIRECT自体よりもその先のSUMIFSや集約関数が毎回再計算されることへの影響の方が大きくなります。
名前付き範囲:過小評価されている選択肢
名前付き範囲は非揮発性で、シート名変更に対応し、監査証跡を読みやすくします。=WACC_Baseは決算資料の数式では=Assumptions!$G$14より格段に明確ですし、CFOが「この数字はどこから来たのか」と聞いたときも、8つのシートを探し回る代わりに名前マネージャーをクリックするだけです。
実務的な課題は保守性です。成熟したFP&Aモデルでは、前提条件・FCFFドライバー・シナリオパラメータ全体で150〜200個の名前付き範囲が蓄積する可能性があります。Google Sheetsには各名前が何を表すかを文書化するネイティブな方法がなく、用途を変更されたセルを指す古い名前は、エラーを表示せずに間違った答えを生み出します。プレフィックス規約で名前を付け(Assum_、Driver_、TV_など)、専用のInputsシートで文書化してください。
ターミナルバリュー(終値)の係数として14.2倍のEBITDA倍数を使うDCFモデルの例:
// 名前付き範囲: TV_EBITDAMultiple → Assumptions!$B$22
// 名前付き範囲: EBITDA_Year5 → 'P&L'!$G$45
=TV_EBITDAMultiple * EBITDA_Year5
これは6ヶ月後でも読める。=Assumptions!$B$22 * 'P&L'!$G$45ではそうはいきません。
QUERY:複数行参照と条件付き集約
QUERYが本領を発揮するのは、シート内で条件付きの集約が必要な場合です。SKU別の貢献利益、部門別の人員数、地域別の売上といったケースです。直接参照だけではこれができず、SUMIFSで対応することはできますが、複数条件の場合は煩雑になります。
=QUERY('P&L'!A:G,
"SELECT B, SUM(C) WHERE D='" & Assumptions!$B$3 & "' GROUP BY B",
1)
これは前提条件シートで指定された期間の部門別貢献利益を抽出し、ヘッダー行を含めて返します。同等のSUMIFS版は3〜4個の数式とヘルパー列が必要になります。
QUERYは非揮発性で、大規模データ範囲(2026年5月時点で5,000行以上)では同等のSUMIFS配列より2〜4倍高速です。
トレードオフとして覚えておくべきことが2点あります。QUERYの構文はSQL風ですがSQLではなく、破損時のエラーメッセージが不親切です。ライブの決算資料の中で壊れたQUERYをデバッグする時間は想定外の負担になります。対策は単純で、必ず本番モデルとは別のシートで単独構築し、期待通りの出力が確認できてから組み込んでください。想定外の列数や空白行が出力された場合、下流の参照が静かに間違った値を拾うことがあります。
もう1点、QUERYはファイル間の参照には対応していません。そのためにはIMPORTRANGEが必要ですが、Google Sheetsのドキュメントでは最大30分ごとのリフレッシュと記載されています。ライブな決算資料では、このラグが問題になる可能性があります。
揮発性タックス:モデルが遅い本当の原因
大規模モデルのパフォーマンス問題は、単一の悪い数式ではなく、その複合的な組み合わせです。複数の下流SUMIFS(各々が全列を参照)を駆動する揮発性INDIRECT、5万セルのワークブック、キー入力のたびに再計算される——タックスは乗算的に作用します。
対処法は地味ですが、効果は確実です。まず揮発性関数を洗い出してください。Google Sheetsには揮発性関数の組み込みトラッカーがないため、手動で検索する必要があります。主な容疑者はINDIRECT、OFFSET、NOW、TODAY、RANDです。
可能な限り非揮発性の代替に置き換えてください:
OFFSET(A1,n,0)→INDEX(A:A,n+1)(INDEXは非揮発性)INDIRECT("'P&L'!A"&row)→ ルックアップを1回ヘルパーセルで解決し、その後は直接参照で下流参照- 動的な範囲の境界 → 境界を名前付き範囲セルで計算し、
A$1:A& BoundCell で参照
このリファクタリングは、複数四半期にわたって揮発性が蓄積したモデルで再計算時間を通常60〜80%削減します。1キー入力で4秒かかるモデルが0.5秒に改善されます。OFFSETが散在するモデルを持っているなら、Ctrl+H で「OFFSET」を検索してINDEXで書き換えられるものを確認するだけで30分もかかりません。5万セルに到達した後ではなく、その前に一度監査しておく価値は十分にあります。
AIによるシート数式作業の自動化
複数タブを扱うシート数式作業の退屈な部分は「どのパターンを使うか知ること」ではなく、「実行すること」です。8つのシート全体でSUMIFSの列参照を一貫させながら配線し、揮発性関数を探し出し、QUERYの出力を決算資料の構造に合わせて再フォーマットする。
ModelMonkeyはこのレイヤーを処理します。平文で参照を説明するだけで(「P&LからAssumptions B3に一致する期間で売上を合計し、地域別に分割」)、正しいシートと列を対象にした数式を書き込みます。Google Sheetsのサイドバーに組み込まれたAIアシスタントで、手動構築より高速で、INDIRECTを直接参照が適切な場所に誤って配置することもありません。2026年5月時点では、Google SheetsとExcelの両方で動作します。これは銀行のカウンターパーティから.xlsxが送られてきて、金曜までにフォーマット済みのリターンモデルで返却することが期待される場合に重要です。
シート数式パターンのまとめ
単一セルの参照でシート名が安定している場合は直接参照、監査証跡や再利用が必要な場合は名前付き範囲、条件付き複数行集約にはQUERYを使用してください。INDIRECTは動的なシート選択が本当に必要な場合のみ、かつ局所化して使用してください。揮発性関数は複合的に影響します。5万セルに到達した後ではなく、その前に監査してください。
よくある質問
Q. INDIRECTを完全に使わない方がいいですか?
そうではありません。動的なシート選択やシナリオ切り替えが本当に必要な場面では有効な選択です。ただし「局所化」が鉄則で、1つのヘルパーセルでシート名を解決し、その値を下流の直接参照から使う構造にする。INDIRECTをモデル全体に分散させると、揮発性の再計算コストが乗算的に積み上がります。
Q. 名前付き範囲が増えすぎた場合、どう整理すればいいですか?
プレフィックス規約(Assum_、Driver_、TV_など)で命名し、専用のInputsシートに一覧と用途説明を記載してください。Google Sheetsの名前マネージャーは文書化機能を持たないため、Inputsシートが実質的な仕様書になります。不使用の名前は削除せず、コメントで「廃止」と記載しておくと、誰かが参照していた場合のトラブルを防げます。
Q. QUERYが壊れたときのデバッグはどうすればいいですか?
QUERYのエラーメッセージは不親切なことが多いため、構文を分割して確認するのが最速です。まずWHERE句を外してSELECTとFROMだけで実行し、期待通りの列が返るか確認する。次にWHERE句を固定値で試し、最後に動的な参照(&Assumptions!$B$3&など)を戻す。本番モデルと同じシートで構築しないことが最大の予防策です。
Q. 5万セルを超えていないモデルでも揮発性の監査は必要ですか?
再計算の遅さを感じていないなら後回しで構いません。ただしモデルは育つものなので、INDIRECTやOFFSETが散在した状態で5万セルに到達すると、そのタイミングでのリファクタリングはコストが高くなります。四半期に一度、Ctrl+Hで揮発性関数の出現箇所を確認しておくだけで十分です。
Q. QUERYとSUMIFSはどちらを選ぶべきですか?
条件が1〜2個で、結果が単一セルに収まるならSUMIFSの方がシンプルです。複数条件・複数行の集約、またはGROUP BYが必要な場面ではQUERYが適しています。2026年5月時点で5,000行以上のデータ範囲ではQUERYがSUMIFS配列より2〜4倍高速ですが、デバッグのしやすさはSUMIFSに軍配が上がります。用途に応じて使い分けてください。