ユーザー定義関数(UDF)の落とし穴:Excelが「重くなる」真犯人を特定せよ
こんにちは。現場で泥臭く、かつエレガントな自動化を追求しているエンジニアです。
「マクロの記録」から一歩踏み出し、自分だけの関数(ユーザー定義関数:UDF)を作れるようになると、Excelの世界は一気に広がります。しかし、多くの初学者がここで最初の壁にぶつかります。
「関数を作った途端、Excelが異様に重くなった……」
これは、あなたが書いたコードのせいではありません。Excelの「再計算の仕組み」を理解していないことが原因です。今日は、この不可視のモンスターを手懐け、プロのパフォーマンスを手に入れるための極意をお伝えします。
—
1. UDFが引き起こす「再計算」の罠
Excelのワークシート関数は、基本的に「入力値が変わった時だけ再計算される」という賢いルールで動いています。
しかし、UDF(Functionプロシージャ)をセルに書き込むと、Excelはこう考えます。
「この関数の中に何が書いてあるか分からないから、シート上で何か変更があるたびに、念のため毎回計算し直そう」
これが重さの正体です。数百、数千ものセルでUDFを呼び出している場合、たった一つのセルを編集しただけで、Excelは全てのUDFを再計算し、フリーズに近い状態になるのです。
—
2. 禁断のキーワード `Application.Volatile`
VBAには、この再計算の挙動を制御する強力なメソッドがあります。それが `Application.Volatile` です。
- `Application.Volatile` を書くと:
シート上の「どのセル」を変更しても、その関数は強制的に再計算されます。
- 書かないと:
引数として渡されたセルが変更された時だけ再計算されます。
ここが極限の知見
多くの入門書では「常に最新の結果を表示するために書こう」と教えられますが、これは半分正解で、半分は罠です。
本当に必要な時(例えば `Now` 関数のように、時間が経てば値が変わる関数を作る時)以外、`Application.Volatile` を使うのは「パフォーマンスの自殺行為」です。
—
3. 実践:賢いUDFの書き方
では、実際に「重くならない」UDFの書き方を比較してみましょう。
悪い例:意図せず重くしているコード
Function BadCalculation(rng As Range)
‘ 理由なくVolatileを呼ぶと、シートのどこを触っても再計算が走る
Application.Volatile
‘ 複雑な計算処理…
BadCalculation = rng.Value 1.08
End Function
良い例:必要な時だけ動くスマートなコード
Function GoodCalculation(rng As Range) As Double
‘ Application.Volatile を書かない!
‘ これだけで、rngの値が変わった時しか計算が走らなくなる
If IsNumeric(rng.Value) Then
GoodCalculation = rng.Value 1.08
Else
GoodCalculation = 0
End If
End Function
—
4. パフォーマンスを劇的に改善する3つの鉄則
現場でトラブルを避けるために、これだけは心に刻んでください。
1. Volatileは「最後の手段」
どうしても「今の時刻」や「計算結果が外部要因で変わる」場合以外、`Application.Volatile` は封印してください。
2. 引数を明示する
UDF内で使う値は、必ず「引数」として渡してください。引数を使わずに `Range(“A1”).Value` のようにセルを直接参照すると、Excelはその依存関係を見失い、再計算の制御が効かなくなります。
3. 重い処理はUDFにしない
複雑なループや大量のデータ検索をUDFに入れるのはNGです。それは「ボタンを押して動かすマクロ(Sub)」の役割です。UDFはあくまで「単純な計算の拡張」に留めましょう。
—
最後に:Excelと仲良くなるために
「マクロが遅い」と感じたとき、それはExcelが悲鳴を上げているサインです。
今日学んだ「再計算のタイミングを制御する」という視点を持てば、あなたはもう「マクロを記録する人」ではありません。「Excelの挙動を支配するアーキテクト」への第一歩を踏み出したのです。
まずは今書いているUDFから、不要な `Application.Volatile` を削除してみてください。驚くほど軽快なExcelが戻ってくるはずです。
ここをクリアできれば、あなたのVBAライフはより強固で美しいものになりますよ。また次のステップで、さらに深い世界を探求していきましょう!
