Excel 揮発性関数 完全ガイド
― 再計算の3種類・INDIRECT問題・条件付き書式の超揮発性・シート間設計・構成変更時の落とし穴まで全網羅 ―
この記事の内容
- 再計算の3種類を理解する
- 核心:「動く列」と「動かない列」を図で理解する
- 揮発性関数の一覧
- よくある誤解と真実(ROW / COLUMN / INDEX は非揮発性)
- SUMIF の条件付き揮発性
- IF / CHOOSE の揮発性「感染」規則
- 揮発性関数を「1セルに閉じ込める」パターン
- 名前の管理(Name Manager)と揮発性
- INDIRECT の3つの問題点
- 揮発性アクション一覧
- サイト構成変更と揮発性アクションの連鎖
- 条件付き書式:「超揮発性」
- シート間の依存関係と揮発性の影響
- オートフィルタ vs 関数による抽出
- INDEX+MATCH と FILTER関数の違い
- 数万行のINDIRECT問題
- 揮発性関数の正しい使いどころ
- 脱・揮発性!代替手段一覧
- まとめチェックリスト
💡 再計算の3種類を理解する
Excelの再計算はすべて同じではありません。以下の3種類を区別することが、パフォーマンス改善の出発点です。
| 種類 | トリガー | 再計算範囲 | コスト |
|---|---|---|---|
| ① Smart Recalc (依存関係再計算) |
セルの値が実際に変わったとき | 変更セルに依存する数式だけ | 最小・必要な再計算 |
| ② 揮発性関数による再計算 | ブック内のどこかで何かが変わったとき | 揮発性関数を含むセルすべて | 揮発性数式の数 × 計算コスト |
| ③ 揮発性アクションによる再計算 | 特定の操作(フィルタ、名前変更、行挿入等) | 影響範囲内の全数式が「dirty」マーク | 範囲内の全数式が無条件に再計算 |
揮発性関数を含むセルは毎回再計算されます。しかし、再計算した結果が前回と同じ値なら、そこから先の依存セルは①の判断で「変化なし=再計算不要」となり動きません。揮発性は「そのセルだけ」で止まり、値が変わらなければ先に伝染しないのです。
Z1に
=TODAY() を入れ、B1:B1000が =IF(A1<$Z$1,"期限切れ","OK") と参照しているとします。何かのセルを編集すると:1. Z1(揮発性)が再計算される → 同じ日の作業中は結果が変わらない
2. Z1の値が変わらないため、B1:B1000は再計算されない(Smart Recalc)
3. 日付が変わった翌日の初回再計算ではZ1の値が変わり、B1:B1000も再計算される(正常な依存関係再計算)
【2】核心:「動く列」と「動かない列」を図で理解する
揮発性関数のパフォーマンス問題を理解するうえで最も重要なポイントは、「揮発性数式のセルは毎回動くが、その結果が変わらなければ参照先は動かない」ということです。
シナリオ:関係ないセル(Z1)を編集したとき
Z1 に「あ」と入力← これがトリガー
開始
A1 =IF(INDIRECT("元!"&D1)>100,"大","小")結果:"大"(前回と同じ)
⚡ 再計算された(揮発性だから)
A2 =IF(INDIRECT("元!"&D2)>100,"大","小")結果:"小"(前回と同じ)
⚡ 再計算された(揮発性だから)
A3 =IF(INDIRECT("元!"&D3)>100,"大","小")結果:"大"(前回と同じ)
⚡ 再計算された(揮発性だから)
変わった?
B1 =A1&":"&C1💤 再計算しない(A1の値が変わっていないから)
B2 =A2&":"&C2💤 再計算しない(A2の値が変わっていないから)
B3 =A3&":"&C3💤 再計算しない(A3の値が変わっていないから)
処理の流れ(タイムライン)
Z1を編集
↓
再計算サイクル開始
A列の揮発性数式を
全行再計算
(ここでフリーズ)
A列の結果を
前回の値と比較
→ 全行「同じ」
B列は
全行スキップ
(計算しない)
B列は動かない。これは良いことです。しかし STEP 2 でA列の30,000個のINDIRECT数式が毎回再計算されること自体がフリーズの原因です。元データが変わっていなくても、INDIRECTを含むA列は「揮発性だから」というだけで必ず全行が動きます。しかもINDIRECTはシングルスレッドなので、マルチコアCPUでも1コアしか使えません。
INDEX+MATCH に置き換えた場合
Z1 に「あ」と入力← これがトリガー
開始
A1 =IF(INDEX(元!E:E,MATCH(D1,元!A:A,0))>100,"大","小")💤 再計算しない(非揮発性・参照先に変化なし)
A2, A3 ...💤 再計算しない
B1 =A1&":"&C1💤 再計算しない
B2, B3 ...💤 再計算しない
INDEX+MATCH は非揮発性なので、Z1の編集とは無関係 → A列もB列も一切動かない → フリーズしない。
まとめ:同じ「B列が動かない」でも天と地の差
| INDIRECT 方式 | INDEX+MATCH 方式 | |
|---|---|---|
| A列 | 30,000回再計算(結果は同じ) | 0回(再計算しない) |
| B列 | 0回(A列の値が変わらないため) | 0回(同じ) |
| 体感 | 数秒〜十数秒フリーズ | 一瞬で完了 |
| 原因 | A列の「無駄な再計算」コスト | ― |
【3】揮発性関数の一覧
以下はMicrosoft公式ドキュメントおよびCharles Williams(Decision Models / FastExcel)の検証に基づく揮発性関数の一覧です。
| 関数 | 揮発性 | リスク・備考 |
|---|---|---|
| INDIRECT() | 揮発性 | シングルスレッド動作・閉じたブック不可・代替推奨 |
| OFFSET() | 揮発性 | INDEXで代替可能 |
| TODAY() | 揮発性 | 1セルに閉じ込めれば影響最小 |
| NOW() | 揮発性 | 同上 |
| RAND() | 揮発性 | 毎回値が変わるため依存先も毎回再計算 |
| RANDBETWEEN() | 揮発性 | 同上 |
| RANDARRAY() | 揮発性 | 365/2021以降 |
| CELL() | 揮発性 | 引数によらず揮発性 |
| INFO() | 揮発性 | 使用頻度は低い |
| SUMIF() | 条件付き揮発性 | 第1引数と第3引数のサイズが異なると揮発性(詳細) |
出典:Microsoft Learn — Excel Improving Calculation Performance、Decision Models — Volatile Excel Functions
【4】よくある誤解と真実(Myth Busters)
一部のサイトでは以下の関数が「揮発性」と記載されていますが、Microsoft公式ドキュメントとCharles Williamsのテストにより非揮発性が確認されています。
| 関数 | 実際の揮発性 | 根拠 |
|---|---|---|
| ROW() | 非揮発性 | 行挿入時の再計算は依存関係追跡による正常動作 |
| COLUMN() | 非揮発性 | 同上 |
| ROWS() | 非揮発性 | Microsoft Learn で明記 |
| COLUMNS() | 非揮発性 | 同上 |
| AREAS() | 非揮発性 | 同上 |
| INDEX() | 非揮発性 | OFFSETの代替として推奨される理由 |
| FILTER() | 非揮発性 | 動的配列関数。ソースデータや条件変更時のみ再計算 |
| XLOOKUP() | 非揮発性 | 依存関係追跡のみで動作 |
SumProductの「A to Z of Excel Functions」ではROW()を「volatile」と記載していますが、Microsoft Learnの "Excel Improving Calculation Performance" ではROW / COLUMN / ROWS / COLUMNS / AREAS / INDEXを「previously documented as volatile but are in fact non-volatile」と明記しています。本ガイドでは公式分類に従います。
【5】SUMIF の条件付き揮発性
SUMIF は通常は非揮発性ですが、第1引数(条件範囲)と第3引数(合計範囲)のサイズが異なる場合に揮発性になります。
❌ 揮発性になるケース(サイズ不一致)
✅ 非揮発性のケース(サイズ一致)
整形シートでSUMIFを大量に使う場合、範囲サイズを必ず一致させてください。
【6】IF / CHOOSE の揮発性「感染」規則
揮発性かどうかは数式の構文解析(パース)の段階で決まり、実行時の評価とは無関係です。
2段階の処理フロー
| 段階 | 処理内容 | 揮発性判定への影響 |
|---|---|---|
| ① 構文解析 (Enter時・ブック読込時) | 数式テキストに揮発性関数名が含まれるかチェック | 含まれていればそのセルを「揮発性」としてマーク |
| ② 実行 (再計算時) | 数式を実際に計算し分岐を決定 | 影響なし。揮発性かどうかは①で決定済み |
具体例
| 数式 | 揮発性? | 理由 |
|---|---|---|
=IF(1>0, 1, RAND()) |
揮発性 | RAND()は実行されないが、構文に「RAND」が存在 → 揮発性マーク |
=IF(1>0, 1, A1)(A1に =RAND()) |
非揮発性 | 構文には「A1」というアドレスだけ。A1の中身は検査されない |
=IF(A1<TODAY(), "期限切れ", "OK") |
揮発性 | 「TODAY」が数式テキストに存在 |
=IF(A1<$Z$1, "期限切れ", "OK")(Z1に =TODAY()) |
非揮発性 | 数式テキストに揮発性関数名なし。$Z$1はただのアドレス |
構文解析では
$Z$1 は「アドレス」として処理されるだけで、Z1の中身を見に行きません。これが「1セルに閉じ込める」パターンの根拠です。
AND() と OR() はIFと異なり、すべての引数を常に評価します。=AND(TRUE, RAND()>0.5) は揮発性であるだけでなく、条件に関わらず毎回 RAND() が実行されます。IFの「短絡評価(条件に応じて片方だけ実行)」とは異なるため注意が必要です。
【7】揮発性関数を「1セルに閉じ込める」パターン
シナリオ:1000行の日付列で期限切れかどうかを判定したい
❌ 悪い例:1000行すべてに TODAY() を直接書く
✅ 良い例:TODAY() は Z1 に1つだけ。他は Z1 を参照
Z1 に入れる数式
B1:B1000 に入れる数式(非揮発性)
前セクションで説明した構文解析の規則のとおり、
$Z$1 はただのセル参照であり、Excelは Z1 の中身を見に行きません。数式テキスト IF(A1<$Z$1,"期限切れ","OK") に揮発性関数名が含まれないため、非揮発性と判定されます。
【8】名前の管理(Name Manager)と揮発性
トラップ①:名前の定義に揮発性関数を入れる
名前の管理で 今日 = TODAY() のような定義を作ると、その名前を参照するすべての数式が揮発性になります。しかも名前が使われるたびに評価されるため、100箇所で「今日」を参照すると100回 TODAY() が実行されます。
❌ 名前の管理に揮発性関数を直接定義
✅ セルに書いて名前はセル参照に
Z1 に入れる数式
トラップ②:名前の操作自体が揮発性アクション
名前の管理で名前を追加・変更・削除する行為自体が「揮発性アクション」です。参照先が単純なセル範囲(例: =Sheet1!$A$1:$D$50)であっても、名前を操作するだけでブック全体の再計算がトリガーされます。大量の名前を一括整理する際にExcelがフリーズする原因はこれです。
揮発性関数を名前の定義に直接入れない。揮発性関数は必ず1つのセルに書き、名前にはそのセル参照を設定する。
【9】INDIRECT の3つの問題点
| # | 問題 | 説明 |
|---|---|---|
| 1 | 常に揮発性 | 引数や結果に関係なく、すべての再計算サイクルで再評価される。結果が前回と同じでも計算自体は毎回走る |
| 2 | 閉じたブック参照不可 | 参照先のブックが閉じているとエラー。INDEX/MATCHは閉じたブックでも動作する |
| 3 | シングルスレッド動作 | Excelのマルチスレッド再計算を無効化し、1つのCPUコアでしか計算されない。数万行で致命的なボトルネック |
シート切替 →
CHOOSE() または XLOOKUP()、動的範囲 → INDEX() のコロン構文、カスケードドロップダウン → FILTER()(365/2021以降)
【10】揮発性アクション一覧
以下の操作は揮発性関数とは無関係に、影響範囲内のすべての数式を「dirty(要再計算)」としてマークします。これが③の再計算です。
| 操作 | 影響範囲 | 備考 |
|---|---|---|
| 行・列・セルの挿入/削除/移動 | 名前付き範囲やクロスシート参照を含む場合、ブック全体 | 構造変更は参照を再構築するため |
| 名前の管理で名前を追加/変更/削除 | ブック全体 | 参照先が単純なセル範囲であっても操作自体がトリガー |
| シート名変更・シート移動・シート削除 | 該当シートを参照する全数式 | 参照文字列の更新が必要なため |
| オートフィルタ操作 | フィルタ範囲内の全数式 | フィルタ切替のたびに範囲内が全てdirty |
| 行/列境界線のダブルクリック(自動調整) | 自動計算モード時にブック全体 | 画面再描画を伴う |
| CSVファイルを開く | 手動計算モードでもブック全体 | Excel仕様の例外的動作 |
| ゴールシーク | 反復ごとにブック全体 | 収束するまで繰り返される |
| 行の非表示/再表示(Excel 2003のみ) | ブック全体 | 2003限定のレガシー動作。2007以降は発生しない |
【11】ブック構成の変更と揮発性アクションの連鎖 ― 数万行で起きる地獄
ブックの構造を変更する操作(シート名変更、シート移動、行列の挿入削除、名前の一括整理など)はすべて揮発性アクションです。数万行の数式が入ったブックでこれらを実行すると、構成変更のたびにブック全体が再計算され、深刻なフリーズが発生します。
具体的に何が起きるか
シナリオ:整形シートに30,000行の数式があるブックで、シート名を「元データ」→「原本」に変更する
シート名を
「元データ」→「原本」
に変更
「元データ」を参照する
全数式の参照文字列
が「原本」に更新される
揮発性アクション発動
影響範囲の全数式が
dirtyマーク
30,000行すべてが
再計算される
(フリーズ)
さらに悪いことに、この30,000行にINDIRECTやOFFSETが含まれている場合、通常の揮発性再計算(②)に加えて揮発性アクション(③)のdirtyマークが重なり、二重に再計算が走ります。
特に危険な操作パターン
| 操作 | 影響 | 対策 |
|---|---|---|
| シート名の変更 | 該当シートを参照する全数式が再計算 | シート名は最初に確定させ、後から変えない |
| 行の大量挿入/削除 | 名前付き範囲やクロスシート参照がある場合、ブック全体 | 構造変更前に手動計算モードに切替。完了後にCtrl+Alt+F9で一括再計算 |
| 名前の一括削除/整理 | 1つ削除するたびにブック全体が再計算 | 手動計算モードで一括処理。またはVBAで Application.Calculation = xlManual にしてから実行 |
| シートの移動/削除 | 参照先を含む全数式 | シート構成は初期段階で確定させる |
| オートフィルタの切替 | フィルタ範囲内の全数式 | INDEX+MATCH / FILTERで別シートに抽出し、元データにはフィルタを使わない |
「数万行の数式が入ったブックを後から構成変更するのは地獄」。シート名、シート構成、名前の定義は最初の設計段階で確定させてください。後から変更すると、変更のたびに数万行が再計算されてExcelがフリーズします。どうしても変更が必要な場合は、必ず手動計算モードに切り替えてから行ってください。
【12】条件付き書式:「超揮発性」 超揮発性
条件付き書式の数式は画面の再描画(repaint)のたびに評価されます。揮発性関数よりさらに強力です。
| 操作 | 通常の揮発性関数 | 条件付き書式の数式 |
|---|---|---|
| セルの値を変更 | 再計算される | 再評価される |
| スクロール | 再計算されない | 画面に入った行が再評価 |
| シート切替(戻る) | 再計算されない | 表示領域が再評価 |
| ウィンドウ復元 | 再計算されない | 表示領域が再評価 |
| 手動計算モード | 抑制できる | 抑制できない |
| 印刷プレビュー / PDF出力 | 再計算されない | 全行が一括評価 → フリーズ |
再計算範囲は「画面に表示されている部分」だけ
通常のスクロール操作では、条件付き書式の再評価は画面に新しく表示された行だけで発生します(1画面30行なら30行分)。画面外の行は評価されません。
ただし、以下のケースでは全行が一括評価されます:
・印刷プレビュー — 全ページを描画しようとするため、全1万行の条件付き書式が一気に評価 → 数十秒フリーズ
・PDF出力 — 同上
・Ctrl+End → 先頭へ戻る — 最終行までジャンプした際に大量の行が描画対象に
・ページレイアウトビュー — 全ページの描画が発生
起きること(具体的な症状)
1万行に =AND($D1>TODAY(), $E1="") のような条件付き書式を設定した場合:スクロールするたびに画面に入った行の数式が全て評価されます(1画面30行なら30回)。TODAY()は揮発性なのでさらに重くなります。手動計算モードにしても条件付き書式の評価は止められません。上下にスクロールを繰り返すだけでExcelが目に見えてカクつきます。印刷プレビューを表示すると、全1万行を一気に描画しようとして数十秒フリーズすることもあります。
対策:補助列を使う
❌ 条件付き書式にTODAY()を直接書く
✅ 補助列で計算し、条件付き書式は値比較のみ
Z1 に入れる数式
補助列 F1 に入れる数式
条件付き書式の数式(単純な値比較 → 高速)
条件付き書式を設定する範囲は必要最小限にしてください。A1:J10000 に設定するよりも、実際にデータがある範囲だけに限定する方が描画時の評価回数が減ります。使わなくなった条件付き書式は必ず削除してください。
【13】シート間の依存関係と揮発性の影響
手入力 / 外部取込
数万行の数式
XLOOKUPで表示・印刷
整形シートが再計算される条件
| # | 条件 | 再計算の種類 |
|---|---|---|
| 1 | 元データの参照先セルが実際に変更された | ① Smart Recalc(正常・必要な再計算) |
| 2 | 整形シート自体に揮発性関数がある | ② 揮発性関数による再計算 |
| 3 | 整形シートに揮発性アクション(フィルタ操作・行挿入・シート名変更等)が行われた | ③ 揮発性アクション |
出力シートで操作しても、整形シートの元データが変わっていなければ、整形シートの数式は動きません(条件2と3に該当しない限り)。出力シートにある揮発性関数は出力シートだけで再計算され、その結果が変わらなければ整形シートには一切波及しません。
整形シートの状態別:影響の比較
| 整形シートの状態 | 再計算回数 | コスト | 出力シートへの連鎖 |
|---|---|---|---|
| 揮発性関数なし | 0 | ゼロ | 元データが変わらない限りなし |
| TODAY() が1セルだけ | 1 | ほぼゼロ | 同じ日なら値が変わらないためなし |
| OFFSET が100個 | 100 | 中程度 | 結果が同じならなし(ただし100回の計算コストは発生) |
| INDIRECT が数千〜数万個 | 数千〜数万 | 非常に重い | 結果が同じでも計算自体でフリーズ |
判定フローチャート
危険シナリオ:印刷・PDF出力時の連鎖
出力シートを印刷・PDF出力する際に最も深刻な遅延が発生します:
出力シートに
揮発性関数
→ 再計算
出力シートに
条件付き書式
→ 全行評価
(超揮発性)
整形シートに
揮発性関数が数千個
→ 全て再計算
③の結果が
変わった場合
→ 出力シートも
再度再計算
このような連鎖が発生するため、整形シートから揮発性関数を排除することが最も効果的な対策です。
整形シートは揮発性フリーに設計する。XLOOKUP / INDEX+MATCH 等の非揮発性関数だけで構成する。TODAY()はシートごと1セルに閉じ込め、他はそのセル参照。条件付き書式は最小限にし、補助列で判定させる。
【14】オートフィルタ vs 関数による抽出
オートフィルタはフィルタを切り替えるたびにフィルタ範囲内の全数式が dirty としてマークされます(③揮発性アクション)。INDEX+MATCH や FILTER関数で別シートに抽出する方式は、①のSmart Recalcだけで動作します。
| 比較項目 | オートフィルタ | INDEX+MATCH | FILTER関数 |
|---|---|---|---|
| 再計算の種類 | ③ 揮発性アクション | ① Smart Recalc | ① Smart Recalc |
| 影響範囲 | フィルタ範囲内の全数式 | 条件に依存するセルだけ | FILTER数式と依存先だけ |
| 元データへの影響 | 元データの数式もdirtyに | 影響なし | 影響なし |
| 関数の揮発性 | ― | 非揮発性 | 非揮発性 |
| 対応バージョン | 全バージョン | 全バージョン | 365 / 2021 / 2024 |
INDEX+MATCHやFILTERで抽出した結果が条件セルの変更に応じて更新されるのは①のSmart Recalcです。これはExcelの正常な動作であり、③の「不要な全範囲dirty」とは根本的に異なります。
【15】INDEX+MATCH と FILTER関数の違い
どちらも非揮発性ですが、動作の仕組みが異なります。
INDEX+MATCH:1行1数式
=INDEX(元データ!A:A, MATCH(H$1, 元データ!C:C, 0))
MATCHが最初の一致行番号を返し、INDEXがその行の値を取得。複数行を抽出するにはSMALL+IF等の追加工夫が必要。行ごとに1つの数式が必要。
FILTER関数:1数式でスピル
=FILTER(元データ!A:E, 元データ!C:C=H1, "該当なし")
条件に一致する全行が1つの数式から自動展開(スピル)。複数条件は * (AND) や + (OR) で組み合わせ。結果の行数が動的に変化。
| 比較項目 | INDEX+MATCH | FILTER関数 |
|---|---|---|
| 揮発性 | 非揮発性 | 非揮発性 |
| 数式の数 | 抽出行数ぶん(多い) | 1つ(スピルで展開) |
| 複数条件 | SMALL+IF等で複雑 | 配列演算で簡潔 |
| 結果行数 | 固定(事前に枠を用意) | 動的(自動拡縮) |
| 対応バージョン | 全バージョン(Excel 97以降) | Microsoft 365 / Excel 2021 / Excel 2024 |
| 再計算コスト | 数式数ぶんの計算 | 1数式で一括計算(大量データでは効率的) |
FILTER関数は Microsoft 365、Excel 2021(コンシューマー版)、Excel 2024(コンシューマー版)で使用できます。ただし企業向けの Office LTSC 2021 / LTSC 2024(ボリュームライセンス版)ではエディションによって利用できないケースがRedditやMicrosoft Q&Aで報告されています。利用可否は
ファイル → アカウント でExcelのバージョン情報を確認してください。Excel 2019以前では使用できないため、INDEX+MATCHが唯一の選択肢です。
【16】数万行のINDIRECT問題:「結果が変わらなくても動く」コスト
「便利だから」とINDIRECTやOFFSETを数万行に使ってしまうケースは、パフォーマンス上の最大の落とし穴です。
何が起きるのか(図解)
A1 =INDIRECT("元!"&D1)結果:150(前回と同じ)
⚡ 再計算された
A2 =INDIRECT("元!"&D2)結果:80(前回と同じ)
⚡ 再計算された
シングルスレッドで数秒〜十数秒
変わった?
No
B1 =A1*1.1💤 スキップ
B2 =A2*1.1💤 スキップ
A列の値が変わっていないから
INDIRECTの結果が変わらない場合の詳細
元データが一切変更されていない場合、30,000個のINDIRECTは全て再計算されますが、結果の値は前回と同じです。この場合:
| 状況 | A列(INDIRECT)の再計算 | B列(A列参照)の再計算 |
|---|---|---|
| 元データ変更なし | 30,000回すべて再計算(値は変わらない) | 0回(値が変わらないためSmart Recalcでスキップ) |
| 元データ1セル変更 | 30,000回すべて再計算(1つだけ値が変わる) | 変わった1セルに依存するB列の数式だけ |
| 元データ大量変更 | 30,000回すべて再計算 | 変わったセルに依存するB列の数式すべて |
つまり、依存先への連鎖は起きませんが、INDIRECT数式自体の30,000回の再計算コストが問題なのです。しかもINDIRECTはシングルスレッドなので、マルチコアCPUでも1コアしか使えず、計算が直列で走ります。
INDEX+MATCH / FILTER に置き換えた場合の比較
| 方式 | 元データ変更なし時 | マルチスレッド | 体感 |
|---|---|---|---|
| INDIRECT × 30,000 | 30,000回 | 不可(シングルスレッド) | 数秒〜十数秒フリーズ |
| INDEX+MATCH × 30,000 | 0回 | 可能 | 一瞬 |
| FILTER × 1(スピル) | 0回 | 可能 | 一瞬 |
「結果が変わらなければB列は動かない」は事実。しかし問題はA列のINDIRECT自体が毎回30,000回も再計算されるコスト。30,000個のINDIRECTがシングルスレッドで毎回再計算されることで、データが変わっていないにもかかわらず数秒〜十数秒のフリーズが発生します。INDEX+MATCHやFILTERに置き換えれば、この無駄な再計算はゼロになります。
【17】揮発性関数の正しい使いどころ
揮発性関数は「悪」ではありません。適切な場面で使えば便利で、問題は使い方です。重要なのは「数」と「場所」のコントロールです。
適切なケース
| ケース | 関数 | 理由 |
|---|---|---|
| ダッシュボードの日付表示(1セル) | TODAY() | 1セルだけなのでコストほぼゼロ |
| 乱数によるシミュレーション | RAND() | 毎回変わることが目的。使い終わったら値で貼り付け |
| ファイルパスの取得(1セル) | CELL("filename") | コスト軽微 |
| 少数のシート動的参照 | INDIRECT() | 数個なら影響は限定的。数百以上ならCHOOSE/XLOOKUPに置換 |
避けるべきケース
| ケース | 問題の関数 | 代替手段 |
|---|---|---|
| 数千〜数万行のデータ整形 | INDIRECT / OFFSET | INDEX+MATCH / XLOOKUP / FILTER |
| 条件付き書式の数式 | TODAY() | 補助列で計算、書式は値比較のみ |
| 全行に同じ日付比較 | TODAY() を全行に | Z1に1つだけ、他は $Z$1 参照 |
| 名前の管理の定義式 | 揮発性関数を直接記述 | セルに書いて名前はセル参照に |
判断基準:使用数 × 依存の深さ
揮発性関数を避けるためにCHOOSEで数十のシート名を手書きしたり、OFFSETの代替で非常に複雑なINDEX式を書いたりすると保守性が低下します。「数個の揮発性関数」と「著しく複雑な非揮発性数式」の間では、コストと保守性のバランスを考えてください。
【18】脱・揮発性!代替手段一覧
| 目的 | 揮発性の方法 | 非揮発性の代替 |
|---|---|---|
| 動的範囲の取得 | =OFFSET(A1,0,0,COUNTA(A:A),1) |
=A1:INDEX(A:A,COUNTA(A:A))(INDEXのコロン構文) |
| シートの動的切替 | =INDIRECT("'"&B1&"'!A1") |
=CHOOSE(C1, Sheet1!A1, Sheet2!A1, Sheet3!A1)またはテーブル+XLOOKUP |
| カスケードドロップダウン | =INDIRECT(D1)(名前参照) |
=FILTER(品目一覧, カテゴリ列=D1)(365/2021以降) |
| 今日の日付との比較 | 各行に TODAY() |
Z1に =TODAY()、各行は $Z$1 参照 |
| データの抽出・フィルタリング | オートフィルタ(揮発性アクション) | INDEX+MATCH / FILTER で別シートに抽出 |
📝 まとめチェックリスト
| # | チェック項目 |
|---|---|
| 1 | 再計算は3種類:① Smart Recalc、② 揮発性関数、③ 揮発性アクション。②と③を最小化する |
| 2 | 揮発性関数は「そのセル」が毎回動く。しかし結果が変わらなければ依存先は動かない |
| 3 | 問題は「依存先への連鎖」ではなく「揮発性数式自体の計算コスト × 数」。INDIRECTはシングルスレッド |
| 4 | IF / CHOOSEの揮発性は構文解析レベル。セル参照は揮発性を「感染」させない。AND/ORは全引数を常に評価する |
| 5 | TODAY / NOW は1セルに閉じ込め、名前の管理にも直接書かない(名前は使用箇所ごとに再評価される) |
| 6 | ROW / COLUMN / ROWS / COLUMNS / INDEX / FILTER は非揮発性。安心して大量に使える |
| 7 | SUMIFは範囲サイズを一致させる(不一致で揮発性化) |
| 8 | 条件付き書式は「超揮発性」。手動計算モードでも止まらない。画面表示部分だけ再評価だが、印刷プレビューでは全行一括評価。補助列を活用 |
| 9 | オートフィルタは揮発性アクション。INDEX+MATCH / FILTERによる別シート抽出が高速 |
| 10 | 名前の追加/変更/削除は揮発性アクション。一括操作時はフリーズ注意 |
| 11 | ブック構成の変更(シート名変更・行列挿入削除・シート移動削除)は揮発性アクション。数万行のブックでは必ず手動計算モードで実行する |
| 12 | 整形シートは揮発性フリーに設計する。数万行のINDIRECTはデータが変わらなくても毎回フリーズ。出力シートとの連鎖にも注意 |
| 13 | 揮発性関数は「悪」ではない。少数・浅い依存なら問題ない。排除しすぎて保守性を犠牲にしない |
| 14 | シート名・シート構成・名前の定義は最初の設計段階で確定させる。後からの変更は揮発性アクションの嵐になる |