【実務・中級編】リソースの「稼働率」が閾値を超えた場合に警告を出す「リアルタイム・モニタリング」 – Project VBA解析バイブル

スポンサーリンク

【Project VBA極限知見】過負荷リソースをリアルタイム検知せよ!起動時アロケーション・モニタリングの全実装

開発プロジェクトの現場において、リソース管理の破綻はプロジェクト死活問題の第一位だ。特にMicrosoft Projectを用いた大規模スケジューリングでは、担当者のキャパシティ(最大ユニット数)を超えたアロケーション、いわゆる「過負荷(Overallocated)」がサイレントに放置されがちである。

「なぜタスクが遅延しているのか?」
「なぜメンバーが疲弊しきっているのか?」

その原因の多くは、平然とスケジュールに組み込まれた「150%稼働」や「200%稼働」の幽霊タスクにある。これを手動で「リソース配分の確認(Team Planner)」画面を開いてチェックするなど、一秒を争うプロジェクトマネージャーの仕事ではない。

今回は、「プロジェクトファイルを開いた瞬間(`Open`イベント)」に全リソースの稼働率をバックグラウンドで走査し、閾値を超えた過負荷リソースが存在する場合、即座に警告ダイアログでポップアップさせるリアルタイム・モニタリングシステムの設計と実装を伝授する。

退屈なリファレンスの引き写しではない。オブジェクトのライフサイクルとパフォーマンスの重みを知り尽くしたアーキテクトだけが書ける、現場で即座に機能するプロダクションコードを公開しよう。

—

1. 堅牢な設計思想:なぜ「起動時イベント」なのか?

実務でVBAツールを導入する際、最も恐れなければならないのは「ユーザーの操作性をスポイルすること」と「メモリリーク・予期せぬエラーによるファイルの破損」だ。

ボタンを押して手動実行させるツールは、結局忘れ去られる。だからこそ、ファイルオープン時のトリガーである `Workbook_Open` ならぬ、Project特有の `Project_Open` イベントをフックする。

アーキテクチャの要点

1. 非同期的な処理の模倣:
Projectが開く瞬間の重い処理は、ユーザーにフリーズの印象を与える。可能な限りオブジェクトの走査を最適化し、軽量なループ構造を採用する。
2. 安全なエラーハンドリング:
リソースが一人も登録されていないプロジェクトや、コストリソースのみが混在するカオスな環境でも、型ミスマッチやNull参照で落ちない堅牢性を持たせる。
3. 閾値の動的変更:
コード内にマジックナンバーを直書きせず、定数として定義。現場の運用ルール(例:100%超えで警告、120%超えでエラー停止など)に容易に追従できるようにする。

—

2. プロダクションコード:`ThisProject` モジュールの実装

以下のコードは、Project VBAのライフサイクルに完全に適合させた実装である。
プロジェクトファイル内の `Microsoft Project Objects` > `ThisProject` モジュールにそのまま貼り付けてほしい。

Option Explicit

‘ ==============================================================================
‘ módulo名: ThisProject (イベントハンドラ)
‘ 概要: プロジェクトオープン時にリソースの過負荷状態をスキャンし、警告を発報する
‘ ==============================================================================

‘ 稼働率の警告閾値(例: 100%を超えるアロケーションを検知対象とする)
Private Const OVER_ALLOCATION_THRESHOLD As Double = 1.0

Private Sub Project_Open(ByVal Sv As Project)
On Error GoTo ErrorHandler

‘ パフォーマンス最適化:画面描画や不要な計算を抑制(Projectでは効果的)
Application.ScreenUpdating = False

Dim res As Resource
Dim overAllocatedCount As Long
Dim warningMessage As String
Dim peakUnits As Double

overAllocatedCount = 0
warningMessage = “【警告】以下のリソースに過負荷(オーバーアロケーション)が検出されました。” & vbCrLf & _
“スケジュールを見直してください。” & vbCrLf & vbCrLf & _
String(50, “-“) & vbCrLf

‘ プロジェクト内の全リソースをイテレート
‘ ※ 注意: コストリソースは稼働率を持たないため除外するフィルタリングを入れる
For Each res In Sv.Resources
If Not res Is Nothing Then
‘ リソースがコストリソースではなく、かつ有効な名前を持つ場合
If res.Type <> pjResourceTypeCost And res.Name <> “” Then

‘ ピークunits(Peak Units)を取得
‘ Projectのオブジェクトモデルでは、ピーク稼働率は Variant型 または Double型 で取得可能
‘ 注意:最大ユニット数(Max Units)に対する割合として評価する
peakUnits = GetPeakAllocationRate(res, Sv)

‘ 閾値を超えているか判定
If peakUnits > OVER_ALLOCATION_THRESHOLD Then
overAllocatedCount = overAllocatedCount + 1
warningMessage = warningMessage & _
“・リソース名: ” & res.Name & _
” (ピーク稼働率: ” & Format(peakUnits 100, “0.0”) & “%)” & vbCrLf
End If
End If
End If
Next res

‘ 画面描画の復元
Application.ScreenUpdating = True

‘ 過負荷リソースが存在する場合のみ警告を表示
If overAllocatedCount > 0 Then
warningMessage = warningMessage & String(50, “-“) & vbCrLf & _
“合計 ” & overAllocatedCount & ” 件の過負荷リソースがあります。”

MsgBox warningMessage, vbExclamation + vbApplicationModal, “リソース・リアルタイムモニタリング”
End If

Exit Sub

ErrorHandler:
Application.ScreenUpdating = True
MsgBox “リソース・モニタリング処理中に予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “システムエラー”
End Sub

‘ ==============================================================================
‘ 補助関数: リソースのピーク稼働率を算出する
‘ ==============================================================================
Private Function GetPeakAllocationRate(ByRef res As Resource, ByRef Sv As Project) As Double
On Error GoTo FuncError

Dim ts As TimeScaleValues
Dim tsv As TimeScaleValue
Dim maxPeak As Double
Dim currentVal As Double

maxPeak = 0#

‘ リソースのタイムスケールデータ(稼働率)を取得
‘ プロジェクトの全期間にわたり、日単位(pjTimescaleDays)でピークユニットを走査する
‘ ※大規模プロジェクトでは週単位(pjTimescaleWeeks)に変更してパフォーマンスを稼ぐことも考慮せよ
Set ts = res.TimeScaleData(Sv.ProjectStart, Sv.ProjectFinish, _
pjTaskResourceActualUnits, pjTimescaleDays, 1)

For Each tsv In ts
If Not IsEmpty(tsv.Value) And IsNumeric(tsv.Value) Then
‘ 稼働率の値を取得(Projectの仕様により値のスケールに注意:通常は1.0 = 100%)
currentVal = CDbl(tsv.Value)

‘ 最大値の更新
If currentVal > maxPeak Then
maxPeak = currentVal
End If
End If
Next tsv

‘ 戻値の設定(ここでは簡略化のため取得できた最大値を返す。
‘ 実務では標準のMaxUnitsに対する割合へ正規化するロジックをここに挟むとさらに精度が上がる)
GetPeakAllocationRate = maxPeak
Exit Function

FuncError:
‘ タイムスケール取得失敗時は安全のため 0 を返す
GetPeakAllocationRate = 0#
End Function

—

3. 現場のプロが解説する「実装の急所」

上記のコードをただコピペするだけでは、真のエンジニアとは言えない。なぜこの実装が堅牢で、どこに罠があるのかを解説しよう。

① タイムスケールデータ(`TimeScaleData`)のコストと罠

MS Project VBAにおいて、リソースの負荷状況を正確に取得するには `TimeScaleData` メソッドが不可欠だ。しかし、このメソッドはプロジェクトの期間が長く、タスク数が多いファイルに対して呼び出すと、凄まじいメモリ消費と処理遅延(重み)を引き起こす。

  • 対策:

もしプロジェクトの期間が数年に及び、日単位(`pjTimescaleDays`)での走査がパフォーマンスを圧迫する場合は、第4引数を `pjTimescaleWeeks`(週単位)に変更するか、プロジェクト全体ではなく「直近3ヶ月」などのウィンドウに絞るアーキテクチャ上の工夫が必要となる。本番環境のデータ量に応じて調整せよ。

② コストリソースとマテリアルリソースの除外

リソースには「作業リソース(Work)」「材料リソース(Material)」「コストリソース(Cost)」の3種類が存在する。
このうち、コストリソースに稼働率(Units)の概念は存在しない。もし `Type` の判定を怠り、コストリソースに対して `TimeScaleData` を叩くと、Runtime Error(実行時エラー)が誘発されるか、ナンセンスな値が返ってくる。
コード内で `res.Type <> pjResourceTypeCost` と厳密にフィルタリングしているのはそのためだ。

③ モーダルダイアログによる強制力

`MsgBox` の引数に `vbApplicationModal` を指定している点に注目してほしい。これはプロジェクト全体の操作を一時停止させ、ユーザーに「過負荷の事実」を確実に認知させるための布石である。
「警告を出したのに、誰も気づかずにスケジュールを進行させていた」という現場の言い訳を、この一撃で完全に断絶する。

—

4. 拡張性:データベース(SQL Server / Azure)連携へのステップ

このリアルタイム・モニタリングをローカルの警告だけで終わらせるのはもったいない。
真に洗練された組織であれば、「誰が、どのプロジェクトで、どれだけ過負荷になっているか」のメトリクスを、ファイルが開かれた瞬間に中央のデータベースへ非同期でロギング(送信)させるべきだ。

‘ 【概念コード】データベースへの監査ログ送信イメージ
Private Sub SendOverAllocationLogToDB(ByVal resourceName As String, ByVal peakRate As Double)
Dim conn As Object
Set conn = CreateObject(“ADODB.Connection”)

‘ セキュアな接続文字列(環境に合わせて変更)
Dim connStr As String
connStr = “Provider=SQLOLEDB;Server=myServerAddress;Database=myDB;Uid=myUser;Pwd=myPassword;”

On Error Resume Next
conn.Open connStr
If conn.State = 1 Then
Dim sql As String
sql = “INSERT INTO ResourceAuditLog (ProjectName, ResourceName, PeakRate, CheckDate) VALUES (‘” & _
ActiveProject.Name & “‘, ‘” & resourceName & “‘, ” & peakRate & “, GETDATE())”
conn.Execute sql
conn.Close
End If
Set conn = Nothing
On Error GoTo 0
End Sub

このように、VBAを単なる「マクロ」としてではなく、「企業システムのエッジクライアント(IoT端末のような位置づけ)」として捉えることで、Projectのポテンシャルは限界突破する。

—

総括

リソースの過負荷放置は、プロジェクトマネジメントの怠慢であり、エンジニアのメンタル崩壊の引き金だ。
今回提供した `Project_Open` によるリアルタイム・モニタリングは、ファイルを開いたその瞬間に現実を突きつける、冷徹かつ慈悲深いセーフティネットとなる。

あなたの管理するプロジェクトから、「オーバーアロケーションの言い訳」を完全に駆逐せよ。実装の成功を祈る。

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