【入門編】リソースの「コスト」をプロジェクト進捗率に応じて按分する自動計算ロジック – Project VBA解析バイブル

スポンサーリンク

こんにちは!Excel VBAのマクロ記録から一歩踏み出し、「もっと本格的にプロジェクト管理を自動化したい!」と熱い想いを持っているあなたへ。

今回は、Microsoft Project(Project VBA)の現場で最も頭を悩ませるポイントの一つである「リソースのコスト管理」をテーマに、ワンランク上の自動化テクニックを伝授します。

「進捗率(%完了)に応じて、実際に発生したコスト(実コスト)を正確に計算し、予算管理表に連動させたい」――。
実務でよくあるこのリクエスト、実はProject VBAのオブジェクト構造の本質を理解していないと、泥沼にはまりがちな難所です。

でも、安心してください。ここをクリアすれば、あなたのProject VBAスキルは間違いなく中級者の域に達します。優しく、そして深く、その極意を解説していきましょう!

—

1. なぜ「進捗率に応じたコスト按分」でハマるのか?

Excelとは異なり、Microsoft Projectには「タスク」「リソース」「割り当て(Assignment)」という3つの強力なオブジェクトが存在します。

初心者が陥りがちな罠が、「タスクのコストを適当に取得して計算しようとする」ことです。
Projectにおいて、コストはリソースがタスクに「割り当てられた瞬間(Assignment)」に発生します。つまり、コストを正確にコントロールしたければ、`Assignment` オブジェクトを自由自在に操る必要があるのです。

今回は、「タスクの進捗率(%完了)に連動して、現時点で発生すべき実コスト(Actual Cost)を自動計算し、リソースの割り当てデータに書き戻す」というプロフェッショナルなロジックを構築します。

—

2. 押さえておくべきProject VBAの重要概念

コードを書く前に、今回の主役を確認しておきましょう。

1. `ActiveProject.Assignments`:
プロジェクト全体にある「どのリソースが、どのタスクに割り当てられているか」という関係性の集合体です。
2. `Assignment.Units`:
リソースの割り当て単位(フルタイムなら1.0、50%なら0.5)。
3. `Assignment.Cost`:
その割り当てにおける総コスト(総予算コスト)。
4. `Assignment.ActualCost`:
実際に発生したコスト。ここをVBAから制御します。
5. `Task.PercentComplete`:
タスクの進捗率(%)。

これらを組み合わせて、「総コスト × (進捗率 / 100)」という按分ロジックを組んでいきます。

—

3. 実装コード:進捗率連動コスト自動計算マクロ

それでは、開発環境(VBAエディタ:[Alt] + [F11])を開き、標準モジュールに以下のコードを貼り付けてみてください。実務ですぐに使えるよう、エラーハンドリングと丁寧なコメントを入れています。

Sub CalculateEarnedCostByProgress()
‘ =================================================================
‘ テーマ: 進捗率を考慮した実コストの自動按分と割り当てデータへの反映
‘ 著者: シニアVBAアーキテクト
‘ =================================================================

Dim tsk As Task
Dim asn As Assignment
Dim targetCost As Currency
Dim progressRate As Double

‘ 画面描画を停止してマクロの実行速度を爆発的に上げる(お約束のプロ手法)
Application.ScreenUpdating = False

On Error GoTo ErrorHandler

‘ プロジェクト内のすべてのタスクをループ
For Each tsk In ActiveProject.Tasks
‘ タスクが存在し、かつサマリータスク(親タスク)ではない場合を対象とする
If Not tsk Is Nothing Then
If tsk.Summary = False And tsk.ExternalTask = False Then

‘ タスクの進捗率を取得(0~100の値を 0.0~1.0 に変換)
progressRate = tsk.PercentComplete / 100#

‘ そのタスクに紐づく「リソース割り当て(Assignment)」をループ
‘ ※1つのタスクに複数のリソースがアサインされているケースに対応するため
For Each asn In tsk.Assignments
If Not asn Is Nothing Then

‘ 【コアロジック】
‘ 割り当てられた総コスト(Cost)に対し、進捗率を掛け合わせて実コストを算出
targetCost = asn.Cost progressRate

‘ 算出した実コストを Assignment の ActualCost(実コスト)に書き込む
‘ ※Projectの仕様上、ActualCostを変更する場合は事前にWorkComplete等との整合性に注意
asn.ActualCost = targetCost

End If
Next asn

End If
End If
Next tsk

Application.ScreenUpdating = True
MsgBox “進捗率に応じたコストの按分計算が正常に完了しました!”, vbInformation, “処理成功”
Exit Sub

ErrorHandler:
Application.ScreenUpdating = True
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
End Sub

—

4. コードの深掘りポイント(ここが分かれば怖くない!)

① なぜ `For Each tsk In ActiveProject.Tasks` の中でさらに `For Each asn In tsk.Assignments` を回すのか?

Projectでは、1つのタスクに「Aさん(設計)」「Bさん(コーディング)」といった複数のリソースが紐づくことがあります。
タスク単体のコストを見るのではなく、「誰が・どのタスクに・どれだけのコストをかけているか」という末端(Assignment)の粒度で処理しなければ、正確なコスト按分はできません。ここがマクロ記録では絶対に辿り着けない、アーキテクトの視点です。

② サマリータスク(親タスク)の除外

`If tsk.Summary = False` の判定が非常に重要です。
親タスク(プロジェクトの大きな節など)のコストや進捗率は、子タスク(実際の作業)の集計値として自動計算されます。ここに直接VBAで値を書き込もうとすると、Projectのデータ構造が矛盾を起こし、エラーや予期せぬ数値のズレを生む原因になります。実作業を行う末端タスク(Leaf Task)のみを対象にするのが鉄則です。

—

5. 現場でありがちな「陥りやすいエラー」と対策

  • エラー:実行時エラー ‘1100’(読み取り専用のプロパティです 等)
  • 原因: Microsoft Projectの設定で、コストが「リソースの稼働実績」から自動計算されるモードになっている場合、VBAから直接 `ActualCost` を書き込めないことがあります。
  • 対策: 必要に応じてタスクの「タスクの種類(Task Type)」を固定にするか、コストの計算方法をマニュアル入力モードに切り替えてから実行してください。
  • 数値がなぜか「0円」になってしまう
  • 原因: タスクにコスト(Cost)やリソース単価が設定されていない状態でコードを走らせている可能性があります。
  • 対策: 事前にリソースシートで標準単価(Standard Rate)が正しく設定されているか確認しましょう。

—

まとめ:ここをクリアすれば、Project VBAの基本はバッチリですよ!

お疲れ様でした!今回は少し歯応えのある「Assignmentオブジェクトを通じたコストの自動按分ロジック」を解説しました。

  • タスクとリソースを繋ぐ `Assignment` の概念
  • サマリータスクを避けて末端タスクを狙い撃ちする技術
  • 進捗率(`PercentComplete`)を掛け合わせた動的なコスト計算

これらを理解できたあなたは、もう単なる「VBAの初心者」ではありません。現場のプロジェクトマネージャーから頼りにされる、立派な自動化エンジニアです。

ぜひ実際のプロジェクトデータで試して、スマートなコスト管理を実現してくださいね。あなたのVBAライフが、さらに飛躍することを応援しています!

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