こんにちは!プロジェクト管理の現場で、日々スケジュールやリソースの調整に奔走していませんか?
「リソースがいつからいつまで稼働しているのか、タスクのスケジュールから自動で算出してパッと一覧で見たい」
「エクセルでがんばってガントチャートやカレンダーを作っているけれど、タスクが変わるたびに手作業で修正するのがもう限界……」
そんな悩みを抱えているあなたへ。
今回は、Microsoft Projectの裏側を自在に操る「Project VBA(Visual Basic for Applications)」を使って、リソースのプロジェクト参加期間を自動算出し、カレンダー形式で可視化する管理ツールの作り方を解説します。
マクロの記録から一歩抜け出して、現場で本当に使える「生きたコード」を一緒に書いていきましょう。ここをクリアすれば、Project VBAの基本はバッチリですよ!
—
1. なぜExcelではなく「Project VBA」なのか?
プロジェクト管理において、Excelは万能ですが「リソースの重複アサイン」や「タスクの遅延に伴う期間の再計算」に関しては、どうしても人間の手作業(あるいは複雑すぎる関数)に頼りがちになります。
一方、Microsoft Projectには、タスクとリソースを結びつける強力なデータベース構造が最初から備わっています。
Project VBAを使うと、このデータベースから「誰が、いつからいつまで、どのタスクにアサインされているか」をごっそり抽出し、一瞬で集計・加工することが可能です。
今回目指すのは、「タスクの全体スケジュールからリソースの必要期間を逆算し、稼働状況をカレンダーのように整理して出力する」という、実務直結の自動化ツールです。
—
2. ツール設計の全体像
今回作成するVBAマクロの動きは以下の通りです。
1. プロジェクト内の全リソースをスキャンする。
2. 各リソースがアサインされているタスクを巡回し、「最も早い開始日」と「最も遅い終了日」を見つけ出す(=プロジェクト参加期間の自動算出)。
3. その期間をベースに、リソースがどのように稼働しているかをイミディエイトウインドウや別シート(今回はログ出力として実装)にカレンダー形式でマッピングする。
まずは、Project特有の「オブジェクトの階層構造」をサクッと理解しておきましょう。
Application (Project本体)
└── ActiveProject (現在開いているプロジェクト)
├── Resources (リソースの集合体)
│ └── Resource (個々のリソース)
└── Assignments (アサイン情報の集合体)
└── Assignment (誰が・どのタスクに・どれくらい割り当てられているか)
この階層をコードで正しく渡り歩くことが、Project VBAを制する第一歩です。
—
3. 実装コード:リソース期間自動算出&カレンダー出力マクロ
以下のコードを、Microsoft ProjectのVBAエディタ(`Alt + F11` で起動)の標準モジュールに貼り付けてください。
実務でそのまま使えるよう、変数の型定義やエラー対策、丁寧なコメントを入れています。
Sub OptimizeResourceAllocation()
‘ =====================================================================
‘ テーマ: リソースのプロジェクト参加期間を自動算出し、稼働状況を可視化する
‘ 執筆者: チーフアーキテクトからのメッセージ
‘ =====================================================================
Dim tsk As Task
Dim res As Resource
Dim asn As Assignment
‘ リソースごとの稼働期間を保持するための変数
Dim resName As String
Dim minStart As Date
Dim maxFinish As Date
Dim hasAssignment As Boolean
‘ イミディエイトウインドウ(Ctrl + G)の見出しを表示
Debug.Print “==================================================”
Debug.Print “【リソース参加期間 & 稼働最適化レポート】”
Debug.Print “==================================================”
‘ 1. プロジェクトに登録されているすべてのリソースをループ処理
For Each res In ActiveProject.Resources
‘ リソースが登録されていない(空白行など)場合はスキップ
If Not res Is Nothing Then
resName = res.Name
hasAssignment = False
‘ 初期値を極端な日付で設定(比較して更新するため)
minStart = #12/31/2099#
maxFinish = #1/1/1900#
‘ 2. アサイン情報(Assignments)から、このリソースに紐づくタスクを探索
For Each asn In res.Assignments
If Not asn.Task Is Data Then ‘ タスクが存在する場合
‘ サマリータスク(親タスク)を除外したい場合はここで条件分岐を追加可能
If Not asn.Task.Summary Then
hasAssignment = True
‘ 開始日の早いものをキャッチ
If asn.Task.Start < minStart Then
minStart = asn.Task.Start
End If
' 終了日の遅いものをキャッチ
If asn.Task.Finish > maxFinish Then
maxFinish = asn.Task.Finish
End If
End If
End If
Next asn
‘ 3. アサインが存在する場合のみ、結果を出力
If hasAssignment Then
Debug.Print “リソース名: ” & resName
Debug.Print ” └ 参画期間: ” & Format(minStart, “yyyy/mm/dd”) & ” ~ ” & Format(maxFinish, “yyyy/mm/dd”)
‘ 【発展】ここでカレンダー形式の簡易マッピングや稼働率チェックを行えます
Call CheckResourceWorkload(res, minStart, maxFinish)
Else
Debug.Print “リソース名: ” & resName & ” (※現在アサインされているタスクはありません)”
End If
Debug.Print “————————————————–”
End If
Next res
MsgBox “リソースの参加期間の算出が完了しました!イミディエイトウインドウを確認してください。”, vbInformation, “処理完了”
End Sub
‘ 補助プロシージャ: リソースの期間内の負荷を簡易チェックするロジック
Private Sub CheckResourceWorkload(targetRes As Resource, startDate As Date, endDate As Date)
‘ ここでは例として、期間中のオーバーロード(過負荷)の有無を判定します
Dim totalWork As Double
totalWork = targetRes.Work / 60 ‘ 分単位の工数を時間に変換
Debug.Print ” └ 総予定工数: ” & totalWork & ” 時間”
If totalWork > 160 Then ‘ 例: 160時間(1人月)を超える場合
Debug.Print ” 【警告】このリソースは期間に対して負荷が高い可能性があります。”
End If
End Sub
—
4. コードのポイントと「初学者が陥りやすい罠」
上記のコードには、Project VBA特有の重要なエッセンスが詰まっています。いくつか重要なポイントを解説します。
① `Nothing` 判定の重要性
Projectのコレクション(`Resources` や `Tasks`)をループさせる際、削除された行や空行が `Nothing` として返ってくることがあります。これをそのまま `res.Name` などで呼び出そうとすると、「実行時エラー ’91’: オジェクト変数または With ブロック変数が見つかりません。」という、VBA初心者キラーのエラーが発生します。
`If Not res Is Nothing Then` というガードを必ず挟むのがプロの鉄則です。
② 日付の比較と初期化のトリック
「最も早い開始日」を見つけるために、最初は `minStart` に未来の遠い日付(例: `2099/12/31`)を代入しています。これを行わないと、最初の比較で正しい最小値が取れなくなってしまいます。日付ロジックを組むときの定番テクニックです。
③ タスクの `Summary`(サマリータスク)の除外
Projectには、複数の子タスクをまとめる「親タスク(サマリータスク)」が存在します。親タスクの日付は子タスクの期間から自動計算されるため、アサイン情報としても重複してカウントされがちです。実務の精度を高めるために `If Not asn.Task.Summary Then` で除外処理を入れています。
—
5. 実行方法と結果の確認
1. Microsoft Projectで、適当なタスクとリソース、そしてアサイン(割り当て)が設定されたプロジェクトを開きます。
2. `Alt + F11` でVBAエディタを開き、上記のコードを貼り付けます。
3. カーソルを `Sub OptimizeResourceAllocation()` の中に置き、`F5` キー(または上部の再生ボタン)を押して実行します。
4. 処理完了後、`Ctrl + G` を押してイミディエイトウインドウを開いてみてください。リソースごとの参加期間と総工数が綺麗に出力されているはずです。
—
まとめ:ここからさらに実務へ応用するために
今回は、リソースのタスク群から「参画期間の自動算出」を行うベースエンジンを作成しました。
ここをクリアしたあなたなら、次のような応用にもチャレンジできます。
- 出力先をイミディエイトウインドウではなく、Excelのシートに直接書き出して綺麗なガントカレンダーを自動生成する
- 期間中の稼働率(ピーク時の負荷)を日別・週別に集計し、リソース不足のボトルネックを自動で赤色ハイライトする
Project VBAを使いこなせば、プロジェクト管理の面倒なルーティンワークはすべて自動化できます。「手作業でのスケジュール調整」から卒業し、より本質的なプロジェクトのコントロールに時間を使いましょう。
あなたのVBAライフが、最高のものになりますように。それでは、次の現場でお会いしましょう!
