こんにちは!普段はExcelマクロをバリバリ書いているけれど、なぜか「Microsoft Project」のVBAを任されて途方に暮れている……そんなあなたへ。
大丈夫、安心してください。Excel VBAのオブジェクト操作の感覚が少しでもあれば、Project VBAの構造もすぐに理解できます。今回は、プロジェクト管理の現場で最も頭を悩ませる「コスト管理(特にリソースの単価変動)」をテーマに、VBAで高度なコストシミュレーションを自動化する方法を徹底解説します。
ここをクリアすれば、Project VBAの基本はバッチリですよ。さあ、一緒にプロの第一歩を踏み出しましょう!
—
1. なぜ「コストレート(CostRateTables)」の操作が必要なのか?
プロジェクトの予算管理において、「人件費」は最大の変動要素です。
例えば、同じエンジニアでも、通常作業と「残業や休日出勤」、あるいは「プロジェクトの後半で単価が上がる」といったケースでは、適用される単価(コストレート)が異なります。
Microsoft Projectには、標準機能として「コストレートテーブル(A〜E)」という強力な単価切り替えの仕組みが備わっています。しかし、これを手動で全リソース・全タスクに対して緻密にシミュレーションしようとすると、途中で心が折れます。
そこで登場するのがProject VBAです。VBAを使えば、リソースの単価テーブルを自在に操り、プロジェクト全体の正確な予測コストを瞬時に弾き出す自動化ツールが作れます。
—
2. Projectオブジェクトモデルの基本と「Resource」の罠
Excel VBAとProject VBAの最大の違いは、「データのつながり方の複雑さ」です。
- Excel: `Range` や `Cell` はシートの中に平面的に存在します。
- Project: `Project` の中に `Task` があり、`Task` には `Assignment`(割り当て)を通じて `Resource`(リソース)が紐付くという、立体的な構造(ネットワーク構造)をしています。
ここで初心者が一番最初にハマる罠が、「コストはTaskオブジェクトではなく、Resource(あるいはAssignment)に宿る」という点です。
コスト分析を自動化するには、以下のルートをコードで辿る必要があります。
1. プロジェクト内の全リソース(`Resources`)にアクセスする
2. 各リソースが持つコストレートテーブル(`CostRateTables`)を読み書きする
3. タスクへの割り当て状況から実際のコストを算出して集計する
—
3. 実践!コスト集計&シミュレーション自動化マクロ
それでは、現場でそのままコピペして使える実用的なコードをお見せします。
このマクロは、各リソースのコストレートA(基本単価)を取得し、割り当てられた作業時間(Work)を掛け合わせて、プロジェクト全体の予測人件費をイミディエイトウインドウに出力するツールです。
Sub SimulateProjectCost()
‘ —————————————————————–
‘ 目的: リソースのコストレートを考慮し、プロジェクトの人件費をシミュレーションする
‘ 対象読者: マクロの記録から脱却し、オブジェクト操作をマスターしたい方へ
‘ —————————————————————–
Dim res As Resource
Dim asn As Assignment
Dim totalProjectCost As Double
Dim standardRate As Double
totalProjectCost = 0
‘ 画面描画を停止してマクロの実行速度を爆発的に上げる(お約束のテクニック)
ScreenUpdating True ‘ 動作確認のためあえてTrueにしていますが、本番ではFalse推奨
Debug.Print “=== リソース別コストシミュレーション開始 ===”
‘ 1. プロジェクトに登録されているすべてのリソースをループ処理
For Each res In ActiveProject.Resources
‘ リソースが登録されていない空行などのエラーを防ぐためのガード
If Not res Is Nothing Then
If res.Type = pjResourceTypeWork (作業 recursos のみ対象) Then
‘ 2. コストレートテーブルAの「標準単価 (StandardRate)」を取得
‘ ※Projectでは単価は「時給」や「日給」などの単位で格納されています
standardRate = res.CostRateTables(1).PayRates(1).StandardRate
Debug.Print “リソース名: ” & res.Name & ” (基本単価: ” & standardRate & ” /h)”
‘ 3. このリソースがどのタスクにどれだけ割り当てられているか(Assignment)を走査
For Each asn In res.Assignments
If Not asn Is Nothing Then
‘ 割り当てられた時間(Workは分単位で保持されるため、時間に変換する場合は注意)
‘ ここでは簡易的にCostプロパティ(既にProjectが計算済みのコスト)を集計
totalProjectCost = totalProjectCost & asn.Cost
End If
Next asn
End If
End If
Next res
‘ 4. 結果の出力
Debug.Print “—————————————-”
Debug.Print “【シミュレーション結果】予測総人件費: ¥ ” & Format(totalProjectCost, “#,
0″)
Debug.Print “=== 処理終了 ===”
MsgBox “コストシミュレーションが完了しました。イミディエイトウインドウを確認してください。”, vbInformation, “完了”
End Sub
—
4. コードの解説と「初心者が陥りやすいエラー」の回避策
上記のコードには、Project VBA特有の重要なポイントが詰まっています。
① `Nothing` 判定を怠るな
Projectのコレクション(`Resources`や指し示す`Assignments`)は、途中に空行や削除されたデータの残骸が含まれていることがよくあります。
`If Not res Is Nothing Then` という生存確認をサボると、容赦なく 「実行時エラー ’91’: オブジェクト変数が設定されていません」 が発生します。現場のコードでは必須の作法です。
② 作業リソース(Work)と材料リソース(Material)の区別
コストが発生するのは主に「人(作業リソース)」ですが、プロジェクトには「資材(材料リソース)」も混ざっています。資材には時間あたりの単価概念がないため、`res.Type = pjResourceTypeWork` でフィルタリングしないと、計算が狂うかエラーになります。
③ コストレートテーブルの階層構造
`res.CostRateTables(1).PayRates(1).StandardRate`
この記述は、「コストレートテーブルA(1番目)の、有効期間1番目の、標準単価」を指しています。
Projectでは、期間ごとに単価を変える(例:来月から単価が10%UPするなど)ために複数の `PayRates` を持つことができます。ここをマスターすれば、将来の単価改定を織り込んだ高度なシミュレーションが可能になります。
—
5. おわりに
いかがでしたでしょうか?
「マクロの記録」ボタンを押すだけでは決して覗けない、オブジェクトの階層を自分の手でコード化していく感覚は、プログラミングの醍醐味そのものです。
Project VBAは、Excel VBAに比べてネット上の情報が少ないのが難点ですが、オブジェクトの構造(モデル)さえつかんでしまえば、あなたのプロジェクト管理業務を劇的に楽にしてくれる最強の武器になります。
「ここをもっとこうしたい」「こういう条件で単価を切り替えたい」といった応用についても、また別の機会にお話しできればと思います。
あなたのVBAライフが、よりスリリングで快適なものになりますように。それではまた!
