Excel における「揮発性関数」:動作が重いと感じたら!

Excel における揮発性関数の特性と影響について


Excel を使っていると、特定の関数が予期せぬタイミングで再計算され、ブックの動作が重くなる経験をしたことがあるかもしれません。これは「揮発性関数」が影響している可能性があります。この記事では、Excelにおける揮発性関数の特性、代表的な関数について、解説します。

揮発性関数とは何か?

揮発性関数(Volatile Function)とは、その関数が含まれるセルだけでなく、ブック内のいずれかのセルが変更された場合や、特定の操作(ファイルの保存、シートの挿入や削除など)が行われた場合に、Excelが再計算を行うたびに、引数の変更の有無に関わらず必ず再計算される関数のことを指します。

例えば、NOW() 関数は現在の日時を返しますが、これはブックを開いたり、何か編集操作をするたびに更新される必要があります。そのため、NOW() は揮発性関数として扱われます。

非揮発性関数との違い

一方、ほとんどのExcel関数は「非揮発性関数(Non-volatile Function)」です。これらの関数は、その関数が直接参照しているセルや、計算に使われる引数に変更があった場合にのみ再計算されます。 これにより、Excelは無駄な計算を省き、効率的に動作します。

具体例で見てみましょう。

  • 非揮発性関数の例: セルA1に =SUM(B1:B5) という数式が入っているとします。この場合、B1からB5のいずれかのセルの値が変更された時だけ、A1のSUM関数が再計算されます。他の無関係なセルを変更しても、A1は再計算されません。
  • 揮発性関数の例: セルA2に =NOW() という数式が入っているとします。この場合、ブック内で何か変更(例えばC1セルに値を入力するなど)があるたびにA2のNOW関数が再計算され、表示される日時が更新される可能性があります。

ユーザーが通常の組み込み関数を意図的に揮発性関数に変更することはできません(VBAでユーザー定義関数を作成する場合は、そのように設定することが可能です)。

揮発性関数と非揮発性関数の主な違いまとめ

再計算の挙動
非揮発性関数: 参照セルや引数が変更された時のみ再計算されます。
揮発性関数: Excelが再計算を行うたびに必ず再計算されます。そのため、揮発性関数を含む数式は常に「変更されたもの」とみなされ(セルがdirty状態になる、とも表現されます)、Excelの再計算制御の仕組みに関わらず実行されます。
パフォーマンスへの影響
揮発性関数: 便利な反面、多用するとブックのパフォーマンスに悪影響を与える可能性があります。揮発性関数が一つでもあると、それが含まれる数式だけでなく、その数式を参照する他の多くのセルも連鎖的に再計算されることがあり、結果としてブック全体の動作が重くなることがあります。特に、データ量が多い、あるいは複雑な計算式が多いワークシートでは、この影響が顕著に現れることがあります。
他のブックへの影響
複数のExcelブックを開いている場合、いずれか一つのブックで何らかの変更(例えばセルの値を編集する、行を挿入するなど)を行うと、現在開いている全てのブックに含まれる揮発性関数が再計算されることがあります。これは、変更が加えられたブックだけでなく、何も操作していない他の開いているブックにも影響を及ぼすため、注意が必要です。
結果の予測可能性
非揮発性関数: 入力値が同じであれば、計算結果も常に同じです。例えば、=SUM(1, 2) は常に3を返します。
揮発性関数: 再計算のタイミングによって結果が変わる可能性があります。例えば、RAND() 関数は毎回異なる乱数を生成し、TODAY() 関数は日付が変わると結果も変わります。

代表的な揮発性関数一覧

以下は、Excel で主に使われる揮発性関数の一覧です。これらの関数は非常に便利ですが、使用する際はその揮発性を意識することが重要です。

NOW()
主な用途: 現在の日付と時刻 (シリアル値) を返します。
備考: ブックを開いたり、ワークシートが再計算されるたびに値が更新されます。そのため、この関数を使ってタイムスタンプを作成した場合、その時刻は常に「今」を指し続けることになります。ファイルを開き直すだけで変更があったとみなされることもあります。
TODAY()
主な用途: 現在の日付 (年月日) を返します。
備考: NOW() と同様に、再計算のたびに実行されます。通常、同日内に再計算されても日付は変わりませんが、ブックを開いたタイミングや日付が変わったタイミングで更新されます。
RAND()
主な用途: 0以上1未満の乱数を返します。
備考: 再計算ごとに異なる乱数を生成します。シミュレーションやランダムサンプリングなどに利用できますが、多用すると計算結果が常に変動し、意図しない再計算を引き起こす可能性があります。
RANDBETWEEN(最小値, 最大値)
主な用途: 指定した範囲内のランダムな整数を返します。
具体例: =RANDBETWEEN(1, 100) は、1から100までの整数をランダムに返します。
備考: 内部的にRAND()関数を利用しているため揮発性です。再計算のたびに結果が変わります。
RANDARRAY([行数], [列数], [最小値], [最大値], [整数判定])
主な用途: 指定した行数と列数の乱数の配列を返します。Excel 365で導入された動的配列関数の一つです。
具体例: =RANDARRAY(3, 4, 1, 10, TRUE) は、3行4列の範囲に1から10までのランダムな整数を生成します。
備考: RAND()と同様に揮発性です。大量の乱数を生成するとパフォーマンスに影響が出ることがあります。配列のサイズを他のセルの計算結果に依存させると、意図しない#SPILL!エラーが発生することもあります。
OFFSET(参照, 行数, 列数, [高さ], [幅])
主な用途: 指定したセル範囲から、指定した行数と列数だけシフトした位置にあるセルまたはセル範囲への参照を返します。動的な範囲参照を作成するのによく使われます。
具体例: =SUM(OFFSET(A1, 1, 1, 3, 2)) は、A1セルから1行下、1列右にシフトしたセル(B2)を開始点とし、高さ3行、幅2列の範囲(B2:C4)の合計を計算します。
備考: 非常に便利な関数ですが、常に揮発性です。多用するとブックのパフォーマンスを著しく低下させる原因となることがあります。可能な場合は、INDEX関数やテーブルの構造化参照、動的配列数式など、非揮発性の代替手段を検討することが推奨されます。
INDIRECT(参照文字列, [参照形式])
主な用途: 文字列で指定されたセル参照を評価し、その参照先のセルの内容を返します。他のセルの値を使って間接的にセル参照を組み立てる場合などに使用されます。
具体例: セルA1に “Sheet2” という文字列、セルA2に “B5” という文字列が入力されている場合、=INDIRECT(A1&"!"&A2) は、Sheet2のB5セルの値を返します。
備考: 常に揮発性です。参照文字列の解析と評価にコストがかかるため、大量に使用するとパフォーマンスが低下します。可能な限り直接参照や、INDEX関数とMATCH関数の組み合わせなどで代替することを検討しましょう。
CELL(検査の種類, [対象範囲])
主な用途: 指定したセルに関する情報(アドレス、列番号、ファイル名、書式など)を返します。
具体例: =CELL("address", A1) は、セルA1のアドレス “$A$1” を返します。=CELL("filename") は、現在のファイル名とパスを返します(ファイルが保存されていない場合は空文字列)。
備考: 引数「検査の種類」によって揮発性になる場合があります。特に CELL("filename") は、ブック名やパスの変更を検出するために揮発性として扱われる代表的な例です。セルの書式情報などを取得できますが、これらの情報が頻繁に変わることは稀なため、必要な場面以外での使用は控えるのが賢明です。
INFO(検査の種類)
主な用途: Excelのバージョン、OSのバージョン、現在の再計算モード、使用可能なメモリ量など、Excelやシステム環境に関する情報を返します。
具体例: =INFO("release") は、実行中のExcelのバージョン番号を文字列として返します。
備考: 取得する情報の内容によって揮発性となる場合があります。使用頻度は高くありませんが、特定の環境情報を取得する際に用いられます。環境情報が頻繁に変わることは通常ないため、結果を固定したい場合や頻繁な再計算が不要な場合は、使用を避けるか、一度取得した値をコピーして値として貼り付けるなどの工夫をすると良いでしょう。
SUMIF(範囲, 検索条件, [合計範囲]) (特殊な場合)
主な用途: 指定された検索条件に一致するセルの値を合計します。
備考: 通常は非揮発性関数ですが、第一引数の「範囲」と第三引数の「合計範囲」の行数または列数が異なる形で指定された場合、Excelはどのセルを合計すべきかを正確に判断するために、揮発性関数と同様の再計算を行うことがあります。例えば、=SUMIF(A1:A4, ">0", B1:D8) は、A1:A4の範囲で0より大きい値を検索し、それに対応するB1:D8の値を合計しようとしますが、引数「範囲」が引数「合計範囲」と異なっているサイズのため、意図しない動作や揮発性のような挙動を示す可能性があります。一方、=SUMIF(A1:A4, ">0", B1:B4)のように範囲と合計範囲のサイズが適切に対応していれば、通常は揮発性とはなりません。範囲指定の不整合に注意が必要です。

※上記の「SUMIF」のケースのように、本来は非揮発性の関数でも、特定の引数の与え方や関数の組み合わせによって、Excelの計算エンジンが安全策として揮発性関数に近い頻度で再計算を行うことがあります。

揮発性関数を使用する上での注意点

揮発性関数はその特性から、ブックのパフォーマンスに影響を与える可能性があるため、使用にはいくつかの注意点があります。

  • 使用は最小限に: 最も基本的な対策は、揮発性関数の使用を本当に必要な場面に限定することです。「この機能は揮発性関数でなければ実現できないか?」「もっと効率的な代替手段はないか?」を常に考えましょう。例えば、OFFSET関数の代わりに、非揮発性のINDEX関数とMATCH関数の組み合わせや、テーブルの構造化参照、新しい動的配列関数(FILTERSORTなど)を使用することで、パフォーマンスを改善できるケースが多くあります。
  • 乱数の扱い: シミュレーションなどで乱数が必要な場合でも、常に再計算させる必要がないのであれば、一度RAND関数やRANDARRAY関数で生成した乱数をコピーし、「値として貼り付け」を行うことで、揮発性を排除し、その後の不要な再計算を防ぐことができます。
  • 大規模なブックでの工夫:
    • 手動計算モードの利用: 特にデータ量が多いブックや、多数の揮発性関数を使用している場合、Excelの計算モードを「手動」に切り替えることを検討しましょう。これにより、セルを編集するたびに自動的に再計算が走るのを防ぎ、任意のタイミングで F9 キーを押すことで再計算を実行できます。
    • 揮発性関数の集約: もし複数の数式で同じ揮発性関数の結果(例えば、TODAY()で今日の日付)を利用する場合は、それぞれの数式に直接TODAY()を記述するのではなく、どこか一つのセル(例: Z1セル)に=TODAY()と入力し、他の数式からはそのZ1セルを参照するようにします。これにより、揮発性関数の計算回数を1回に抑えることができます。
  • 条件付き書式やデータの入力規則での使用: 条件付き書式やデータの入力規則の数式にも揮発性関数を使用できますが、これらも再計算のたびに評価されます。広範囲のセルに揮発性関数を用いた条件付き書式を設定すると、パフォーマンスに大きな影響が出ることがあるため注意が必要です。
  • 非揮発性の代替手段の活用: Excel 365では、スピル機能やXLOOKUP関数、LET関数、各種動的配列関数など、従来は揮発性関数に頼らざるを得なかった処理を、より効率的かつ非揮発的な方法で実現できる新しい機能が多数追加されています。これらの新機能を積極的に活用し、揮発性関数の使用を避けることも、安定したパフォーマンスのブックを作成するための重要なポイントです。
  • 誤解されがちな関数について: 過去の情報や一部の資料では「揮発性」とされていたものの、現在のExcelでは実際には非揮発性である関数も存在します。例えば、INDEXROWSCOLUMNSAREASといった関数は、古い情報源では揮発性として扱われることがありましたが、現行バージョンでは非揮発性です。特にINDEX関数は、OFFSET関数の強力な代替手段となり得るため、その特性を正しく理解しておくことが重要です。

まとめ

揮発性関数は、Excelに動的な機能をもたらす便利なツールですが、その「常に再計算される」という特性は、特に大規模なファイルや複雑な計算においてはパフォーマンス低下の要因となり得ます。一方で、非揮発性関数は必要な時にのみ再計算されるため、より安定したパフォーマンスを期待できます。

これらの関数の違いを理解し、それぞれの特性に応じて適切に使い分けることが、効率的で信頼性の高いスプレッドシートを作成する上で非常に重要です。Excelのバージョンアップに伴い、関数の挙動や新しい代替機能が登場することもあるため、常に最新の情報を確認し、最適な方法を選択するよう心がけましょう。

揮発性関数を賢く利用し、Excelのポテンシャルを最大限に引き出しましょう。

コメント