【入門編】プロ向け:計算エンジンの挙動を制御する隠し設定(Options)のVBA操作 – Project VBA解析バイブル

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

「マクロの記録」の先へ。Project VBAの心臓部「計算エンジン」を支配する技術

こんにちは。プロジェクト管理の自動化、その深淵へようこそ。

あなたがもし今、「マクロの記録」ボタンを押し、画面上の操作をそのままコードに書き出す段階にいるとしたら……おめでとうございます。あなたは自動化の第一歩を、正しく踏み出しました。

しかし、もしあなたが「なぜか日付が思い通りに動かない」「大量のタスクを更新すると、画面が固まって動かなくなる」「制約条件を入れたはずなのに、計算結果が矛盾している」といった壁にぶつかっているのなら、それはあなたが「Projectの心臓部(計算エンジン)」に触れようとしている証拠です。

Project VBAは、単なる「Excelのようなセル操作」ではありません。それは、膨大な依存関係と制約条件を解く「数理モデルの制御」なのです。

今日は、プロのエンジニアが現場で密かに行っている、`Application.Options` を介した計算エンジンの制御術について、その本質を解き明かしていきましょう。ここをクリアすれば、あなたの作るツールは「ただの記録」から「信頼できるシステム」へと昇華します。

1. なぜ「自動計算」があなたのコードを破壊するのか

Projectを開いているとき、タスクの期間を変えると、後続のタスクがスルスルと動きますよね? これが「自動計算(Automatic Calculation)」です。

初心者の方は、この「便利さ」に頼りがちです。しかし、大規模なプロジェクト(数千タスク規模)をVBAで操作するとき、この自動計算こそが最大の敵になります。

陥りやすい罠:パフォーマンスの崩壊

例えば、1,000個のタスクに対して、ループ処理で一つずつ「期間」を書き換えるコードを書いたとしましょう。

  • 自動計算がONの場合:

1個目のタスクを変更 $\rightarrow$ 全プロジェクトの再計算 $\rightarrow$ 2個目のタスクを変更 $\rightarrow$ また全再計算……
結果として、1,000回の全計算が走り、処理時間は指数関数的に増大します。

解決策:計算モードの「サンドイッチ制御」

プロは、処理の開始前に計算を「手動」に切り替え、すべての書き換えが終わった最後に一度だけ「再計算」を実行します。これをサンドイッチ制御と呼びましょう。

' --- 計算エンジンの制御パターン ---
Sub OptimizedTaskUpdate()
    On Error GoTo ErrorHandler
    
    ' 1. 画面更新を止めて、計算モードを手動(Manual)に切り替える
    ' これが「エンジンの暴走」を防ぐ鍵です
    Application.Options.Calculate = pjManual
    
    ' 2. メインの処理(大量のデータ更新)
    Dim t As Task
    For Each t In ActiveProject.Tasks
        If Not t Is Nothing Then
            ' 例:特定の条件に基づいて期間を変更
            t.Duration = t.Duration + 2 * pjDay 
        End If
    Next t
    
    ' 3. 最後に一度だけ、エンジンのスイッチを「自動」に戻して再計算させる
    Application.Options.Calculate = pjAutomatic
    
    MsgBox "更新が完了しました!", vbInformation
    Exit Sub

ErrorHandler:
    ' エラーが起きても、計算モードが「手動」のまま放置されると
    ' ユーザーが「Projectがおかしくなった!」と混乱するため、必ず戻す
    Application.Options.Calculate = pjAutomatic
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub

2. 制約条件(Constraints)の正体:ASAPとALAPを操る

次に、多くのユーザーが混乱する「日付が動かない問題」について。
Projectには、タスクの動きを縛る「制約条件(Constraint)」があります。

VBAで `Task.Start` や `Task.Finish` に直接日付を代入しようとしても、そのタスクに「Must Finish On(〇月〇日に終了しなければならない)」という強い制約がかかっていたら、エンジンはあなたの命令を拒絶(無視)します。

プロが理解すべき「制約の強さ」

制約には、エンジンの計算を「強く縛るもの」と「緩やかに従わせるもの」があります。

  • pjAsSoonAsPossible (ASAP): 「できるだけ早く」。エンジンの計算結果に身を任せる、最も柔軟な状態。
  • pjMustStartOn / pjMustFinishOn: 「必ずこの日に」。エンジンの計算を強制的に上書きする、最も硬直した状態。

あなたがVBAでスケジュールを「最適化」したいなら、まず制約を「緩いもの」に解いてから、日付を操作するのが鉄則です。

実践:制約を動的に制御するコード

Sub ResetAndSetConstraints()
    Dim t As Task
    Set t = ActiveProject.Tasks(1) ' 対象のタスク
    
    ' --- プロのテクニック ---
    ' 1. まず、既存の「強い制約」を解除して ASAP(できるだけ早く)に戻す
    ' これをしないと、日付の代入が無視されることがあります
    t.ConstraintType = pjAsSoonAsPossible
    
    ' 2. その上で、スケジュールを制御する
    ' 例えば、特定のタスクを「遅らせる」のではなく「制約で固定する」場合
    t.Start = DateAdd("d", 7, Date) ' 7日後に開始
    t.ConstraintType = pjStartNoEarlierThan ' 「これより前には開始しない」という緩い制約へ
    
    ' 3. ALAP(できるだけ遅く)を実現したい場合
    ' Projectには直接の「ALAP属性」はありません。
    ' 「制約を外した状態で、後続関係を調整する」のがエンジニアの仕事です。
End Sub

3. まとめ:エンジニアとしての視点

ここまで読んでくれたあなたに、最後に大切なことを伝えます。

Project VBAを扱うとき、あなたは「セルの値を書き換える作業員」であってはなりません。あなたは「プロジェクトの論理構造を設計するアーキテクト」であるべきです。

  • パフォーマンスを意識せよ: `Application.Options.Calculate` を使い、計算のタイミングを支配する。
  • 論理の矛盾を防げ: `ConstraintType` を理解し、エンジンの「拒絶」を予測する。
  • エラーハンドリングを忘れるな: 計算モードを「手動」にしたままエラーで終了させることは、ユーザーの作業環境を破壊する行為です。

「マクロの記録」で得たコードを、今日の知識を使って「整理・再構築」してみてください。それこそが、脱・初級者への最短ルートです。

ここをクリアすれば、Project VBAの基本はバッチリですよ。
さあ、次の自動化へ向かって、素晴らしいコードを書き進めてください!

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