Project VBAを掌握せよ:リソースカレンダーをCSVで支配する「例外日」自動化術
こんにちは。現場で泥臭い自動化を積み重ね、いつしかProject VBAの深淵を覗くようになったエンジニアです。
「マクロの記録」ボタンを押すだけの日常から卒業したい君へ。今回は、Projectの心臓部である「リソースカレンダー」をCSVから一括操作するという、現場で最も重宝されるスキルを伝授します。
手作業でカレンダーの例外日をポチポチ入力する……そんな苦行は今日で終わりにしましょう。
—
1. なぜ「カレンダー」をコードで触るのか?
Projectにおける「リソースカレンダー」は、ただの休日設定ではありません。「プロジェクトの納期という名の物理法則」を決定づけるマスターデータです。
- 手動の罠: リソースが100人いれば、祝日の設定だけで何時間かかるか。
- 自動化の真髄: CSVを用意し、FSO(FileSystemObject)で読み込み、Projectのオブジェクトを叩く。これができれば、君はもう単なるオペレーターではありません。
—
2. 準備するもの:CSVの構造
まずは、CSVを以下の形式で準備してください(例:`holiday.csv`)。
2023/12/29,年末休暇
2024/01/01,元日
※日付と名称をカンマで区切る、この単純なルールが自動化の第一歩です。
—
3. 実装:FSOとProjectオブジェクトの融合
では、核心のコードです。標準モジュールに貼り付けてください。
Option Explicit
‘ 参照設定: Microsoft Scripting Runtime (FSOを使うため)
‘ Microsoft Project XX.X Object Library
Sub ImportResourceCalendarExceptions()
Dim fso As Object
Dim ts As Object
Dim strLine As String
Dim data() As String
Dim res As Resource
Dim cal As Calendar
‘ ファイルパスの設定
Const CSV_PATH As String = “C:\Temp\holiday.csv”
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set ts = fso.OpenTextFile(CSV_PATH, 1) ‘ 1 = ForReading
‘ 全リソースをループしてカレンダーを操作
For Each res In ActiveProject.Resources
‘ リソース自体のカレンダーを取得
Set cal = res.Calendar
‘ CSVを読み込みながら例外を追加
ts.ReadLine ‘ 先頭行を飛ばす等の処理が必要ならここで
Do Until ts.AtEndOfStream
strLine = ts.ReadLine
data = Split(strLine, “,”)
‘ 例外日の追加: Exceptions.Add(開始日, 終了日, 名前)
‘ ここがProject VBAの肝です
cal.Exceptions.Add Type:=pjDayTypeWorking, _
Start:=data(0), _
Finish:=data(0), _
Name:=data(1)
Loop
ts.Close
Next res
MsgBox “カレンダー更新完了!”, vbInformation
End Sub
—
4. ここを理解すれば、君はもう中級者だ
コードを読み解く際、以下の3点を意識してください。
① FSO(FileSystemObject)の役割
VBA標準の`Open`文よりも、FSOの方がエラーハンドリングが強力で、現代的です。ファイルを「ストリーム」として扱う感覚は、他の言語でも役立つ基礎体力になります。
② `Resource.Calendar` と `ActiveProject.BaseCalendar` の違い
ここが初心者が一番陥りやすい罠です。
- Resource.Calendar: そのリソース固有のカレンダー。
- BaseCalendar: プロジェクト全体や、複数のリソースで共有する「ベース」となるカレンダー。
今回は「リソースの稼働を個別に調整する」ため、`res.Calendar`を狙い撃ちしています。
③ `Exceptions.Add` の魔法
`Type:=pjDayTypeWorking`(稼働日)か`pjDayTypeNonWorking`(非稼働日)かを指定できます。今回は祝日なので、本来は`pjDayTypeNonWorking`を指定するのが正解ですね。※あえてヒントを残しておきます。ぜひ書き換えて試してみてください。
—
5. 陥りやすいエラーと対策
- 「オブジェクトが必要です」エラー:
`ActiveProject.Resources`が空ではないか確認しましょう。リソースが登録されていないプロジェクトではループが回りません。
- 日付の形式エラー:
CSV内の日付文字列がシステムの日付設定と合致しない場合、`CDate()`関数で明示的に変換してから渡すのが安全です。
—
最後に:先輩からのアドバイス
「マクロの記録」は便利ですが、Projectのオブジェクトモデルは非常に深い。記録では決して出力されないプロパティやメソッドが、君の仕事を自動化の領域へ引き上げてくれます。
最初は難しく感じるかもしれません。でも、今日このコードを動かした瞬間、君は「Projectという巨大なシステムの管理者」になったのです。
次は、プロジェクトの進捗に応じて「自動的にタスクを再スケジュールする」機能に挑戦してみませんか?応援していますよ。困ったことがあれば、またいつでも聞きに来てください。
