【入門編】リソースの「カレンダー」を個別のプロジェクトファイルから一括削除するクリーンアップ – Project VBA解析バイブル

スポンサーリンク

こんにちは!プロジェクト管理の現場で、日々奮闘されていることと思います。

MS Projectを使っていると、なんだかファイルが重くなったり、動かすたびにモッサリしたりすることはありませんか?その原因の一つが、「使われなくなったリソースカレンダーや、不要な例外日の肥大化」です。

今回は、Project VBAの底力を借りて、個別のプロジェクトファイルに巣食う「不要なカレンダーのゴミ」を一網打尽にし、ファイルをシャキッと軽量化するテクニックを伝授します。

「マクロの記録」のボタンを押すだけだったあの頃を卒業し、オブジェクトの生命線を自在に操るエンジニアへの第一歩を、一緒に踏み出しましょう!ここをクリアすれば、Project VBAの基本はバッチリですよ。

—

なぜプロジェクトファイルは重くなるのか?

MS Projectでは、リソースごとに「稼働日」や「休日」を定義するカレンダーを持たせることができます。プロジェクトを長期間運用したり、他のファイルからリソースをコピー&ペーストしたりしていると、「もう使っていないはずのリソースカレンダー」や、過去のイベントなどの「無駄な例外日(Exception)」がファイル内にこっそりと蓄積されていきます。

これがファイルのサイズを膨らませ、計算処理を重くする原因になります。しかし、これを一つひとつ手作業で削除していくのは……考えただけで気が遠くなりますよね。

だからこそ、VBAの出番です!

—

押さえておくべきProject VBAの基本構造

Excel VBAと違い、MS ProjectのVBAには独特の「階層構造(オブジェクトモデル)」があります。今回ターゲットにするのは `Resources` と `Calendar` です。

ここで一つ、実務で絶対に知っておくべき最重要の前提があります。

> ⚠️ 注意:ベースカレンダーとリソース個別カレンダーの罠
> MS Projectには、プロジェクト全体を支配する「ベースカレンダー(標準、夜勤など)」と、特定のリソースに紐づく「リソースカレンダー」があります。
> 標準のベースカレンダーをうっかり削除しようとすると、Projectは激怒してエラーを吐きます。また、現在進行形でタスクに割り当てられているリソースのカレンダーを消すことも許されません。

今回のスクリプトでは、「標準ベースカレンダー以外の、不要なカスタムカレンダー(または未使用の例外日)」を安全にクリーンアップするアプローチを取ります。

—

実装コード:一括クリーンアップ・マクロ

以下のコードを、MS ProjectのVBAエディタ(`Alt + F11`)の標準モジュールに貼り付けてください。

実務の現場でそのままコピペして使えるよう、エラーハンドリングと丁寧なコメントを仕込んでおきました。

Sub CleanUpResourceCalendars()
‘ ==============================================================================
‘ テーマ: リソースカレンダーの例外日クリーンアップ & 未使用カレンダーのパージ
‘ 開発者視点のポイント: 削除不可のシステム標準カレンダーを保護しつつ、
‘ 肥大化した例外日をクリアしてファイルを軽量化します。
‘ ==============================================================================

Dim c As Calendar
Dim exc As Exception
Dim deletedCount As Long
Dim excCount As Long

deletedCount = 0
excCount = 0

‘ 画面描画を停止して処理速度を爆発的に上げる(お作法です)
App.ScreenUpdating = False

On Error GoTo ErrorHandler

‘ プロジェクト内のすべてのカレンダーを走査
For Each c In ActiveProject.Calendars

‘ 【重要】標準ベースカレンダー(Standard, 24Hours, Night Shiftなど)は削除対象外とする
If Not c.BaseCalendar Then

‘ デバッグ用イミディエイトウィンドウ出力
Debug.Print “調査中カレンダー: ” & c.Name

‘ カレンダーに登録されている「例外日(休日や特別稼働日)」を古い順からチェックして削除
‘ 例外日コレクションの数が多いほど、ファイルが肥大化しています
Dim i As Long
For i = c.Exceptions.Count To 1 Step -1
Set exc = c.Exceptions(i)

‘ ここに「特定の条件(例: 過去の古すぎる日付)」で削除するロジックを入れることも可能
‘ 今回はシンプルに、すべてのカスタム例外日をリフレッシュ対象とします
‘ ※実務では必要に応じて日付の条件分岐(If exc.Start < #1/1/2023# Then ...)を追加してください ' 例外日を削除 exc.Delete excCount = excCount + 1 Next i End If Next c ' 処理終了後のフィードバック App.ScreenUpdating = True MsgBox "クリーンアップが完了しました!" & vbCrLf & _ "削除された例外日の総数: " & excCount, vbInformation, "VBA自動化完了" Exit Sub ErrorHandler: App.ScreenUpdating = True MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "予期せぬエラー" End Sub ---

コードの読み解きポイント(先輩からの解説)

1. `App.ScreenUpdating = False` による高速化
VBAで大量のオブジェクト(例外日など)を操作するとき、画面がチラつくと処理速度が何倍も遅くなります。最初に画面描画を止め、最後に `True` に戻すのは、プロのエンジニアにとっての「挨拶」のような基本テクニックです。

2. 逆順ループ(`To 1 Step -1`)の魔術
コレクション(要素の集まり)を前から順番に削除していくと、インデックス(番号)がズレてしまい、思わぬバグ(エラーやスキップ)を生みます。「コレクションを削除・変更するときは後ろから数える」。これはExcel VBAでもProject VBAでも共通の鉄則です。しっかり覚えておいてくださいね。

3. `c.BaseCalendar` のガード
すべてのカレンダーを無心で消そうとすると、Projectの心臓部である標準カレンダーまで消そうとしてエラーになります。「ベース(基準)ではないもの=個別のカスタムカレンダー」という条件でフィルターをかけるのが、安全なシステム構築のコツです。

—

サイズの肥大化したプロジェクトファイルは、それだけでチーム全体のパフォーマンスをジワジワと奪っていく隠れたボトルネックです。このスクリプトを定期的(あるいはプロジェクトのキックオフ前など)に走らせることで、常に軽快でストレスのない環境を維持できます。

「ここをもっとこうしたい」「こんなエラーが出るんだけど?」といった疑問があれば、いつでも頼ってください。エンジニアとしてのあなたの成長を、私はいつも応援しています!

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