こんにちは!Project VBAの世界へようこそ。
マクロの記録から一歩踏み出し、「現場で本当に使える自動化」をマスターしようとしているあなたなら、日々のスケジュール管理でこんな悩みを抱えたことがあるのではないでしょうか?
- 「せっかく順調に進んでいるタスクの進捗率を、誰かにうっかり上書きされてスケジュールが狂ってしまった…」
- 「過去に完了したタスクの前提条件(依存関係)をいじられて、ガントチャート全体の辻褄が合わなくなった…」
複数人でひとつのプロジェクトファイルを扱っていると、どうしてもこうしたヒューマンエラーや誤操作は避けて通れません。
そこで今回は、「タスクの完了率(%コンプリート)に基づいて、進捗済みタスクをVBAで自動的に保護(ロック)する仕組み」を徹底解説します。
ここをクリアすれば、Project VBAのオブジェクト操作の核心がグッと見えてきますよ。しっかりついてきてくださいね!
—
1. なぜ「進捗済みタスクの保護」が必要なのか?
Excelと違い、Microsoft Projectは「時間」と「リソース」と「依存関係(タスク同士のつながり)」が複雑に絡み合う生き物です。
例えば、タスクAがすでに「100%完了」しているにもかかわらず、誰かが誤ってその期間や先行タスクを変更してしまうと、後続のタスクすべてのスケジュールがドミノ倒しのように崩壊します。
これを防ぐために、「一定以上進んだタスクは、VBAの力で自動的に編集不可(または制約固定)にしてしまおう」というのが今回のテーマです。
押さえておくべきProject VBAの重要オブジェクト
Project VBAを操る上で、以下の階層構造は絶対に覚えておいてください。
Application (Project本体)
└── ActiveProject (現在開いているプロジェクト)
└── Tasks (タスクの集合体)
└── Task (個々のタスク)
個々の `Task` オブジェクトには、進捗を表す `PercentComplete` や、スケジュールの固定方法を決める `ConstraintType` といった強力なプロパティが備わっています。これらをVBAで制御します。
—
2. 【実践】進捗済みタスクを自動ロックするVBAコード
それでは、実際のコードを見てみましょう。
今回は、「完了率が 100%(=完全に完了したタスク)」を検出し、そのタスクのスケジュールや前提条件がうっかり変更されないよう、制約を「完了日以降(As Late As Possible または Start No Earlier Than など、実務に合わせて調整)」に固定、あるいは編集ロックをかけるスクリプトです。
以下のコードを、ProjectのVBAエディタ(`Alt + F11`)の標準モジュールに貼り付けてみてください。
Sub ProtectCompletedTasks()
‘ 宣言
Dim tsk As Task
Dim protectedCount As Long
‘ 初期化
protectedCount = 0
‘ 画面描画を停止してマクロの実行速度を爆発的に上げる(プロの鉄則)
Application.ScreenUpdating = False
‘ アクティブプロジェクト内のすべてのタスクをループ処理
For Each tsk Is ActiveProject.Tasks
‘ 抽出条件:有効なタスク(サマリータスクや空行を除外)かつ、完了率が100%のもの
If Not tsk Is Nothing Then
If tsk.Summary = False And tsk.PercentComplete = 100 Then
‘ 【重要】ここでタスクを保護する処理を行います
‘ 例:タスクの制約タイプを「指定日以降に開始(Start No Earlier Than)」にし、
‘ 現在の開始日に固定することでスケジュール崩壊を防ぎます。
‘ ※Projectの仕様上、完全な「読み取り専用」プロパティはないため、
‘ 制約をかけたり、フラグフィールドを「Yes」にして注意喚起します。
tsk.ConstraintType = pjStartNoEarlierThan
tsk.ConstraintDate = tsk.Start
‘ ユーザー定義のフラグフィールド(例: フラグ1)を「Yes」にして視覚的にロック状態を示す
tsk.Flag1 = True
‘ コメント欄にロック日時を自動記録
tsk.Notes = tsk.Notes & vbCrLf & “[VBA自動保護] 完了済みのため ” & Date & ” にロックされました。”
protectedCount = protectedCount + 1
End If
End If
Next tsk
‘ 画面描画を再開
Application.ScreenUpdating = False
Application.ScreenUpdating = True
‘ 完了メッセージ
MsgBox “処理が完了しました。” & vbCrLf & _
“保護されたタスク数: ” & protectedCount & ” 件”, vbInformation, “タスク自動ロック”
End Sub
—
3. コードの注目ポイントを解説!
初心者の方でも「おっ、なるほど!」と思えるように、コードのキモを3つに分けて解説します。
① `Application.ScreenUpdating = False` の魔法
プロのVBAエンジニアが必ず書くのがこの一行です。Projectはタスク数が数千件になると、ループ処理のたびに画面のガントチャートを再描画しようとして動作がものすごく遅くなります。
処理の最初に画面描画を止め、最後に `True` に戻すことで、処理スピードが何倍にも跳ね上がります。
② `tsk.Summary = False` でのフィルタリング
ここが実務で一番ハマりやすいポイントです。
Microsoft Projectには、子タスクをまとめる「サマリータスク(親タスク)」が存在します。親タスクの `PercentComplete` は子タスクの進捗から自動計算されるため、親タスクに対して直接VBAで値を書き換えたり制約を強制しようとすると、エラーや予期せぬバグの原因になります。
そのため、`tsk.Summary = False`(=個別の実作業タスクであること)という条件を必ず挟むのが鉄則です。
③ 制約(Constraint)によるガード
Excelのように「セルをロックしてシート保護」という概念がProjectにはありません。その代わり、「制約(Constraint)」という強力な仕組みを使って、タスクが勝手に前後に移動しないようガチッと固定します。
—
4. 陥りやすいエラーと回避のコツ
開発現場でこのマクロを運用し始めると、いくつかの「壁」にぶつかることがあります。あらかじめ知っておきましょう。
- エラー:「実行時エラー ‘1100’: このフィールドは読み取り専用です。」
- 原因: サマリータスクや、リソースによって自動計算されるフィールド(コストや一部の工数など)を無理やり書き換えようとした時に発生します。
- 対策: 先ほど紹介したように、必ず `If tsk.Summary = False` でサマリータスクを弾くガード条件を入れてください。
- 「マクロを実行しても何も変わらない気がする…」
- 原因: 対象となるタスクの `PercentComplete` が本当に100%になっているか確認してください。また、タスク名だけの空行(`Task is Nothing`)が混ざっているとスキップされます。
—
まとめ:ここをクリアすれば、Project VBAは怖くない!
今回は「タスクの完了率に基づいた依存関係・スケジュールの自動ロック」という、実務で今すぐ使えるテーマを解説しました。
- プロジェクトのオブジェクト構造(`ActiveProject.Tasks`)を理解する
- サマリータスクを必ず除外する(`tsk.Summary = False`)
- 画面描画を制御してパフォーマンスを保つ
この3つさえ押さえておけば、あなたの組むVBAコードは、ただの「自動化マクロ」から、プロジェクトの品質を守る「堅牢なシステム」へと進化します。
現場のメンバーから「おっ、これのおかげでスケジュールが荒れなくなったよ!」と感謝される瞬間はもうすぐです。ぜひ、あなたの手元のプロジェクトファイルで試してみてくださいね。
それでは、次回の高度なVBA解説でお会いしましょう!
