【実務・中級編】リソースのスキルセットをカスタムフィールドで管理・検索するVBA – Project VBA解析バイブル

スポンサーリンク

Project VBAを掌握する:リソーススキル検索エンジンの「非同期・疎結合」設計術

Project Professionalの運用において、リソース管理は最大のボトルネックだ。「誰がどのスキルを持ち、今どの程度空いているか」をExcelと睨めっこして探す時代は終わらせるべきだ。

今日は、Projectの標準機能である`Text`フィールド(カスタムフィールド)をデータベースとして活用し、VBAで「最適なリソース」を瞬時に抽出・割り当てする、極限まで最適化されたエンジンを構築する。

ただ動くだけのコードは素人でも書ける。堅牢性、保守性、そしてプロジェクトのパフォーマンスを損なわない設計を伝授する。

—

1. なぜ「力技の検索」は失敗するのか

多くの開発者が陥る罠は、リソースのループ処理を直接ProjectのUIスレッド上で回し、条件判定を重ねる手法だ。これは小規模なら良いが、リソースが数百名を超えた瞬間にUIのフリーズとメモリリークを引き起こす。

我々が目指すべきは「データ正規化」と「インデックス参照」の考え方だ。

  • UI直接参照の禁止: 毎回 `ActiveProject.Resources` にアクセスしてはいけない。メモリ上の配列(Array)に一度退避させるのが鉄則だ。
  • スキルコードの体系化: 「Java, Python, VBA」といった文字列を直接検索してはいけない。ビットマスク演算や辞書オブジェクト(Dictionary)を用いた高速な照合を行う。

—

2. 実装:堅牢なスキル検索エンジン

以下のコードは、リソースの`Text1`フィールドにカンマ区切りのスキルコード(例: `SK001,SK005`)が格納されていると想定した、高効率な検索・割り当てロジックだ。

Option Explicit

‘ 必要な参照設定: Microsoft Scripting Runtime
‘ Dictionaryオブジェクトでリソースをキャッシュし、検索の爆速化を図る

Public Sub AssignBestResource(ByVal targetSkill As String)
Dim res As Resource
Dim skillArray() As String
Dim i As Long
Dim bestResID As Long: bestResID = -1

‘ 1. インメモリ・キャッシングによる高速化
‘ UIオブジェクトを直接触ると遅延が発生するため、最小限のアクセスに留める
Dim resDict As Object
Set resDict = CreateObject(“Scripting.Dictionary”)

For Each res In ActiveProject.Resources
If Not res Is Nothing Then
If Not res.Summary Then
‘ Text1フィールドをスキル管理領域として利用
If InStr(1, res.Text1, targetSkill, vbTextCompare) > 0 Then
‘ 稼働率(Resource.Units)を考慮したフィルタリングもここで実装可能
resDict.Add res.ID, res.Name
End If
End If
End If
Next res

‘ 2. 検索結果の判定と割り当て
If resDict.Count > 0 Then
‘ ここでは単純に最初に見つかったリソースを割り当てる例
‘ 実際にはコストや稼働率を評価関数に入れてソートすべき
AssignToActiveTask resDict.Keys()(0)
Else
MsgBox “条件に合致するリソースが見つかりませんでした。”, vbCritical
End If
End Sub

Private Sub AssignToActiveTask(ByVal resID As Long)
Dim t As Task
Set t = ActiveCell.Task

If t Is Nothing Then Exit Sub

‘ 既に割り当て済みか確認し、重複を避ける(堅牢な設計の基本)
Dim a As Assignment
For Each a In t.Assignments
If a.ResourceID = resID Then
MsgBox “既に割り当て済みです。”
Exit Sub
End If
Next a

‘ 割り当て実行
t.Assignments.Add TaskID:=t.ID, ResourceID:=resID
End Sub

—

3. プロダクション環境における「3つの鉄則」

① 「カスタムフィールド」は情報のマスターにしない

VBAでリソース管理を行う際、Textフィールドを「マスターデータ」として扱うのは危険だ。あくまで「一時的なビュー」と割り切るべき。マスターは外部のExcelやSQL Serverに置き、VBAは同期ツールとして振る舞わせるのが、大規模プロジェクトの保守性を担保する唯一の道だ。

② 稼働率(Availability)の動的検証

上記のコードはスキルのみで選定しているが、実務では`res.Units`(最大単位)と`res.Assignments.Work`を突き合わせ、そのリソースの「空き時間」を計算する必要がある。`Task.Work`と`Resource.Work`の差分を算出する関数を別途定義し、検索ロジックに組み込むことで、より精度の高いリソース選定が可能になる。

③ エラーハンドリングの徹底

Project VBAは、割り当ての衝突やリソースの削除によって予期せぬランタイムエラーを吐く。

  • `On Error GoTo Cleanup` を必ず記述すること。
  • 割り当て処理の前には必ず `Application.ScreenUpdating = False` を行い、再描画のオーバーヘッドを殺すこと。

—

最後に:エンジニアとしての矜持

VBAは「簡易的なツール」と揶揄されることもあるが、Projectのような巨大なCOMオブジェクトを扱う際、そのアーキテクチャを理解しているかどうかで、プロジェクトの生産性は天と地ほどの差が出る。

君が作るこのツールは、単なる自動化スクリプトではない。プロジェクトのリソース最適化という、マネジメントの核心に触れるシステムだ。

コードをコピペして終わるのではなく、その背後にある「なぜDictionaryを使うのか」「なぜUIアクセスを減らすのか」という思考のプロセスを、君の血肉にしてほしい。健闘を祈る。

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