ExcelでOFFSET関数を多用してはいけない理由――揮発性関数がファイル全体を遅くする
「OFFSETを使えばグラフの参照範囲が動的にできる」
確かにそうです。でも、OFFSETを多用しているファイルは、開くたびに、セルを編集するたびに、スクロールするたびに重くなります。
揮発性関数とは何か
Excelの関数には「揮発性関数(Volatile Function)」があります。
通常の関数(SUMやVLOOKUPなど)は、参照しているセルの値が変わったときだけ再計算されます。
揮発性関数は何か別のセルが変更されるたびに、シート全体で再計算が走ります。自分が参照しているセルとは無関係に、何かが変わるたびに常に再計算対象になります。
揮発性関数の代表例:
`OFFSET`
`INDIRECT`
`NOW`
`TODAY`
`RAND` / `RANDBETWEEN`
`VOLATILE`(VBA)
OFFSETが遅い理由
=OFFSET(A1, 0, 0, COUNTA(A:A), 1)このような式を使って動的な参照範囲を作ると、シートのどこかのセルが変更されるたびにOFFSETの再計算が走ります。
OFFSETが1つなら影響は小さいです。でも、10個・20個のOFFSETが1つのシートにあると、1セルを編集するたびに20回の再計算が全シートに走り、応答が遅くなります。
OFFSETをINDEX/COUNTAに置き換える
OFFSETの多くの用途は、揮発性でないINDEXで代替できます。
Before(OFFSET):
=OFFSET(A1, 0, 0, COUNTA(A:A), 1)After(INDEX):
=A1:INDEX(A:A, COUNTA(A:A))INDEXは揮発性ではありません。参照しているセルが変わったときだけ再計算されます。
INDIRECTも同様の問題がある
=INDIRECT("Sheet2!A" & B1)シート名やセルアドレスを文字列で動的に作れる便利な関数ですが、INDIRECTも揮発性関数です。
「シートを動的に切り替えたい」という用途では、ドロップダウン+名前付き範囲やXLOOKUPを使うほうがパフォーマンスへの影響を減らせます。
NOW・TODAY・RANDの扱い
`=TODAY()` や `=NOW()` は現在日時を返す揮発性関数です。
日付を参照したいだけであれば、1セルにTODAYを入れて、他のセルはそのセルを参照するようにすれば、揮発性の計算を1回に絞れます。
`=RAND()` はセルを編集するたびに値が変わる仕様です。乱数が必要な場合は、生成後に値として貼り付けてしまうのが一般的です。
まとめ:揮発性関数は「必要最小限」に
| 関数 | 揮発性 | 代替案 |
|------|-------|-------|
| OFFSET | ○ | INDEX |
| INDIRECT | ○ | XLOOKUP・名前付き範囲 |
| NOW/TODAY | ○ | 1セルだけ使い、他はそのセル参照 |
| RAND | ○ | 生成後に値貼り付け |
ファイルが重い原因を探すときは、「Ctrl+End でデータの最終セルを確認」「条件付き書式のルール確認」とあわせて、「揮発性関数の個数確認」も見てみてください。数式バーで検索(Ctrl+F → `OFFSET`)するだけで、使われている箇所がわかります。
もしこの記事が役に立ったら、スキ♡をポチっとしていただけると励みになります。
フォローしていただくと、同じような実務直結のExcel記事をお届けします。
IT実務ラボ|「なぜそうするか」の理由まで、丁寧に。
