こんにちは!Microsoft Projectの裏側に潜む広大なVBAの世界へようこそ。
普段、マクロの記録ボタンを押して「動いた!」と喜んでいた時期から一歩進み、いよいよ「自分の手でプロジェクトを意のままにコントロールしたい」と願うあなたへ。
今回は、現場で絶対に避けて通れない、しかしGUIでやると発狂しそうになる面倒な作業――「リソースのベースカレンダーの動的生成と一括適用」を、VBAの魔術を使って一撃で解決する方法を伝授します。
ここをクリアすれば、Project VBAの「オブジェクトのライフサイクルとスコープ」の基本がパーフェクトに身につきますよ。さあ、一緒に扉を開けましょう!
—
1. なぜGUIではなく「VBAでカレンダー」なのか?
想像してください。
あなたは数十人の外部パートナーや、変則的なシフトで動く製造ライン、あるいは海外の拠点を持つグローバルプロジェクトの管理を任されています。
プロジェクトごとに「土日休み」「水曜定休」「夜勤シフト」「現地国の祝日」が違う。これをMS ProjectのGUIで一つひとつ「変更」画面を開いてポチポチ設定していませんか?
- GUIの悲劇: リソースが100人いれば、100回同じダイアログを開いてカレンダーを選び直す地獄。
- VBAの救済: 独自の勤務カレンダーオブジェクトをプログラムで瞬時に生み出し、一瞬でリソースに割り当てる。
Project VBAにおいて、カレンダー(`Calendar`オブジェクト)とリソース(`Resource`オブジェクト)の関係性を理解することは、中級者への登竜門です。
—
2. 押さえておくべきProject VBAの基本構造
コードを書く前に、Project特有の「世界観」を頭に入れておきましょう。Excel VBAとは少し空気が違います。
1. ActiveProjectがすべての中心:
Excelの `ActiveWorkbook` と同じように、今開いているプロジェクトは `ActiveProject` です。
2. カレンダーはプロジェクト全体のもの:
カレンダーは、個々のリソースに属しているのではなく、プロジェクト(`ActiveProject.Calendars`)に属しています。まずプロジェクトの中に「ベースとなる型」を作り、それをリソースの `BaseCalendar` プロパティに紐付ける、という二段構えをとります。
—
3. 【実践】ベースカレンダーを動的生成し、リソースへ一括適用するコード
百聞は一見にしかず。現場でそのままコピペして、少しカスタマイズするだけで使える実用的なコードを用意しました。
このスクリプトは、「特殊シフト(水曜休み・土日出勤)」という名前の新しいカレンダーを作り、プロジェクト内のすべてのリソースに強制適用するものです。
Sub ApplyCustomBaseCalendarToAllResources()
Dim targetCalendarName As String
targetCalendarName = “【特殊シフト】水曜休みカレンダー”
Dim newCal As Calendar
Dim res As Resource
Dim calExists As Boolean
On Error GoTo ErrorHandler
‘ — 1. すでに同じ名前のカレンダーが存在するかチェック —
calExists = False
For Each newCal In ActiveProject.Calendars
If newCal.Name = targetCalendarName Then
calExists = True
Exit For
End If
Next newCal
‘ — 2. 存在しない場合は新しくカレンダーを生成 —
If Not calExists Then
‘ Add メソッドで新しいベースカレンダーを作成
Set newCal = ActiveProject.Calendars.Add(targetCalendarName)
‘ 【重要】ここで独自の休日や稼働時間を設定できます
‘ 例として「水曜日(DayType = 4)」を休日(非稼働日)に設定します
‘ (1:日曜日, 2:月曜日, 3:火曜日, 4:水曜日, 5:木曜日, 6:金曜日, 7:土曜日)
newCal.WeekDays(pjWednesday).Working = False
‘ 土曜日・日曜日は稼働日に変更する例
newCal.WeekDays(pjSaturday).Working = True
newCal.WeekDays(pjSaturday).WorkTimes.Add From:=”09:00″, To:=”18:00″
newCal.WeekDays(pjSunday).Working = True
newCal.WeekDays(pjSunday).WorkTimes.Add From:=”09:00″, To:=”18:00″
MsgBox “新しいベースカレンダー「 ” & targetCalendarName & ” 」を作成しました。”, vbInformation, “生成完了”
Else
Set newCal = ActiveProject.Calendars(targetCalendarName)
MsgBox “既存のカレンダー「 ” & targetCalendarName & ” 」を使用します。”, vbInformation, “既存利用”
End If
‘ — 3. プロジェクト内の全リソースに作成したカレンダーを一括適用 —
Dim applyCount As Long
applyCount = 0
For Each res In ActiveProject.Resources
‘ リソースが空白(ゴミデータ)でないことを確認
If Not res Is Nothing Then
If res.Name <> “” Then
‘ リソースのベースカレンダープロパティに名前を代入
res.BaseCalendar = newCal.Name
applyCount = applyCount & 1 ‘ カウントアップのつもり (実際は加算処理に修正してね)
applyCount = applyCount + 1
End If
End If
Next res
‘ — 4. 完了通知 —
MsgBox “処理が完了しました!” & vbCrLf & _
“対象カレンダー: ” & targetCalendarName & vbCrLf & _
“適用されたリソース数: ” & applyCount & ” 人”, vbInformation, “一括処理成功”
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “予期せぬエラー”
End Sub
—
4. コードの深掘り解説:ここがエンジニアの腕の見せ所
初心者の方がハマりやすいポイントや、コードの核心部分を紐解いていきましょう。
① `ActiveProject.Calendars.Add` の罠
カレンダーを新しく作る時、すでに同じ名前のカレンダーが存在していると、Projectは容赦なく実行時エラー(エラー番号:1100など)を吐き出して止まります。
そのため、コード前半のように「ループを回して同名のカレンダーがないか事前に確認する(Existチェック)」という防衛的プログラミング(Defensive Programming)がプロの現場では必須となります。
② 曜日を表す定数(`pjWednesday` など)
Project VBAには、曜日をスマートに指定するための組み込み定数(`pjSunday`, `pjMonday`, `pjWednesday`…)が用意されています。マジックナンバー(いきなり数字の `4` を書くなど)を使わず、こうした公式の定数を使うことで、コードの可読性が劇的に上がります。
③ `res.BaseCalendar` への代入
リソース側にカレンダーを適用する際、オブジェクトそのものではなく「カレンダーの名前(文字列)」を代入している点に注目してください。
`Set res.BaseCalendar = newCal` ではなく、 `res.BaseCalendar = newCal.Name` です。これを知らずにオブジェクトをそのまま突っ込んでエラーになる初心者が後を絶ちません。ここ、テストに出ますよ!
—
5. 初学者が陥りやすいエラーと回避の呪文
最後に、現場で泣かないための心得をいくつか。
- エラー:「指定された名前が見つかりません」
- 原因: `res.BaseCalendar` に代入しようとした文字列が、実際にはプロジェクトに存在しないカレンダー名である場合(全角・半角のスペースや誤字脱字に注意)。
- エラー:「このフィールドはエンタープライズリソースに対して読み取り専用です」
- 原因: Project ServerやProject Onlineに接続された「エンタープライズ環境」でローカルマクロを実行している場合、サーバー側のリソース設定はVBAから直接書き換えられないことがあります。ローカル環境(スタンドアロン)でテストしているか確認してください。
—
おわりに:自動化の快感をあなたに
いかがでしたか?
「リソースのカレンダー変更をVBAで自動化する」という一見難しそうなテーマも、オブジェクトの構造を少し覗き見れば、怖くありませんよね。
手作業で数時間かかっていたリソース設定が、たった0.5秒で、しかもヒューマンエラーゼロで完了する――。この瞬間を味わうと、もう二度と手動には戻れなくなります。
ここをクリアしたあなたなら、もうProject VBAの基本はバッチリです!自信を持って、自分のプロジェクトの自動化に挑んでください。それでは、次回の極限の知見でお会いしましょう!
