【実務・中級編】リソースの「カレンダー例外」を祝日テーブルから一括更新するメンテナンスツール – Project VBA解析バイブル

スポンサーリンク

Project VBAを掌握せよ:リソースカレンダー例外を「祝日データ」で一括制圧する極限設計

プロジェクト管理において、リソースの稼働率調整は死活問題だ。特に、毎年変わる祝日を各リソースの「カレンダー例外」として手動でポチポチ登録している現場があるなら、それは即刻辞めるべきだ。その作業は、ヒューマンエラーの温床であり、エンジニアの時間をドブに捨てているに等しい。

今回は、Project VBA(Microsoft Project VBA)を駆使し、外部CSVから祝日を読み込み、全リソースのカレンダーを一括更新する「堅牢かつ高速」なツール設計を伝授する。

—

1. なぜ「力技のループ」が地獄を招くのか

多くの初心者は、全リソースをループで回し、その中でさらにカレンダー例外を一つずつ追加するコードを書く。だが、考えてみてほしい。Projectのオブジェクトモデルにおいて、`Exceptions.Add`は非常に重い処理だ。

  • 非効率な設計: 毎回`ActiveProject.Resources`を全走査し、例外の重複チェックを怠る。
  • メモリの浪費: プロセス間通信が多発し、数千件のタスクやリソースを抱えるプロジェクトでは、アプリが「応答なし」になる。

極限の知見: 「例外」は追加する前に「既存の定義との比較」を行い、差分のみを適用する。これが、大規模プロジェクトにおける唯一の正解だ。

—

2. 実装の要諦:堅牢なコード・アーキテクチャ

以下のコードは、保守性を考慮し、CSV読み込みとカレンダー更新のロジックを分離したプロダクションレベルの構成だ。

祝日一括更新スクリプト (VBA)

Option Explicit

‘ 祝日データ形式(CSV): 2024/01/01, 元日
Public Sub SyncHolidaysFromCSV()
Dim filePath As String
Dim fso As Object, ts As Object
Dim lineData As String
Dim holidayDate As Date
Dim holidayName As String
Dim res As Resource

filePath = “C:\Temp\Holidays.csv” ‘ 外部定義ファイル
Set fso = CreateObject(“Scripting.FileSystemObject”)

If Not fso.FileExists(filePath) Then
MsgBox “祝日ファイルが見つかりません。”, vbCritical
Exit Sub
End If

Set ts = fso.OpenTextFile(filePath, 1) ‘ ForReading

‘ プロジェクト全体のリソースを巡回
For Each res In ActiveProject.Resources
If Not res Is Nothing Then
‘ カレンダー例外の更新処理
ts.SkipLine ‘ 必要に応じてヘッダー読み飛ばし
Do While Not ts.AtEndOfStream
lineData = ts.ReadLine
holidayDate = CDate(Split(lineData, “,”)(0))
holidayName = Split(lineData, “,”)(1)

‘ 重複チェック:既存の例外に存在するか確認してから追加
If Not IsHolidayExists(res.Calendar, holidayDate) Then
res.Calendar.Exceptions.Add Type:=pjDayTypeWorking, _
Start:=holidayDate, _
Finish:=holidayDate, _
Name:=holidayName
End If
Loop
ts.Close
Set ts = fso.OpenTextFile(filePath, 1) ‘ 再度読み込み用に開く
End If
Next res

MsgBox “全リソースのカレンダー更新が完了しました。”, vbInformation
End Sub

‘ 既存例外の重複チェック関数
Private Function IsHolidayExists(cal As Calendar, targetDate As Date) As Boolean
Dim ex As Exception
IsHolidayExists = False
For Each ex In cal.Exceptions
If ex.Start = targetDate Then
IsHolidayExists = True
Exit Function
End If
Next
End Function

—

3. 現場で生き残るための「3つの鉄則」

① ファイルI/Oのボトルネックを排除せよ

上記のコードでは、リソースごとに毎回ファイルを読み込んでいる。リソース数が多い場合、CSVを一度配列(`Variant`型)に格納し、メモリ上で処理する設計に変更せよ。ディスクI/Oは極限まで減らすのが鉄則だ。

② エラーハンドリングの徹底

`CDate`変換で失敗するCSVデータは、例外を吐いて止まる。`IsDate`でバリデーションを行い、不正な行はログに出力して処理を継続する設計にすべきだ。現場ツールが途中で止まることは、プロジェクトマネージャーからの信頼を失うことに直結する。

③ データベース連携の視点

もし祝日データがExcelやSharePoint等で管理されているなら、CSV経由ではなく直接`ADO`経由で取得することを検討せよ。中間ファイルは「同期ズレ」の原因となる。

—

結論:ツールは「書く」のではなく「守る」もの

今回紹介したコードは、あくまで「骨子」だ。重要なのは、このスクリプトを「誰でも確実に実行できる状態」に保つことにある。リボンメニューに組み込む、あるいはプロジェクトのオープン時に更新チェックを走らせるなど、業務フローの中に組み込んでこそ、真の自動化エンジニアと言える。

「手作業を減らす」という甘い考えを捨て、「管理コストをゼロにする」という野心を持ってほしい。それが、Project VBAを制し、プロジェクトを支配する唯一の道だ。

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