こんにちは! Project VBAの世界へようこそ。
マクロの記録ボタンを押すだけのステージから抜け出し、「自分の手でプロジェクトの時間を自在にデザインしたい」そう思ってこのページに辿り着いたあなたへ。
今回は、実務の現場でめちゃくちゃ重宝する「タスクの期間に応じて依存関係のラグタイム(遅延時間)を自動計算し、スケジュールに反映させるロジック」を伝授します。
「先行タスクがこれくらいの日数かかるなら、後続タスクはその30%分だけ遅らせてスタートさせたい」――そんな複雑なWBSの調整、手動でやってたら日が暮れますよね。それをVBAのエンジンで一瞬にして自動化してしまいましょう。
ここをクリアすれば、Project VBAの基本と「実務で使えるオブジェクト操作の作法」はバッチリです。温かく導きますので、一緒に一歩ずつ進んでいきましょう!
—
1. なぜ「ラグタイムの自動化」が必要なのか?
MS Projectでは、タスク同士を繋ぐ「依存関係(FS: Finish-to-Startなど)」に、ラグタイム(Lag Time)を設定できます。「先行タスク終了後、2日空けてから着手する」といった調整ですね。
しかし、プロジェクトの規模が大きくなると、こんな課題に直面します。
- 「タスクAの期間が変更されるたびに、後続タスクのラグ(例えば期間の20%分)を手動で計算し直すのは無理…」
- 「人間が計算すると、小数点以下の丸め誤差や入力ミスが必ず起きる」
これをVBAで解決します。「先行タスクの期間(Duration)を取得し、その〇%を計算して、後続タスクのラグ(Lag)に代入する」。この一連の流れをコード化していきましょう。
—
2. 実装コード:コピペで動く実践VBA
まずは、開発現場でそのまま使えるコードをお見せします。
今回は、「選択しているタスク(または指定したタスクIDのペア)」に対し、先行タスクの期間の「30%」を後続タスクのラグとして自動設定するマクロです。
Sub AutoCalculateLagTime()
‘ =====================================================================
‘ テーマ: 先行タスクの期間に対するパーセンテージでラグタイムを自動設定する
‘ 対象: アクティブプロジェクトの選択タスク(先行・後続のペア)
‘ =====================================================================
Dim tskPredecessor As Task ‘ 先行タスク
Dim tskSuccessor As Task ‘ 後続タスク
Dim dep As Dependency ‘ 依存関係オブジェクト
Dim durDays As Double ‘ 先行タスクの期間(日換算)
Dim lagMinutes As Long ‘ 計算されたラグ(分換算)
Const LAG_RATIO As Double = 0.3 ‘ ラグの割合(30%の場合は 0.3)
‘ エラーハンドリングの基本:画面描画を停止して爆速化
Application.ScreenUpdating = False
On Error GoTo ErrorHandler
‘ ユーザーがタスクを選択しているかチェック
If ActiveSelection.Tasks.Count = 0 Then
MsgBox “対象となるタスクを選択してください。”, vbExclamation, “入力エラー”
Exit Sub
End If
‘ 選択されたタスクの最初のタスクを「後続タスク」と仮定して処理
‘ (※実務ではWBSのループ処理に組み込みますが、今回は分かりやすく単体ペアで解説)
Set tskSuccessor = ActiveSelection.Tasks(1)
‘ このタスクに「先行タスク」が設定されているか確認
If tskSuccessor.PredecessorTasks.Count = 0 Then
MsgBox “選択されたタスクには先行タスクが設定されていません。”, vbExclamation, “前提エラー”
Exit Sub
End If
‘ 最初の先行タスクを取得
Set tskPredecessor = tskSuccessor.PredecessorTasks(1)
‘ MS Projectの期間(Duration)の内部単位は「分(Minutes)」です。
‘ 日数に直すために 480(8時間/日 × 60分)で割るのが定番のテクニック!
durDays = tskPredecessor.Duration / 480
‘ 【コアロジック】先行タスクの期間の30%をラグとして計算
‘ MS Projectのラグの基本単位も「分」なので、日数を再び分(×480)に戻します
lagMinutes = CLng((durDays LAG_RATIO) 480)
‘ 後続タスクの「依存関係(Predecessorsコレクション)」を走査し、該当するラグを書き換える
For Each dep In tskSuccessor.DependencyPredecessors
If dep.FromTask.ID = tskPredecessor.ID Then
‘ ラグを設定(分単位で渡すのがProject VBAの作法)
dep.Lag = lagMinutes & “m”
Exit For
End If
Next dep
Application.ScreenUpdating = True
MsgBox “ラグタイムの自動計算が完了しました!” & vbCrLf & _
“先行タスク期間: ” & durDays & “日” & vbCrLf & _
“設定されたラグ: ” & (lagMinutes / 480) & “日”, vbInformation, “成功”
Exit Sub
ErrorHandler:
Application.ScreenUpdating = True
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
End Sub
—
3. コードのキモを噛み砕く!プロの技術解説
ここからは、コードの裏側にある「Project VBAならではの設計思想」を解説します。ここを理解すると、他のコードを書くときにも応用が効くようになりますよ。
① 時間単位の罠:「分(Minutes)」で考える
Excel VBAと大きく違うところ、それは MS Projectの内部データはすべて「分(Minutes)」で保持されている という点です。
- `Duration` プロパティを取得すると、例えば「3日」であっても `1440`(分)という数値返ってきます。
- 標準的な1日を8時間(480分)として計算するため、コード内では `480` で割ったり掛けたりしています。ここがProject VBAで最もつまずきやすいポイントですが、これをクリアすればもう怖くありません!
② 依存関係(Dependency)オブジェクトのライフサイクル
タスクとタスクを繋ぐ線は、Excelにはない概念です。
MS Projectでは、「後続タスク側から見た先行タスクとの関係」を `Dependency` オブジェクトとして操作します。
- `tskSuccessor.DependencyPredecessors` をループさせることで、どのタスクとどう繋がっているかをピンポイントで特定し、`dep.Lag = …` で数値を流し込むことができます。
③ 画面描画の停止 (`ScreenUpdating = False`)
大規模なWBSに対して何百行ものラグ計算を走らせるとき、画面がチカチカ描画されると処理が極端に遅くなります。
処理の最初に `ScreenUpdating = False` を挟み、最後に `True` に戻す。これは伝説的なエンジニアたちが必ず仕込む、パフォーマンス最適化の基本中の基本です。
—
4. 陥りやすいエラーと対策
初心者のうちは、こんな壁にぶつかりがちです。あらかじめ知っておけば怖くありません。
- エラー:「型が一致しません」 (Error 13)
- 原因: ラグに代入する際、数値をそのまま渡そうとするとProjectが混乱することがあります。
- 対策: コードのように `& “m”` と文字結合させて文字列として渡す(例: `”1440m”`)か、適切な型変換(`CLng`など)を行うのが安全です。
- 「先行タスクがありません」というエラー
- 原因: ネットワーク線が繋がっていないタスクに対してラグ計算を実行してしまっています。
- 対策: コード内に入れているような `If tskSuccessor.PredecessorTasks.Count = 0` による事前チェックを必ず入れる癖をつけましょう。
—
最後に:ここをクリアすれば、あなたはもう中級者!
お疲れ様でした!
「タスクのプロパティを読み取り、計算し、依存関係というリレーションシップを書き換える」――この一連の自動化を自分の手で動かせたなら、あなたのProject VBAスキルは確実に「マクロの記録」のレベルを卒業しています。
実務では、これをさらに発展させて「プロジェクト全体の全タスクをループ処理し、WBSの階層構造(WBSレベル)やカスタムフィールドの値に応じて動的にラグを変える」といった高度な自動化に応用できます。
ぜひ今日のコードをあなたのプロジェクトに持ち帰り、スマートなスケジュール管理を実現してみてください。
ここをクリアしたあなたなら、どんな自動化も絶対にモノにできますよ。応援しています!
