こんにちは。プロジェクト管理の現場で日々、スケジュールとリソースのパズルに挑んでいる皆さん。
「進捗率(%完了)を更新したのに、現場の感覚とズレている気がする……」
「メンバーから『あと何時間で終わります』と報告を受けたけど、それをProjectに反映させるのが面倒だ……」
そんな悩みを持ったことはありませんか?
実は、Microsoft Projectを「ただのガントチャート描画ツール」から「生きた管制塔」へと進化させる鍵は、【進捗率】ではなく【残工数】を主役に据えることにあります。
今日は、Project VBAの基本をマスターしながら、現場の「残り時間」から正確な進捗率を自動で導き出す魔法のロジックを伝授します。ここを乗り越えれば、あなたはもうProject VBAの初心者卒業ですよ。
—
1. なぜ「進捗率」を直接入力してはいけないのか?
多くの人がやりがちなのが、タスクの「%完了」に「だいたい50%くらいかな」と数値を直接入力することです。しかし、これは危険です。
Projectにおける進捗の本質は、以下の数式で成り立っています。
[総工数] = [実績工数] + [残工数]
[進捗率(%完了)] = [実績工数] ÷ [総工数]
現場のメンバーが一番正確に把握しているのは「あとどれくらいで終わるか(残工数)」です。ここを起点にVBAで逆算してあげることで、データの整合性が劇的に向上します。
—
2. Project VBAの心臓部「Taskオブジェクト」を理解する
コードを書く前に、私たちが操作する対象を整理しましょう。
Project VBAで最も頻繁に扱うのは `Task` オブジェクト です。
- `t.ActualWork`: これまでに費やした実績工数(分単位で保持されます)
- `t.RemainingWork`: あとどれくらいかかるかの残工数
- `t.PercentComplete`: 私たちが求めたい進捗率(0〜100)
これらを1つずつ手で更新するのは大変ですよね? だから、VBAという「自動化の執事」に任せるのです。
—
3. 実装:残工数から進捗を自動計算するマクロ
それでは、実際のコードを見てみましょう。このコードは、プロジェクト内の全タスクをスキャンし、最新の「残工数」に基づいて「進捗率」を再計算します。
Sub UpdateProgressByRemainingWork()
‘ ———————————————————
‘ 目的: 残工数(Remaining Work)を基準に、タスクの進捗率を自動計算する
‘ 開発者: Project VBA チーフアーキテクト
‘ ———————————————————
Dim t As Task
Dim totalWork As Double
Dim actualWork As Double
Dim remainingWork As Double
‘ 画面更新を停止して処理速度を向上させる
Application.ScreenUpdating = False
‘ プロジェクト内のすべてのタスクをループ処理
For Each t In ActiveProject.Tasks
‘ 1. 空白行やサマリータスク(まとめタスク)はスキップする
‘ サマリータスクは配下のタスクから自動計算されるため、直接いじらないのが鉄則です
If Not (t Is Nothing) Then
If Not t.Summary Then
‘ 2. 各工数の値を取得(内部的には「分」単位で保持されています)
actualWork = t.ActualWork
remainingWork = t.RemainingWork
‘ 3. 総工数を算出 (実績 + 残り)
totalWork = actualWork + remainingWork
‘ 4. 進捗率の計算
‘ 総工数が0(まだ何も割り当てられていない)の場合はエラー回避
If totalWork > 0 Then
‘ 進捗率 = (実績 / 総工数) 100
‘ ProjectのPercentCompleteプロパティに代入します
t.PercentComplete = (actualWork / totalWork) 100
Else
‘ 工数が全く設定されていない場合は0%とする
t.PercentComplete = 0
End If
‘ デバッグ用(イミディエイトウィンドウに出力)
Debug.Print “Task: ” & t.Name & ” -> New Progress: ” & t.PercentComplete & “%”
End If
End If
Next t
‘ 画面更新を再開
Application.ScreenUpdating = True
MsgBox “すべてのタスクの進捗率を、残工数に基づいて更新しました!”, vbInformation, “完了”
End Sub
—
4. ここがポイント! プロが教えるコードの解説
① `If Not (t Is Nothing)` の重要性
Projectのタスク一覧には、何も入力されていない「空白行」が存在することがあります。これに触れようとすると、VBAは「そんなオブジェクトはありません!」と怒ってエラーを出してしまいます。この一行は、エラーで止まらない堅牢なツールを作るための必須テクニックです。
② サマリータスクを触らない
`If Not t.Summary` という条件を入れています。サマリータスク(子タスクをまとめている親タスク)の進捗率は、Project自身が自動で集計するものです。ここをVBAで無理やり書き換えると、計算ロジックが衝突してデータが壊れる原因になります。「餅は餅屋」に任せるのが、Project VBAの極意です。
③ 単位の壁「分」を意識する
Project内部では、工数はすべて「分」で管理されています。例えば「1時間」は `60` です。今回のコードは比率計算なので単位を気にする必要はありませんが、今後「あと2時間追加したい」といった処理を作る際は、`2 60` と書く必要があることを覚えておいてくださいね。
—
5. 陥りやすいエラーと回避策
もしマクロを動かして「実行時エラー ‘1100’」などが出た場合は、以下の点を確認してみてください。
1. タスクが「自動スケジューリング」になっているか?
手動スケジューリングのタスクは、Projectの計算エンジンが一部制限されます。基本的には「自動スケジューリング」で運用することをお勧めします。
2. 実績工数が入力されているか?
残工数だけを入れても、実績が0なら進捗率は0%のままです。「今日は3時間やった(実績)、でもあと5時間かかる(残り)」という両方のデータがあって初めて、正確な進捗が弾き出されます。
—
おわりに:一歩先へ進むあなたへ
「マクロの記録」から一歩踏み出し、こうして自分でループ(`For Each`)を書き、条件分岐(`If`)を加えられるようになれば、Project VBAの基本はバッチリです。
このマクロを使えば、メンバーに「進捗何パーセント?」と聞く必要はありません。「あと何時間で終わる?」と聞くだけで、あなたのProjectは常に最新の、そして正確な状況を映し出すようになります。
まずはこのコードをコピーして、テスト用のプロジェクトで動かしてみてください。その一歩が、あなたのPMライフを劇的に楽にするはずです。
もし分からないことがあれば、いつでも聞いてくださいね。応援しています!
