Project VBAを掌握せよ:独自のWBSコードを自動生成する「階層構造の魔法」
こんにちは。プロジェクト管理の現場で「なぜProject標準のWBSコードはこうも融通が利かないんだ!」と頭を抱えたことはありませんか?
MS Projectの標準機能は優秀ですが、企業の現場には「A-01-01」のような独自の管理コード体系が必ず存在するはずです。これを手作業で更新するのは、まさに苦行。今日は、Project VBAを使ってこのWBSコードを完全に制御し、階層構造と連動させて自動採番する方法を伝授します。
マクロの記録から一歩踏み出し、Projectの「心臓部」に触れる準備はいいですか?
—
1. なぜ「WBSコード」に手を出してはいけないのか?
まず、重要な警告です。MS Projectの`WBS`フィールドは、標準機能の「WBS番号の再計算」と密接に結びついています。ここに値を直接書き込むと、プロジェクトの階層構造が変わった瞬間に整合性が崩壊します。
そこで、我々プロのアーキテクトは「ユーザー設定フィールド(Text1など)」を活用します。Projectの標準仕様を壊さず、かつ独自のビジネスロジックを実装する。これが長生きするシステムの鉄則です。
—
2. 階層構造を読み解く:OutlineLevelの正体
Projectのタスクには、必ず`OutlineLevel`というプロパティが存在します。
- プロジェクト全体:レベル0
- 大項目:レベル1
- 中項目:レベル2
- 作業:レベル3
この「深さ」と、その親タスクが何番目にあるかを知れば、コードは自動生成できます。
実装のポイント:親タスクを特定する
VBAで親タスクを探すには、現在のタスクから一つずつ上に遡り、`OutlineLevel`が自分より小さいタスクを探すのが最も確実です。
—
3. 実践:WBS自動採番コード
それでは、以下のコードを標準モジュールに貼り付けてみてください。このコードは、全タスクを走査し、階層構造に基づいて「A-01-01」形式のコードを生成します。
Sub GenerateCustomWBS()
Dim t As Task
Dim parentTask As Task
Dim wbsCode As String
‘ プロジェクト内の全タスクをループ
For Each t In ActiveProject.Tasks
If Not t Is Nothing Then
‘ プロジェクトサマリータスクはスキップ(レベル0)
If t.OutlineLevel > 0 Then
‘ 親タスクを探すロジック
Set parentTask = GetParentTask(t)
If parentTask Is Nothing Then
‘ 親がいない(レベル1)の場合の採番
t.Text1 = “A-” & Format(t.OutlineChildren.Count + 1, “00”)
Else
‘ 親のコードを継承し、自分の兄弟の中での順序を付与
t.Text1 = parentTask.Text1 & “-” & Format(GetSiblingIndex(t), “00”)
End If
End If
End If
Next t
MsgBox “WBSコードの自動採番が完了しました!”, vbInformation
End Sub
‘ 親タスクを特定する補助関数
Function GetParentTask(t As Task) As Task
Dim p As Task
Set p = t.ParentTask
‘ 親がプロジェクト全体(ID=0)の場合はNothingを返す
If p.ID = 0 Then Set GetParentTask = Nothing Else Set GetParentTask = p
End Function
‘ 兄弟タスク内での自分の順番を返す関数
Function GetSiblingIndex(t As Task) As Integer
Dim sibling As Task
Dim count As Integer
count = 1
For Each sibling In t.ParentTask.OutlineChildren
If sibling.ID = t.ID Then
GetSiblingIndex = count
Exit Function
End If
count = count + 1
Next sibling
End Function
—
4. コードの解説:ここを理解すれば無敵です
- `ActiveProject.Tasks`: プロジェクト内の全タスクを収めたコレクションです。ここをループするのがVBAの基本。
- `OutlineChildren`: 指定したタスクの「直下」にあるタスク群を指します。これを使うと、わざわざ複雑なループを書かなくても「兄弟関係」を簡単に取得できます。
- `Text1`への代入: MS Projectには`Text1`〜`Text30`まで、自由に使えるフィールドがあります。これらはExcelで言えば列のようなもの。ここに計算結果を格納するのが、Project VBAの正しい作法です。
—
5. 初学者が陥りやすい罠と対策
1. 「Nothing」の罠: `t.ParentTask`は、タスクが階層の最上位にある場合、エラーではなく`Nothing`を返します。これを確認せずにプロパティにアクセスすると、Projectがクラッシュします。必ず`If Not t.ParentTask Is Nothing Then`でガードしましょう。
2. パフォーマンス: タスク数が多い場合、`For Each`ループの中でGUI描画が走ると激重になります。大規模プロジェクトでは`Application.ScreenUpdating = False`を冒頭に入れると劇的に速くなります。
—
最後に:自動化は「思考の解放」
WBSコードを手打ちしている時間は、クリエイティブな思考を止める「負債」です。
今回紹介したコードをベースに、皆さんの会社のルールに合わせて「A-」を「ProjectCode-」に変えたり、レベルごとに区切り文字を変えたりしてみてください。
「コードを書くこと」は「仕組みを創ること」です。今日からProjectの奴隷ではなく、Projectを支配するアーキテクトとして、快適なプロジェクト管理ライフを送ってくださいね。
応援しています!何か詰まったら、いつでも聞きに来てください。
