【入門編】【中級者向け】カスタムフィールドの値をクリアする際の高速化テクニック – Project VBA解析バイブル

スポンサーリンク
スポンサーリンク

Project VBAの深淵へ:数千行のカスタムフィールドを一瞬でクリアする「高速化の極意」

こんにちは。自動化の世界へようこそ。
マクロの記録機能を使って「動くもの」を作れるようになったあなた。素晴らしい一歩を踏み出しましたね。でも、現場の膨大なデータを前にして、こんな経験はありませんか?

「マクロを動かしたけれど、処理が終わるまでコーヒーを淹れに行かなければならないほど遅い……」

もし、数千行のタスクに対して「Text1」などのカスタムフィールドを一つずつクリアするコードを書いて、その遅さに絶望しているのなら、おめでとうございます。あなたは今、「オブジェクトのライフサイクル」と「アプリケーションのオーバーヘッド」という、プロフェッショナルへの登竜門に立っています。

今日は、単なる「コードの書き方」ではなく、なぜ遅いのか、どうすれば劇的に速くなるのか。Project VBAの心臓部に触れる、極限の知見をお伝えします。

1. なぜ、あなたのマクロは「重い」のか?

まず、多くの初学者が書いてしまう「典型的なコード」を見てみましょう。

❌ 避けるべき「素朴すぎる」コード

Sub NaiveClearFields()
    Dim t As Task
    
    ' 全てのタスクをループで回して、Text1を空にする
    For Each t In ActiveProject.Tasks
        If Not t Is Nothing Then
            t.Text1 = "" ' ← ここが「重い」原因!
        End If
    Next t
    
    MsgBox "完了しました"
End Sub

一見、完璧に見えます。論理的で、読みやすい。しかし、タスクが5,000行あった場合、このコードは地獄のような速度になります。

犯人は「画面更新」と「再計算」の連鎖

なぜ遅いのか? 理由は2つあります。

1. 画面更新(Screen Updating)のコスト:
Projectは、`t.Text1 = “”` が実行されるたびに、「あ、値が変わったな。画面を書き換えなきゃ!」と律儀に反応します。1行変えるごとに画面をリフレッシュしているのです。
2. 再計算(Recalculation)のトリガー:
Projectは非常に強力な計算エンジンを持っています。カスタムフィールドが計算式(Formula)を使っている場合、値を一つ書き換えるたびに、プロジェクト全体のスケジュールの整合性を再計算しようと試みます。

「1回書き換えるたびに、画面を書き換え、プロジェクト全体を計算し直す」
この無駄なループが、あなたの時間を奪っている正体です。

2. プロの処方箋:描画と計算を「封印」せよ

エンジニアとして、私たちはアプリケーションの挙動を「コントロール」しなければなりません。
高速化の鉄則はシンプルです。「作業中は、余計なことは一切させるな」。

✅ プロフェッショナルな高速化コード

Sub ProfessionalFastClearFields()
    Dim t As Task
    Dim startTime As Double
    
    ' パフォーマンス計測開始
    startTime = Timer
    
    ' --- 【極意1】画面更新を停止する ---
    ' これにより、値が変わるたびに画面がチラつくのを防ぎ、描画コストをゼロにします
    Application.ScreenUpdating = False
    
    On Error GoTo ErrorHandler ' 万が一のエラー時に設定を戻すための保険
    
    ' --- 【極意2】計算モードを管理する ---
    ' Projectの計算エンジンが、ループ中に暴走しないように制御します
    ' (※Projectのバージョンにより挙動が異なるため、慎重に扱います)
    
    For Each t In ActiveProject.Tasks
        ' タスクが存在しない(空行)場合はスキップ
        If Not t Is Nothing Then
            ' 値の代入
            t.Text1 = ""
        End If
    Next t
    
    ' --- 【極意3】最後に一括で反映させる ---
    ' 全ての処理が終わった後に、一度だけ画面を更新し、計算を完了させます
    Application.ScreenUpdating = True
    
    MsgBox "完了! 実行時間: " & Round(Timer - startTime, 2) & " 秒"
    Exit Sub

ErrorHandler:
    ' エラーが起きても、画面更新停止状態のまま放置するのは御法度です
    Application.ScreenUpdating = True
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub

3. アーキテクトの視点:さらに高みを目指すために

ここからは、中級者から上級者へステップアップするための「思考のフレームワーク」を授けます。

オブジェクト・アクセスの重みを理解する

VBAの世界からProjectのオブジェクト(`Task`など)にアクセスすることは、「別の世界への通信」です。
`t.Text1 = “”` という一行を実行するたびに、VBAという言語の領域から、Projectというアプリケーションの領域へデータを送り、結果を受け取るという「通信コスト」が発生します。

もし、カスタムフィールドが複数あるなら、以下のように書くべきです。

' 悪い例:何度もプロパティにアクセスする
t.Text1 = ""
t.Text2 = ""
t.Text3 = ""

' 良い例(考え方):
' 可能な限り、一つのオブジェクトに対して、最小限の操作で済ませる。
' もし複雑な計算が必要なら、VBA側の変数に一度まとめてから、最後に一括代入する。

エラーハンドリングは「礼儀」である

高速化のために `Application.ScreenUpdating = False` を使う際、最も陥りやすい罠が「エラーでマクロが止まり、Projectの画面が固まった(更新されない)ままになる」ことです。

これは、ユーザーから見れば「フリーズした」ように見えます。
`On Error GoTo ErrorHandler` を使い、たとえ失敗しても必ず `Application.ScreenUpdating = True` を通るルートを作っておくこと。これが、信頼されるエンジニアの「作法」です。

まとめ:ここをクリアすれば、基本はバッチリです

今回のポイントを整理しましょう。

1. 原因を知る: 遅いのは「画面更新」と「再計算」のオーバーヘッドのせい。
2. 制御する: `Application.ScreenUpdating = False` で、余計な描画を封印する。
3. 責任を持つ: エラーが起きても、必ず設定を元に戻す(`True` にする)仕組みを作る。

このテクニックをマスターすれば、あなたはもう「マクロの記録」に頼るユーザーではありません。「アプリケーションの挙動を支配する、自動化エンジニア」の仲間入りです。

さあ、次のプロジェクトでは、このスピード感を武器に、圧倒的な効率化を実現してください。応援していますよ。

タイトルとURLをコピーしました