こんにちは!日々のマクロ作成、お疲れ様です。
「マクロの記録」から一歩踏み出し、自力でコードを書けるようになると、ExcelやProjectといったMicrosoft Office製品の自動化が劇的に楽しくなりますよね。
今回は、実務で大量のデータを扱うプログラミングにおいて絶対に避けて通れない「超重要テクニック」のお話です。
「マクロを動かしたら、なんだか画面がフリーズしたみたいに固まって全然終わらない……」
そんな経験はありませんか? もしかしたらそれ、ExcelやProjectが「要所要所で、余計なおせっかい(自動再計算)を一生懸命やっているから」かもしれません。
ここをクリアすれば、あなたの書くコードは見違えるほど高速化し、VBAの基本を完全にマスターした「中級者の扉」を確実に開くことができますよ。さあ、優しく紐解いていきましょう!
—
1. なぜマクロは遅くなるのか?(スケジュール計算エンジンの正体)
ExcelやProjectなどのアプリケーションには、裏側でデータを監視し、値が変わるたびに全体の関係性を計算し直す「再計算エンジン」というものが常にスタンバイしています。
例えば、Projectで数百行にわたるタスクの開始日や制約条件(ASAP:できる限り早く、ALAP:できる限り遅く、など)を一括で変更するプログラムを書いたとします。
- 素朴なコードの場合:
1. 1行目の制約を変える ➔ 「大変だ!全体を再計算しなきゃ!」(エンジンが爆音で稼働)
2. 2行目の制約を変える ➔ 「また変わった!全体を再計算しなきゃ!」(再びエンジンがフル回転)
3. 3行目の……(以下、無限ループ)
これでは、まるで「赤信号のたびにアクセルを全開にしては急ブレーキを踏む」ようなもので、パソコンにものすごい負荷がかかります。処理が遅くなるのは当然ですよね。
解決の鍵:Application.Calculationプロパティ
この無駄な暴走を防ぐのが、`Application.Calculation` というプログラティングのスイッチです。
「これから大量のデータを書き換えるから、私の合図が出るまで勝手に再計算しちゃダメだよ(手動モード)」
とVBAで指示を出し、すべての書き換えが終わった瞬間に「はい、今のデータを元に一回だけ再計算して!(自動モードに戻す)」と命令する。
この「非同期的なエンジン制御(手動化と一括再計算)」こそが、プロのエンジニアが必ず実装している鉄則のアーキテクチャなのです。
—
2. 実践!爆速スケジュール制御アーキテクチャ
百聞は一見にしかず。実際のコードを見てみましょう。
今回は、大量のタスクに対して何らかの制約条件や日付の変更を一気に行うシーンを想定した、実用的なVBAコードです。
Sub OptimizeScheduleUpdate()
Dim app As Object
Set app = Application
‘ —————————————————-
‘ 1. エラー対策の準備
‘ —————————————————-
On Error GoTo ErrorHandler
‘ —————————————————-
‘ 2. 計算エンジンの停止(ここが最重要!)
‘ —————————————————-
‘ 自動計算をオフにし、VBAが裏で勝手に再計算するのを完全にブロックします
app.Calculation = xlCalculationManual ‘ ※Projectの場合は環境に応じた制御プロパティを使用
‘ 画面の描画も一時停止することで、さらなる高速化を図ります
app.ScreenUpdating = False
app.DisplayAlerts = False
‘ —————————————————-
‘ 3. メインの大量データ処理(例:ループ処理)
‘ —————————————————-
Dim i As Long
For i = 1 To 10000
‘ ここで大量の制約変更やパラメータ書き換えを実行
‘ 例: Cells(i, 2).Value = “ASAP”
‘ (※この間、再計算は一切走りません!驚異的なスピードで処理されます)
Next i
‘ —————————————————-
‘ 4. 一括再計算と設定の復元
‘ —————————————————-
‘ 処理がすべて終わったので、ここで「1回だけ」全体を再計算させます
app.Calculation = xlCalculationAutomatic
app.Calculate ‘ 強制再計算の実行
‘ 画面描画を元に戻す
app.ScreenUpdating = True
app.DisplayAlerts = True
MsgBox “すべてのスケジュール最適化が完了しました!”, vbInformation
Exit Sub
ErrorHandler:
‘ —————————————————-
‘ 5. 堅牢なエラーハンドリング(絶対忘れちゃダメな理由)
‘ —————————————————-
‘ 万が一マクロの途中でエラーが起きた場合でも、設定を必ず元に戻します
app.Calculation = xlCalculationAutomatic
app.ScreenUpdating = True
app.DisplayAlerts = True
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub
—
3. コードの心臓部を深掘り!知っておくべきポイント
上記のコードには、プログラミング初心者から一歩抜け出すための重要な知見が詰まっています。いくつかポイントを解説しますね。
① なぜ `On Error GoTo` が必要なのか?
もし、計算を手動(Manual)にしたままプログラムの途中でエラーが起き、マクロが強制終了してしまったらどうなるでしょうか?
なんと、Excel(またはProject)全体が「手動計算モードのまま」凍結されてしまいます。 その後、ユーザーが普通に表にデータを入力しても、合計値や関数が一切自動で変わらなくなるため、「バグった!Excelが壊れた!」と大パニックになります。
だからこそ、プロのコードには必ず 「エラーが起きたときでも、確実に設定を元に戻す保険(ErrorHandler)」 がセットで組み込まれているのです。
② 画面描画(ScreenUpdating)とのコンボ技
`Calculation = xlCalculationManual` と合わせて使いたいのが `ScreenUpdating = False` です。
VBAがセルやタスクを1つ書き換えるたびに、Excelは律儀に画面の見た目をパッと描き直そうとします。これも動作が重くなる大きな原因。
裏でこっそり作業を進めさせ、最後に「はい、おしまい!」と画面をパッと最新の状態に切り替えることで、体感速度は数倍〜数十倍に跳ね上がります。
—
4. 初学者が陥りがちな「罠」と注意点
ここだけは気をつけてほしい、というポイントをいくつか挙げておきます。
- 「とりあえず何でもかんでも手動にすればいいや」の罠
ループの中で書き換えた値に「依存する別の値」を、ループの途中で読み取ろうとするコードを書いている場合、計算エンジンを止めていると「古い値」を拾ってしまい、計算結果が狂います。
あくまで「書き換えは一気に済ませ、最後にまとめて計算させる」という独立したロジックの時に使いましょう。
- オブジェクトモデルの違いに注意
Excel VBAでは `Application.Calculation = xlCalculationManual` ですが、Microsoft Project VBAなどを操作する際は、アプリケーションの仕様やスケジューリングモード(手動スケジュール vs 自動スケジュール)の挙動に合わせた適切なメソッドやプロパティ選択が必要になります。基本の考え方は同じですが、リファレンスをしっかり確認するクセをつけましょう。
—
まとめ:ここをクリアすれば、もう「初心者」とは言わせない!
いかがでしたでしょうか?
今回紹介した 「Application.Calculationプロパティによる再計算エンジンの非同期制御」 は、単なるテクニックではなく、アプリケーションのライフサイクルを理解したプロフェッショナルな設計思想そのものです。
「ただ動くコード」から「速く、安全で、環境に優しいコード」へ。
この概念をあなたの引き出しに加えることができれば、明日からのVBA開発の景色がガラリと変わるはずです。
ここをクリアしたあなたなら、どんなに巨大なスケジュールデータや複雑な制約条件を扱う案件が来ても、もう怖くありませんよ。ぜひ、実際の業務コードに応用してみてくださいね!
