【Project VBA極意】「稼働日」を制する者はスケジュールを制す ― カレンダー連携の自動化設計
こんにちは。プロジェクト管理の現場で「なぜかスケジュールの計算がズレる」という悩みに頭を抱えたことはありませんか?
Project VBAを使いこなす上で、多くの人が「タスクの開始日・終了日」という表面的なデータばかりを追いかけます。しかし、真に自動化を極めたエンジニアは違います。彼らが見ているのは、その裏側にある「カレンダー」という名のエンジニアリングの心臓部です。
今日は、Project VBAにおける「カレンダー情報の取得と稼働日計算」という、中級者への登竜門を徹底解説します。ここをクリアすれば、あなたのツールは単なる「記録係」から「予測エンジン」へと進化します。
—
1. なぜ「カレンダー」が重要なのか?
Projectには大きく分けて2つのカレンダーが存在します。
1. プロジェクト標準カレンダー: プロジェクト全体のデフォルト設定。
2. タスク固有カレンダー: 特定のタスクにだけ適用される例外(例:24時間稼働の設備、特定の休日がある作業)。
VBAで日付計算を行う際、単に「+5日」と加算してはいけません。Projectの世界では「土日や祝日は稼働日ではない」からです。これらを無視した計算は、現場の混乱を招くだけの「ゴミデータ」を生成します。
—
2. 稼働日計算のための「基礎知識」
Project VBAでは、`ActiveProject.BaseCalendars` プロパティを使ってカレンダーにアクセスします。
ここで最も重要なメソッドが `Calendar.Period` です。このメソッドは、指定した期間が「稼働日か、休日か」を判定するために使います。
コードの全体像:稼働日ベースの計算
まずは、タスクの開始日から指定した「稼働日数」後の日付を算出するコードを見てみましょう。
‘ 稼働日を考慮して終了日を算出するロジック
Sub CalcFinishDateByWorkingDays()
Dim proj As Project
Dim tsk As Task
Dim cal As Calendar
Dim workDays As Integer
Dim currentDate As Date
Dim count As Integer
Set proj = ActiveProject
Set tsk = proj.Tasks(1) ‘ 対象タスク
Set cal = proj.BaseCalendars(“標準”) ‘ プロジェクトの標準カレンダーを取得
workDays = 5 ‘ 5稼働日後に設定したい場合
currentDate = tsk.Start
count = 0
‘ 稼働日をカウントしていくループ
Do While count < workDays
currentDate = DateAdd("d", 1, currentDate)
' Calendar.Period でその日が稼働日か判定
If cal.Period(currentDate).Working = True Then
count = count + 1
End If
Loop
' 結果をデバッグウィンドウに出力
Debug.Print "開始日: " & tsk.Start
Debug.Print workDays & "稼働日後の終了予定日: " & currentDate
End Sub
---
3. 陥りやすい「罠」とその対策
罠1:タスク固有カレンダーの無視
多くのコードが「標準カレンダー」のみを参照して計算を完結させます。しかし、タスクに「夜間シフトカレンダー」が割り当てられている場合、この計算は破綻します。
- 解決策: `Task.Calendar` プロパティを確認し、もし設定されていれば `Task.Calendar` を、そうでなければ `Project.Calendar` を使うという「条件分岐」を必ず入れましょう。
罠2:リソースカレンダーの考慮漏れ
タスクにリソースが割り当てられている場合、実は「リソース個人のカレンダー」が最優先されることがあります。ここが中級者と熟練者の分かれ道です。
`tsk.Assignments` をループし、割り当てられたリソースの `Resource.Calendar` を取得する処理を組み込むと、精度は格段に上がります。
—
4. プロの設計思想:自動化のステップ
現場でそのまま使える「自動化ツール」を作るための設計図は以下の通りです。
1. 入力の正規化: タスクの開始日、稼働日数、カレンダー名を引数として受け取る関数を作る。
2. カレンダーの解決: `If Not tsk.Calendar Is Nothing Then …` でタスク固有カレンダーがあるか判定し、優先順位を決める。
3. 判定ルーチン: `Period` メソッドを活用し、休日(土日祝)をスキップするループ処理を実装する。
4. 書き戻し: 計算結果を `tsk.Finish` に格納する。
—
最後に:まずは手を動かそう
VBAは、書いたコードが即座にプロジェクトに反映される強力なツールです。最初はエラーが出るかもしれません。しかし、`Debug.Print` を駆使して、プログラムが「どの日を休日と判断し、どの日を稼働日と判断したか」を追跡してみてください。
この「カレンダーのロジック」を掌握すれば、あなたはもう「マクロの記録」に頼る初心者ではありません。プロジェクトの未来を計算できる、真のエンジニアです。
次回の記事では、「依存関係(先行タスク)の自動設定と、それに伴うクリティカルパスへの影響分析」について深く掘り下げていきます。お楽しみに!
