【入門編】CalendarオブジェクトをVBAで操作し、プロジェクト固有の「特別休暇」を一括設定する – Project VBA解析バイブル

スポンサーリンク

こんにちは!Project VBAの世界へようこそ。
マクロの記録ボタンを押すだけのステージから一歩進み、自分の手でプロジェクトを意のままにコントロールしたい。そんな熱量を持ったあなたを、私は待っていました。

今回は、実務で必ずと言っていいほど直面する壁「プロジェクト固有の特別休暇の一括設定」をテーマに解説します。

Excel VBAならセルの色を変えるだけで済む話も、MS Projectの世界では「時間軸」と「リソースの稼働日」が複雑に絡み合います。しかし、ご安心を。ここをクリアすれば、Project VBAの基本構造は完全にあなたのものです。さあ、一緒に本質を掴んでいきましょう!

1. なぜ「特別休暇」の自動化が必要なのか?

標準のカレンダー機能を使えば、土日や年末年始の休日は設定できますよね。しかし、実務ではこんな要望が飛んできます。

  • 「全社創立記念日のため、来週の水曜日を急遽休日にしたい」
  • 「プロジェクト独自の全社会議の日は、全タスクの工数計算から除外したい」

これをGUI(画面操作)で何十個ものタスクやリソースに対して手動で設定していたら、それだけで残業が確定してしまいます。
だからこそ、「外部のテキスト(CSVなど)から日付を読み込み、ProjectのCalendarオブジェクトへ一括で流し込む」という自動化の出番なのです。

2. 押さえておくべきProjectオブジェクトの階層構造

コードを書く前に、MS Projectの頭の中を覗いてみましょう。Excelが「ワークブック・ワークシート・セル」なら、Projectは次のようなピラミッド構造をしています。

Application (アプリ全体)
┗ ActiveProject (いま開いているプロジェクト)
┣ Calendars (カレンダーのコレクション)
┃ ┗ Calendar (個別のカレンダー:標準、夜勤など)
┃ ┗ Exceptions (例外日:特別休暇など)
┗ Tasks (タスクのコレクション)

今回の主役は `Calendar` オブジェクト と、その中にある `Exceptions`(例外日) です。カレンダーに対して「この日は例外的に休みだよ」とVBAで教え込むのが、今回のミッションの核心となります。

3. 実装コード:外部ファイルから休日を一括設定する

それでは、現場で即戦力として使える実用コードを公開します。
あらかじめデスクトップなどに、以下のような日付リスト(Shift-JISまたはUTF-8)を記述したテキストファイル(例: `holidays.txt`)を用意しておいてください。

【holidays.txt の中身の例】

2023/11/01
2023/11/15
2023/12/24

黄金のVBAコード

Sub ImportSpecialHolidays()
Dim proj As Project
Dim cal As Calendar
Dim filePath As String
Dim fileNum As Integer
Dim buf As String
Dim targetDate As Date
Dim errCount As Long

‘ 1. アクティブなプロジェクトを取得
Set proj = ActiveProject

‘ 2. 操作するカレンダーを特定(通常は「標準」ベース)
‘ ※プロジェクト内で使用しているベースカレンダー名を指定してください
On Error Resume Next
Set cal = proj.Calendars(“標準”)
On Error GoTo 0

If cal Is Nothing Then
MsgBox “指定されたベースカレンダーが見つかりません。”, vbCritical, “エラー”
Exit Sub
fi

‘ 3. テキストファイルのパスを指定(環境に合わせて変更してください)
filePath = “C:\Temp\holidays.txt”

‘ ファイルの存在確認
If Dir(filePath) = “” Then
MsgBox “休日リストのファイルが見つかりません: ” & filePath, vbCritical, “エラー”
Exit Sub
End If

‘ 4. テキストファイルを読み込みモードでオープン
fileNum = FreeFile
Open filePath For Input As #fileNum

errCount = 0

‘ 5. 1行ずつ読み込んでカレンダーの例外日(Exception)として追加
Do Until EOF(fileNum)
Line Input #fileNum, buf

‘ 空行やコメント行をスキップ
If Trim(buf) <> “” And IsDate(buf) Then
targetDate = CDate(buf)

‘ 【重要】Exceptions.Add メソッドで特別休暇を追加
‘ 引数: From(開始日), To(終了日), Name(名称)
On Error GoTo AddError
cal.Exceptions.Add Type:=pjExceptionByName, _
From:=targetDate, _
To:=targetDate, _
Name:=”特別休暇(自動設定)”
On Error GoTo 0
End If
Loop

Close #fileNum

‘ 6. 完了メッセージ
MsgBox “特別休暇の一括設定が完了しました!”, vbInformation, “成功”
Exit Sub

AddError:
‘ すでに同じ日付が登録されている場合のエラー等をハンドリング
errCount = errCount + 1
Resume Next
End Sub

4. コードの急所と、初心者がハマる罠

上記のコードには、Project VBA特有の「知っていないと泥沼にハマるポイント」がいくつか隠されています。プロの知見として共有しておきましょう。

① カレンダーは「名前」で正確に指定する

Excelなら `Sheets(1)` で適当にシートを掴めますが、Projectのカレンダーは複数のベースカレンダーやリソース個別カレンダーが混在しています。
`proj.Calendars(“標準”)` のように、必ず対象となるカレンダー名を明確に指定してください。ここを間違えると「オブジェクト変数が見つかりません」というエラーの餌食になります。

② `Exceptions.Add` の仕様と重複エラー

`cal.Exceptions.Add` は非常に強力ですが、すでに同じ日付が例外日として登録されている状態で再度実行すると、実行時エラーが発生します。
実務では過去に手動設定した日と重複することもあるため、コード内ではあえて `On Error GoTo AddError` を挟み、万が一の重複エラーを華麗にスルーする(あるいはカウントする)堅牢な設計にしています。

③ タスクのスケジュール再計算(リカルキュレート)

カレンダーを変更しただけでは、すでに配置されているタスクの期限が自動で再計算されない場合があります。必要に応じて、コードの最後に `CalculateAll` メソッドを挟むと完璧です。

‘ カレンダー設定の最後に全タスクを再計算
CalculateAll

最後に:ここをクリアすれば、あなたはもう中級者です

お疲れ様でした!
MS Projectのオブジェクトモデルは、Excelに比べると情報が少なく、最初は取っつきにくく感じたかもしれません。しかし、今回のように 「外部ファイルを読む ➔ カレンダーオブジェクトを捉える ➔ 例外日(Exception)を追加する」 という一連の流れを自分の手で組み上げられたのであれば、あなたのProject VBAスキルは確実に「実務レベル」に到達しています。

ここをクリアできれば、スケジュール管理の自動化など敵ではありません。
ぜひ、ご自身の現場の業務効率化にこのコードを役立ててくださいね。それでは、次のステージでお会いしましょう!

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