【実務・中級編】Assignmentオブジェクトの「WorkContour」をVBAで制御し工数配分を最適化する – Project VBA解析バイブル

スポンサーリンク

Project VBAの深淵:Assignment.WorkContourを掌握し、工数配分の呪縛を解く

プロジェクトマネジメントにおいて、MS Projectの「標準機能」に依存しすぎることは、往々にしてスケジュール崩壊の引き金となります。特に「工数配分(Work Contour)」の概念を無視した自動化は、ガントチャート上の見栄えを整えるだけで、現場のリアルな稼働感と乖離した「ハリボテの計画」を生み出すからです。

今日は、Project VBAの真髄である`Assignment.WorkContour`プロパティを制御し、実務で使える「工数配分の最適化」を実装するアーキテクチャを伝授します。

—

1. なぜ「WorkContour」の制御が必要なのか?

MS Projectのデフォルトは「平準(Flat)」です。しかし、現実のプロジェクトでは以下のような配分が求められます。

  • 前倒し(FrontLoaded): 設計・着手段階でパワーを集中させる。
  • 山型(Bell): 熟練度が必要なフェーズでピークを作る。
  • 遅延(BackLoaded): 承認待ちや他依存がある場合に後半へシフトする。

これらを手動で設定するのは非効率の極みであり、数百行のタスクを抱えるプロジェクトではVBAによる一括制御が必須となります。

2. 実装の鉄則:Assignmentオブジェクトのライフサイクル

VBAでAssignmentを操作する際、最も多いバグは「存在しないアサインメントへのアクセス」と「再計算によるオーバーライド」です。

  • 鉄則1: `Assignment`オブジェクトを取得する際は、必ず`Task.Assignments`コレクションの存在を確認せよ。
  • 鉄則2: `Application.ScreenUpdating = False`を忘れずに。Projectの再描画は、Excel VBAの比ではないほどパフォーマンスを削ります。
  • 鉄則3: 変更後は必ず `Task.Calculate` を呼び出し、変更をエンジンに確定させること。

—

3. 実践:工数配分を一括制御するプロダクションコード

このコードは、指定したタスクIDに対し、WorkContourを動的に適用する堅牢な関数です。

‘ ==============================================================================
‘ Project: Assignment Contour Optimizer
‘ 概要: 指定タスクのアサイン情報を取得し、WorkContourを一括変更する
‘ ==============================================================================
Sub ApplyWorkContourToProject(targetTaskID As Long, contourType As PjContour)
Dim proj As Project
Dim tsk As Task
Dim asn As Assignment

Set proj = ActiveProject
Set tsk = proj.Tasks(targetTaskID)

‘ 画面更新を停止し、再計算負荷を抑える
Application.ScreenUpdating = False

On Error GoTo ErrorHandler

‘ アサインメントが存在するか確認
If tsk.Assignments.Count = 0 Then
Debug.Print “Warning: No assignments found for Task ID ” & targetTaskID
GoTo Cleanup
End If

‘ 該当タスクの全てのアサインメントに配分を適用
For Each asn In tsk.Assignments
‘ WorkContourプロパティを直接操作
‘ PjContour列挙型: pjFlat, pjFrontLoaded, pjBackLoaded, pjBell 等
asn.WorkContour = contourType
Next asn

‘ プロジェクトエンジンに計算を強制する
tsk.Calculate

Cleanup:
Application.ScreenUpdating = True
Exit Sub

ErrorHandler:
MsgBox “エラー発生: ” & Err.Description, vbCritical
Resume Cleanup
End Sub

‘ 実行例: ID 5のタスクを「前倒し(FrontLoaded)」にする
Sub RunOptimizer()
Call ApplyWorkContourToProject(5, pjFrontLoaded)
End Sub

—

4. 運用上の注意点とアーキテクチャの極意

このツールを業務に組み込む際、以下の点に留意してください。

外部データとの連携(Excel/SQL)

もし配分パターンをExcelで管理している場合、`VLOOKUP`的な処理をVBA内で行うのではなく、一度`Dictionary`オブジェクトにキャッシュしてからループを回してください。Projectのオブジェクトモデルに対して、ループ内で都度`Workbook.Open`や`Query`を投げるのはアーキテクチャの敗北です。

稼働率調整(PeakUnits)との併用

`WorkContour`はあくまで「配分の形」を決めるものです。もし「稼働率(PeakUnits)」も同時に制御したい場合は、`asn.Units = 0.5`(50%)のように値をセットした後に`WorkContour`を適用してください。順序を逆にすると、Projectのエンジンが推論した単位数で上書きされるリスクがあります。

保守性の確保

この種のコードを属人化させないために、設定値(どのタスクにどのContourを当てるか)は、VBAのコード内ではなく、プロジェクトファイル内の「テキストカスタムフィールド(Text1等)」に保持させ、VBAはそのフラグを読み取って処理する設計にしましょう。これにより、開発者でなくともPMが配分パターンを変更できるようになります。

—

最後に

VBAは「書けること」が目的ではありません。「プロジェクトという巨大な生命体を、意図通りにコントロールすること」がエンジニアの使命です。

WorkContourを支配することは、工数という「時間」を支配することと同義です。このコードをベースに、あなたの現場に最適な自動化エンジンを組み上げてください。もしシステムが複雑化し、計算のオーバーヘッドが無視できなくなったら、次は`Application.Calculation = pjManual`を検討するタイミングです。

エンジニアの諸君、コードでプロジェクトの未来を設計したまえ。

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