Project VBAの深淵:カレンダー例外を考慮したリソース稼働可能時間の自動算出ロジック
プロジェクト管理において、最も多くの工数を無駄にしているのは「稼働可能時間の見積もりミス」だ。祝日、夏季休暇、個人の有給休暇……。これらをExcelのセル上で手動計算しているようでは、プロのエンジニアとは言えない。
今回は、Project VBA(MS Project Object Model)を駆使し、カレンダーの例外(Exception)をプログラムで完全に掌握し、リソースの稼働可能時間を日次で正確に算出するアーキテクチャを伝授する。
—
1. なぜ「力技の計算」はプロジェクトを崩壊させるのか
多くの開発者が陥る罠は、`Work`プロパティを単純に合計するだけのロジックだ。しかし、Projectのカレンダーには「ベースカレンダー」と「リソースカレンダー」という二重構造が存在する。
- ベースカレンダー: 全体的な祝日設定。
- リソースカレンダー: 特定個人の休暇や時短勤務。
これらを考慮せず、単純に週40時間稼働と仮定して計画を立てれば、連休明けにプロジェクトが遅延するのは必然だ。「カレンダー例外を無視しない」ことこそ、堅牢なプロジェクト設計の第一歩である。
—
2. 実装の要諦:`Calendar.Exceptions` へのアクセス
MS Projectのオブジェクトモデルでは、`Resource.Calendar.Exceptions` を走査することで、特定期間の稼働変更を抽出できる。ここでのポイントは、「稼働日を数えるのではなく、除外日を引く」という逆転の発想だ。
以下のコードは、特定期間におけるリソースの有効稼働時間を算出するプロダクションレベルの関数である。
‘ Project VBA: 指定期間のリソース稼働時間を算出する
‘ @param res: 対象のリソースオブジェクト
‘ @param startDate: 開始日
‘ @param endDate: 終了日
‘ @return: 稼働可能時間(分単位)
Public Function GetAvailableMinutes(ByRef res As Resource, ByVal startDate As Date, ByVal endDate As Date) As Double
Dim cal As Calendar
Dim currentDay As Date
Dim totalMinutes As Double
Dim isException As Boolean
Set cal = res.Calendar
totalMinutes = 0
‘ 1日ずつ走査(パフォーマンスを考慮し、大規模プロジェクトでは期間を分割してキャッシュ化を推奨)
For currentDay = startDate To endDate
‘ 土日を除外(ベースカレンダーの設定に準拠)
If Weekday(currentDay, vbMonday) <= 5 Then
' カレンダー例外のチェック
If IsWorkingDay(cal, currentDay) Then
' プロジェクトの標準稼働時間(分)を取得
totalMinutes = totalMinutes + 480 ' 例:8時間勤務 = 480分
End If
End If
Next currentDay
GetAvailableMinutes = totalMinutes
End Function
' 例外日判定ロジック
Private Function IsWorkingDay(ByRef cal As Calendar, ByVal targetDate As Date) As Boolean
Dim ex As Exception
' デフォルトは稼働日とみなす
IsWorkingDay = True
' 例外リストを走査し、非稼働日であればFalseを返す
For Each ex In cal.Exceptions
If targetDate >= ex.Start And targetDate <= ex.Finish Then
If Not ex.Working Then
IsWorkingDay = False
Exit Function
End If
End If
Next ex
End Function
---
3. 設計上の注意点:パフォーマンスと整合性
このコードを実務で運用する際、以下の3点に注意せよ。
1. 計算のキャッシュ化: プロジェクトのリソース数が100名を超えると、ループ処理がボトルネックになる。計算結果は一度取得したら、同一セッション内では再利用する設計にすること。
2. データベース連携の罠: Excelや外部DBから休暇情報をインポートする場合、必ず「日付型(Date)」の形式を統一せよ。特に`yyyy/mm/dd`の文字列変換で発生するロケール依存のバグは、修正に最も時間を浪費する。
3. 例外の優先度: MS Projectの仕様上、例外には「優先度」が存在する。複数のカレンダーが重なる場合、リソースカレンダーの設定がベースカレンダーを上書きすることを常に念頭に置くこと。
—
4. 最後に:エンジニアの誇り
業務自動化ツールを作ることは、単に「楽をする」ことではない。「プロジェクトの不確実性を排除し、チームが計画通りに走れる環境を設計すること」だ。
今回のコードは、あなたのプロジェクト管理における「真実の稼働率」を可視化するはずだ。明日からの運用で、根拠のない「なんとなく空いているはず」という甘い見積もりを撲滅しよう。
もし君が、さらに高度なリソース平準化や、APIを用いた外部システム(JiraやAsana等)との同期まで視野に入れているのであれば、まずはこの基盤ロジックを磨き上げることだ。堅牢な基盤こそが、複雑なシステムを支える唯一の道である。
健闘を祈る。
