【実務・中級編】リソースの「単価履歴」を別ファイルで管理し、プロジェクトのコスト計算を自動化する – Project VBA解析バイブル

スポンサーリンク

プロジェクト管理の「聖杯」を求めて:Project VBAによるリソース単価の動的再計算術

多くの現場で、Project VBA(Microsoft Project)を用いたコスト管理が「張りぼて」になっているのを目にする。特に、リソースの単価(Standard Rate)をハードコーディングしたり、ファイルに直接書き込んで運用したりする手法だ。

言っておくが、それは「コスト管理」ではなく「コストの記録」に過ぎない。

プロジェクトの単価は変わる。メンバーの昇給、派遣契約の更新、あるいはインフレ対応。単価の変更履歴を保持せず、現在の値だけを更新して過去のコストを消し去ることは、プロジェクトの財務データに対する「冒涜」だ。

今回は、外部Excelファイルで単価履歴を厳密に管理し、Project VBAからそれを参照してコストを再計算する、堅牢なアーキテクチャを伝授する。

—

なぜ「直接編集」が地獄への入り口なのか

多くの開発者が陥る過ちは、Projectの`Resource.StandardRate`を直接操作することだ。これには以下の欠陥がある。

1. 監査証跡の欠如: 誰がいつ単価を変えたのか、過去の単価はいくらだったのかが不明になる。
2. 計算の非再現性: 過去のレポートを出そうとしたとき、現在の単価に基づいた数値しか出せない。
3. データ不整合: プロジェクトファイルとExcelで「正」が二つ存在し、同期が取れなくなる。

我々が目指すべきは「外部マスタによる一元管理」と「再計算ロジックの疎結合化」である。

—

実装設計:単価履歴マスタの構造

外部Excelには、以下の3列を持たせるだけで十分だ。

  • `ResourceName`(リソース名)
  • `EffectiveDate`(適用開始日)
  • `Rate`(単価)

これを「単価履歴管理表」として運用する。計算時には「プロジェクトのタスク開始日」と「履歴テーブル」を突き合わせ、Lookupを行うのが鉄則だ。

—

プロダクションコード:単価反映エンジン

以下に、ADO(ActiveX Data Objects)を用いて外部Excelを読み込み、Projectのコストを再計算する堅牢な実装を示す。

‘ 必要な参照設定: Microsoft ActiveX Data Objects x.x Library
Option Explicit

Public Sub SyncResourceCosts()
Dim conn As Object
Dim rs As Object
Dim strConn As String
Dim res As Resource
Dim targetRate As Double

‘ 外部Excelのパス(運用に合わせて変更)
Const EXCEL_PATH As String = “C:\ProjectData\RateHistory.xlsx”

‘ ADOでExcelをデータベースとして接続(高速かつメモリ消費が少ない)
strConn = “Provider=Microsoft.ACE.OLEDB.12.0;Data Source=” & EXCEL_PATH & _
“;Extended Properties=””Excel 12.0 Xml;HDR=YES;”””

Set conn = CreateObject(“ADODB.Connection”)
conn.Open strConn

‘ 現在のリソースをループ
For Each res In ActiveProject.Resources
If Not res Is Nothing Then
‘ SQLで最新の有効単価を検索(現在の日付以前で最大のEffectiveDateを持つものを取得)
Set rs = conn.Execute(“SELECT TOP 1 Rate FROM [Sheet1$] ” & _
“WHERE ResourceName = ‘” & res.Name & “‘ ” & _
“AND EffectiveDate <= Date() ORDER BY EffectiveDate DESC") If Not rs.EOF Then targetRate = rs.Fields(0).Value ' 単価を適用 ' 注意: リソースのコスト単価変更は、既存のアサインメント計算に影響を与える res.StandardRate = targetRate Debug.Print "Updated: " & res.Name & " to " & targetRate End If End If Next res ' 後処理 rs.Close conn.Close MsgBox "コスト計算の同期が完了しました。", vbInformation End Sub ---

堅牢な運用のための3つの提言

1. エラーハンドリングは「沈黙」を許すな

コード中で`On Error Resume Next`を乱用するエンジニアがいるが、それは論外だ。上記コードはシンプルに見えるが、実環境では「リソース名の一致」や「ファイルロック」で必ず失敗する。`On Error GoTo`で例外をキャッチし、ログファイルに詳細を出力する仕組みを必ず実装すること。

2. ファイルアクセスの排他制御

ProjectとExcelを同時に開く際、Excel側が読み取り専用で開かれているとADO接続が失敗することがある。運用上は「読み取り専用」で開くか、一時ファイルをコピーして処理する設計が賢明だ。

3. 「コストの再計算」の重みを理解せよ

`StandardRate`を変更すると、Projectは全タスクの工数に対して再計算を走らせる。大規模プロジェクト(数千行レベル)では、この処理が数秒~数十秒かかる。GUIの更新を止めるために `Application.ScreenUpdating = False` を活用するのを忘れてはならない。

結論

自動化とは、単にコードを書くことではない。「データが生まれてから消えるまでのライフサイクル」を設計することだ。

リソース単価を外部マスタ化し、それをプログラムで注入する。このアーキテクチャこそが、属人化を排除し、プロジェクトの財務的透明性を担保する唯一の道である。コードをコピーして終わりにするな。その背後にある「なぜそう設計したのか」という思想まで、現場に根付かせてほしい。

それができる人間だけが、Project VBAを「掌握」していると言えるのだ。

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