Project VBAの「開始日固定」と依存関係:未来を縛り、過去を繋ぐ魔法
皆さん、こんにちは!Project VBAの世界へようこそ。私は、長年この世界でコードを紡いできた、いわば「VBAの錬金術師」のようなものです。今日は、皆さんがProject VBAを使いこなす上で、きっと「なるほど!」と思っていただける、とっておきのテクニックをお伝えします。
特に、マクロの記録だけでは物足りない、もっと自由にProject VBAを操りたい!そんな初学者の方や、脱初心者を目指す皆さんに向けて、「タスクの開始日を固定しつつ、依存関係を維持する」という、一見すると矛盾しているかのような、でも実は非常に強力な制御法について、図解を交えながら丁寧に解説していきますね。
ここをクリアすれば、Project VBAの基本はバッチリですよ。さあ、一緒にProject VBAの奥深い世界へ飛び込みましょう!
なぜ「開始日固定」と「依存関係」の両立が重要なのか?
Project VBAを触り始めたばかりの頃は、タスクの開始日や終了日を直接入力したり、依存関係を設定したりと、個々の機能に目が行きがちですよね。でも、実際のプロジェクト管理では、もっと複雑な状況が頻繁に起こります。
例えば、
- 「このタスクは、必ず〇月〇日に開始しなければならない!」
- 「そのタスクが終わらないと、次のタスクは絶対に始められない…」
このような、「絶対に変えられない期日」と「どうしても守らなければならない順序」が同時に存在する場合、どうすれば良いのでしょうか?
もし、開始日を固定したまま依存関係を設定しようとすると、Project VBAは「え?でも、このタスクの開始日は固定されているのに、前のタスクが終わらないと始められないって、どういうこと?」と混乱し、予期せぬ日付のズレや、エラーを引き起こしてしまいます。
そこで登場するのが、今回ご紹介する「開始日固定」と「依存関係」を両立させるためのVBA制御テクニックです。これをマスターすれば、プロジェクトの制約を正確に反映させ、より現実的で実行可能なスケジュールを作成できるようになります。
依存関係の基本:タスクの「繋がり」を理解する
まずは、依存関係の基本からおさらいしましょう。Project VBAでは、タスク同士を「繋げる」ことで、あるタスクの完了が次のタスクの開始に影響を与えるように設定できます。これが「依存関係」です。
主な依存関係の種類は以下の4つです。
1. 終了-開始 (FS: Finish-to-Start): 前のタスクが終了したら、次のタスクを開始する。(最も一般的)
2. 開始-開始 (SS: Start-to-Start): 前のタスクが開始したら、次のタスクも開始する。
3. 終了-終了 (FF: Finish-to-Finish): 前のタスクが終了したら、次のタスクも終了する。
4. 開始-終了 (SF: Start-to-Finish): 前のタスクが開始したら、次のタスクが終了する。(あまり使われない)
これを、図でイメージしてみましょう。
graph TD
A[タスクA] –>|FS| B(タスクB)
C[タスクC] –>|SS| D(タスクD)
E[タスクE] –>|FF| F(タスクF)
- タスクA → タスクB (FS): タスクAが終わらないと、タスクBは開始できません。
- タスクC → タスクD (SS): タスクCが始まったら、タスクDも開始できます。(例えば、並行して行う作業)
- タスクE → タスクF (FF): タスクEが終わったら、タスクFも終了できます。(例えば、最終確認と承認)
「開始日固定」の落とし穴と「制約日」の活用
さて、いよいよ本題です。Project VBAでタスクの「開始日」を固定したい場合、通常はタスクの「制約」設定を利用します。
プロジェクト管理画面でタスクをダブルクリックし、「タスク情報」ダイアログを開くと、「制約」タブがあります。ここで「制約の種類」を「開始指定日」などに設定し、「制約日」に具体的な日付を入力します。
しかし、この「開始指定日」を設定した状態で、さらに「依存関係」を設定しようとすると、問題が発生しやすいのです。Project VBAは、設定された「開始指定日」を最優先しようとするため、依存関係によって本来開始できないはずの日付にタスクが設定されそうになると、自動で日付を調整してくれなかったり、エラーメッセージを表示したりします。
陥りやすいエラー例:
「タスクA(開始指定日: 2023/10/26)が、タスクB(終了日: 2023/10/25)に依存しているのに、タスクBが終わる前にタスクAを開始しようとしている!どうしろと?!」
まるで、指示された期日を守ろうとするあまり、物理法則(タスクの依存関係)を無視してしまおうとするかのようです。
「開始日固定」と「依存関係」を両立させるVBA制御法
ここで、魔法の杖、いえ、VBAコードの出番です!
私たちが目指すのは、「タスクの開始日を固定しつつ、依存関係も正しく維持する」こと。これを実現するには、Project VBAの「自動平準化」機能と、制約設定の順序、そしてVBAでの微妙な制御が鍵となります。
1. VBAでの「制約」設定と「依存関係」設定の順番
Project VBAのオブジェクトモデル(VBAからProject VBAを操作するための仕組み)では、タスクのプロパティを操作する順番が重要になることがあります。
一般的に、タスクの「制約」を設定してから「依存関係」を設定すると、上記のような問題が起こりやすいです。そこで、逆に「依存関係」を先に設定し、その後に「開始日固定」の制約を設定する、という順序でVBAコードを記述してみましょう。
2. 「自動平準化」の活用
Project VBAには、「自動平準化」という便利な機能があります。これは、タスクの依存関係や制約に基づいて、プロジェクト全体のスケジュールを自動的に調整してくれる機能です。
この「自動平準化」を適切に利用することで、開始日を固定したいタスクであっても、依存関係を維持したまま、他のタスクの変更に影響されずに、その「開始指定日」を保つことができます。
3. VBAコード例:開始日固定タスクと依存関係の自動設定
それでは、具体的なVBAコードを見てみましょう。
ここでは、以下のシナリオを想定します。
- 「タスクX」 の開始日を 「2023/10/26」 に固定したい。
- 「タスクY」 は、 「タスクA」 が終了したら開始する(FS依存関係)。
- 「タスクZ」 は、 「タスクX」 が開始したら開始する(SS依存関係)。
Sub SetFixedStartDateAndDependencies()
Dim pj As Project
Dim tskX As Task
Dim tskY As Task
Dim tskZ As Task
Dim tskA As Task
Dim fixedStartDate As Date
‘ Projectオブジェクトを取得 (現在アクティブなプロジェクト)
Set pj = Application.ActiveProject
‘ 固定したい開始日を設定
fixedStartDate = CDate(“2023/10/26”)
‘ — タスクの参照 —
‘ 実際には、タスク名やIDで検索して取得してください。
‘ ここでは例として、Nameプロパティで取得しています。
On Error Resume Next ‘ タスクが見つからなくてもエラーで止まらないようにする
Set tskX = pj.Tasks.UniqueID(3) ‘ 例: UniqueIDが3のタスク
Set tskY = pj.Tasks.UniqueID(4) ‘ 例: UniqueIDが4のタスク
Set tskZ = pj.Tasks.UniqueID(5) ‘ 例: UniqueIDが5のタスク
Set tskA = pj.Tasks.UniqueID(2) ‘ 例: UniqueIDが2のタスク
On Error GoTo 0 ‘ エラーハンドリングを元に戻す
‘ — タスクが見つからなかった場合のエラー処理 —
If tskX Is Nothing Or tskY Is Nothing Or tskZ Is Nothing Or tskA Is Nothing Then
MsgBox “指定されたタスクが見つかりませんでした。タスク名やIDを確認してください。”, vbCritical
Exit Sub
End If
‘ — 依存関係の設定 (先に設定する) —
‘ タスクY: タスクA (FS: Finish-to-Start) 依存
‘ Successor: 次のタスク (タスクY)
‘ Predecessor: 前のタスク (タスクA)
‘ Link: 依存関係の種類 (pjFinishToStart)
tskY.Predecessors.Add tskA.UniqueID, pjFinishToStart
‘ タスクZ: タスクX (SS: Start-to-Start) 依存
tskZ.Predecessors.Add tskX.UniqueID, pjStartToStart
‘ — 開始日固定の制約設定 (後から設定する) —
‘ タスクXの制約の種類を「開始指定日」に設定
tskX.ConstraintType = pjConstraintMustStartOn
‘ タスクXの制約日を開始日として設定
tskX.ConstraintDate = fixedStartDate
‘ — 重要: 自動平準化の実行 —
‘ このコードを実行する前に、Project VBAの「ツール」>「オプション」>「スケジュール」タブで
‘ 「タスクの平準化」が有効になっていることを確認してください。
‘ もしくは、VBAから設定することも可能です。
‘ Application.AutoSchedule = True ‘ 全てのタスクを自動スケジュールする場合
‘ pj.AutoSchedule = True ‘ プロジェクト全体を自動スケジュールする場合
‘ ここでは、手動で平準化を実行するイメージです。
‘ 実際には、Application.CalculateUntil(Now) などで計算をトリガーするのが一般的です。
‘ もしくは、タスクのプロパティ変更が自動で再計算を促す場合もあります。
‘ この例では、制約設定後にProject VBAが自動的に再計算してくれることを期待します。
MsgBox “タスク ‘” & tskX.Name & “‘ の開始日を固定し、依存関係を設定しました。”, vbInformation
End Sub
コードの解説:
- `Dim pj As Project`, `Dim tskX As Task` など: 各オブジェクト(プロジェクト、タスク)を格納するための変数を宣言しています。
- `Set pj = Application.ActiveProject`: 現在開いているProject VBAのプロジェクトを取得します。
- `fixedStartDate = CDate(“2023/10/26”)`: VBAで日付を扱う際は、`CDate`関数で文字列を日付型に変換すると安全です。
- `Set tskX = pj.Tasks.UniqueID(3)`: タスクは、`UniqueID`(一意のID)や`ID`(表示上のID)、`Name`(タスク名)などで参照できます。`UniqueID`は、タスクの削除や追加があっても変わらないため、VBAで扱う際には最も信頼性が高いです。
- `tskY.Predecessors.Add tskA.UniqueID, pjFinishToStart`: ここが依存関係を設定する部分です。
- `tskY.Predecessors.Add`: `tskY`(タスクY)に先行タスク(Predecessor)を追加します。
- `tskA.UniqueID`: 先行タスクの`UniqueID`を指定します。
- `pjFinishToStart`: 依存関係の種類を指定します。`pjFinishToStart`は「終了-開始」を意味します。他にも`pjStartToStart`(開始-開始)などがあります。
- `tskX.ConstraintType = pjConstraintMustStartOn`: タスクXの制約の種類を「開始指定日 (Must Start On)」に設定します。
- `tskX.ConstraintDate = fixedStartDate`: 設定した「開始指定日」を代入します。
実行上の注意点:
1. タスクの検索: 上記コードの `pj.Tasks.UniqueID(3)` の部分は、ご自身のプロジェクトのタスクに合わせて、`UniqueID`、`ID`、または`Name`で正しくタスクを取得するように変更してください。`UniqueID`で取得するのが最も確実です。
2. 自動平準化の有効化: Project VBAの「ツール」>「オプション」>「スケジュール」タブで、「タスクの平準化」にチェックが入っていることを確認してください。または、VBAで `Application.AutoSchedule = True` や `pj.AutoSchedule = True` を実行しておくと、変更が自動的にスケジュールに反映されやすくなります。
3. 計算のトリガー: VBAコードを実行した後、Project VBAの画面上で明示的に計算が実行されない場合があります。その場合は、Excelなどで適当なセルに数式を入力して再計算を促すか、VBAで `Application.CalculateUntil(Now)` のようなコードを実行して、再計算をトリガーしてみてください。
このテクニックの応用:柔軟なスケジュール管理へ
この「開始日固定」と「依存関係」の制御法をマスターすると、Project VBAでのスケジュール管理が格段に柔軟になります。
- 外部要因による影響の最小化: 特定のタスク(例: 承認、資材調達の開始)が外部要因で期日を固定されている場合でも、そのタスクに依存する後続タスクのスケジュールを、依存関係を保ったまま自動調整させることができます。
- 「クリティカルパス」の正確な把握: クリティカルパス(プロジェクト完了日を左右する最も重要なタスクの連なり)を正確に把握するには、各タスクの依存関係と制約を正確に設定することが不可欠です。このテクニックは、その精度を高めるのに役立ちます。
- 「もし〜だったら」シナリオのシミュレーション: 特定のタスクの開始日を仮に変更した場合、プロジェクト全体にどのような影響が出るかをシミュレーションする際にも、この制御法が役立ちます。
まとめ:Project VBAの「未来を縛り、過去を繋ぐ」魔法を使いこなそう
いかがでしたでしょうか?
今回は、Project VBAにおける「タスクの開始日を固定しつつ、依存関係を維持する」という、少し高度ですが非常に実用的な制御法について解説しました。
- 依存関係を先に設定し、制約(開始日固定)を後から設定する
- 自動平準化機能を活用する
この2つのポイントを意識してVBAコードを記述することで、Project VBAはあなたの指示を正確に理解し、意図した通りのスケジュールを生成してくれるようになります。
マクロの記録だけでは決して到達できない、Project VBAの「本質」に一歩近づいたのではないでしょうか?
この知識を武器に、ぜひ皆さんのプロジェクト管理をより洗練させていってください。そして、もし分からないことや、さらに深掘りしたいことがあれば、いつでも声をかけてくださいね。Project VBAの旅は、まだまだ続きます!
