【Project VBAの極意】その日付操作、危険です。稼働日カレンダーを掌握して「正しいタスク開始日」を制御せよ
こんにちは。Project VBAの世界へようこそ。
マクロの記録ボタンを押してコードを眺めていたあなた、そろそろ「なぜか計算がズレる」「祝日にタスクが入ってしまう」という壁にぶつかっていませんか?
Project VBAにおいて、日付を扱うことは単なる数値の計算ではありません。それは、「Projectの心臓部であるカレンダーという名の制約」と向き合う作業です。
今日は、初心者の方が陥りやすい「日付計算の落とし穴」と、それを回避してプロのコードを書くための極意を伝授します。
—
1. なぜ「DateAdd関数」だけでは不十分なのか?
VBA標準の`DateAdd`関数や`+ 1`という操作は、いわば「カレンダーのない世界」の住人です。
Projectにおける「1日」とは、物理的な24時間ではありません。「プロジェクトカレンダーで設定された稼働時間」を指します。
- 落とし穴: 土日を無視してタスクを翌日に設定すると、休日である日曜日にタスクが始まってしまう。
- 真実: Projectは、カレンダー設定を無視した強制的な値の代入を極端に嫌います。無理やり書き換えると、スケジュールが崩壊し、予期せぬ「制約(Constraints)」が勝手に付与されてしまいます。
—
2. 稼働日を考慮した「正しいタスク開始日」の書き換え方
Project VBAでタスクの開始日を安全に操作するには、`Task.Start` プロパティを直接いじる前に、「Projectが持つカレンダー機能」を呼び出すのが鉄則です。
以下のコードは、タスクの開始日を「現在の開始日から3営業日後」に安全にずらすためのテンプレートです。
Sub SafeSetStartDate()
Dim proj As Project
Dim tsk As Task
Dim newDate As Date
Set proj = ActiveProject
Set tsk = proj.Tasks(1) ‘ 1番目のタスクを操作
‘ プロジェクトの稼働日カレンダーを使用して日付を計算する
‘ proj.Calendar.DateAdd を使うのが、プロのやり方です
‘ 3d は「3営業日」を意味します
newDate = proj.Calendar.DateAdd(tsk.Start, “3d”)
‘ ここで初めてタスクの開始日を更新する
tsk.Start = newDate
MsgBox “タスク「” & tsk.Name & “」の開始日を更新しました。”
End Sub
このコードのポイント
- `proj.Calendar.DateAdd`: これが伝説の武器です。ただのVBA関数ではなく、Projectが持つ「稼働日カレンダー」を読み込んで計算してくれます。
- 「d」の扱い: このメソッドでは「3d」と書けば「3営業日」として解釈されます。これが`DateAdd`との決定的な違いです。
—
3. 初心者が絶対やってはいけない「やってはいけない操作」
現場でよく見る「動かない、あるいはバグるコード」の典型例を紹介します。
1. 文字列で日付を代入する
- `tsk.Start = “2023/10/01″`
- これを行うと、Projectは「あ、このタスクは強制的にこの日に固定しなきゃ(開始日制約の付与)」と判断し、後続タスクとの連動が壊れます。
2. 土日を計算ロジックに入れてしまう
- if文で「土日なら月曜にする」といったロジックを自分で書こうとしないでください。カレンダー設定が変更された瞬間に、あなたのコードはゴミになります。
—
4. プロのエンジニアとしてのアドバイス:日付操作の「作法」
タスクの開始日を操作する際、必ず「制約条件(ConstraintType)」に注意を払ってください。
もし、VBAで日付をセットしたことで「開始日固定」という制約がついてしまったら、後でスケジュール調整が効かなくなります。日付を動かした後は、必要に応じて制約を解除する処理もセットで覚えると、あなたのスキルは一気に中級者レベルへ引き上がります。
‘ 日付を更新した後、制約を「できるだけ早く(As Soon As Possible)」に戻す
tsk.ConstraintType = pjAsSoonAsPossible
—
まとめ:ここをクリアすれば、あなたはもう初心者じゃない
Project VBAにおける日付計算とは、「自分勝手な計算を押し付けるのではなく、Projectのカレンダーに相談する」というプロセスです。
1. `DateAdd`ではなく`Calendar.DateAdd`を使え!
2. 稼働日を理解し、制約条件に注意せよ!
3. マクロの記録に頼らず、オブジェクトモデルの意図を汲み取れ!
この二つを守るだけで、あなたの書くコードは「勝手にスケジュールが狂う」という呪縛から解放されます。
次は、タスクの「期間」と「稼働時間」の関係について深く掘り下げてみましょうか。Project VBAの世界は、知れば知るほど面白いですよ。またいつでも質問してくださいね。
