見出し画像

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実務ラボ|「なぜそうするか」の理由まで、丁寧に。

いいなと思ったら応援しよう!