【入門編】「ラグタイム」の単位変換:日数から時間単位への一括変換と計算ロジックの最適化 – Project VBA解析バイブル

スポンサーリンク

こんにちは!Project VBAの世界へようこそ。
マクロの記録から一歩踏み出し、本格的なプロジェクト制御の自動化に挑むあなたを、今日は心から歓迎します。

現場でMS Projectを触っていると、必ずと言っていいほどぶ wall(壁)にぶつかりますよね。そう、「ラグタイムの単位問題」です。
画面上では「2日」と入力したはずなのに、VBAで覗いてみると「16時間」になっていたり、逆にカレンダーの設定変更によってズレが生じたり……。

「ここをクリアすれば、Project VBAの基本はバッチリですよ!」

今回は、カレンダーの稼働時間に完全に依存するラグタイムの正体を暴き、日数から時間単位への一括変換と、計算ロジックを極限まで最適化する実務的なアプローチを、優しく、そして深く伝授します。

1. なぜ「ラグタイム」でプログラミング初学者はつまずくのか?

タスクとタスクの間に設ける「前提条件(先行タスク)」と、その間の「遅延時間(ラグタイム)」。
GUI(画面)からポチポチ設定している分には楽ですが、これをVBAで制御しようとすると、多くの人が混乱の沼にハマります。

最大の理由は、「Project内部のデータはすべて『分(Minutes)』単位で保持されている」という事実を知らないからです。

画面で「2日(2d)」と見えていても、VBAの `Task.Predecessors` コレクションが返すラグは、実はカレンダーの稼働時間に換算された「分」の数値です。例えば、1日=8時間稼働のプロジェクトなら、2日=960分となります。これを無視して生データ(日数)をそのまま計算式に突っ込むと、スケジュールが大崩壊を起こします。

カレンダーの呪縛を解く鍵

Projectのラグタイムを制するには、以下の3ステップをマスターする必要があります。
1. 稼働時間(MinutesPerDay / MinutesPerWeek)の把握
2. 生データ(文字列や分)の安全なパース
3. 正確な時間単位(Hours)への一括変換ロジック

2. 【実践】日数から時間単位へ!ラグタイム一括変換マクロ

それでは、現在アクティブなプロジェクト内の全タスクをスキャンし、すべての先行タスクのラグタイムを「時間(Hour)」ベースで強制的に再計算・統一する実務コードを公開します。

開発タブのVBE(Visual Basic Editor)を開き、標準モジュールにペーストしてください。そのまま現場で動かせる実用コードです。

Sub OptimizeLagTime_To_Hours()
Dim t As Task
Dim predLink As TaskDependency
Dim projMinutesPerDay As Double
Dim currentLagMinutes As Long
Dim targetHours As Double
Dim msg As String

‘ エラーハンドリングの要:プロジェクトが空の場合のガード
On Error GoTo ErrorHandler
If ActiveProject.Tasks.Count = 0 Then
MsgBox “現在、タスクが登録されていません。”, vbExclamation, “処理中断”
Exit Sub
End If

‘ 【超重要】プロジェクト標準のカレンダーから「1日あたりの稼働分」を取得する
‘ これをサボると、8時間PRJと7.5時間PRJで計算が狂います。
projMinutesPerDay = ActiveProject.Calendar.Days(pjMonday).WorkingTimes(1).To / 60
‘ ※簡易的に 1日=480分 (8時間) 固定にする場合は以下のように書き換えてもOKですが、
‘ カレンダー連携を意識するのがプロの作法です。
If projMinutesPerDay <= 0 Then projMinutesPerDay = 480 ' フォールバック Dim updateCount As Long updateCount = 0 ' 全タスクを巡回するループ For Each t In ActiveProject.Tasks If Not t Is Nothing Then ' タスクが持つすべての先行タスク(依存関係)をチェック For Each predLink In t.Predecessors ' 現在のラグタイム(内部値は「分」で格納されている)を取得 currentLagMinutes = predLink.Lag ' 「分」を「時間(Hour)」に変換する ' 例: 960分 / (480分/日 8h?) -> ここでは厳密に「分から時間」へ換算
‘ 1時間 = 60分 なので、Lag(分) / 60 で時間が出ます。
targetHours = currentLagMinutes / 60

‘ 【実務的最適化】
‘ ここでは例として、「すべてのラグを『4時間』に統一する」あるいは
‘ 「日数で入っているものを時間単位の厳密な値に丸め直す」処理を行います。
‘ 今回は安全のため、現在の時間をそのまま「時間単位の文字列」として再設定します。

‘ ProjectのLagプロパティに文字列(例: “16h”)を代入すると、
‘ Projectエンジンが自動的にカレンダー解釈してくれます。
predLink.Lag = CStr(targetHours) & “h”

updateCount = updateCount + 1
Next predLink
End If
Next t

‘ 完了報告
MsgBox “ラグタイムの最適化が完了しました!” & vbCrLf & _
“処理した依存関係の数: ” & updateCount & ” 件”, vbInformation, “成功”

Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
End Sub

3. コードの心臓部を徹底解説

初心者から一歩抜け出すために、上記のコードで最も重要なポイントを3つに絞って解説します。

① `predLink.Lag` の正体は「分(Minutes)」

先ほども触れましたが、VBAから `predLink.Lag` を呼び出すと、返ってくる数値の単位は「分」です。画面で「1d(1日)」と表示されていても、返値は `480`(8時間稼働の場合)になります。
ここを「1日=1」と勘違いして計算してしまうのが、初心者が最も陥りやすい罠です。必ず `/ 60` を挟んで「時間」に直すか、Projectの仕様である `Str & “h”`(時間単位の文字列指定)を活用しましょう。

② カレンダーオブジェクトの非対称性への配慮

コード内で `ActiveProject.Calendar` を叩いています。MS Projectは曜日ごとに稼働時間が異なる設定(例:水曜日は午前のみ、など)が可能です。
プログラミングの現場では、マジックナンバー(いきなり `480` と書くなど)を避け、プロジェクトの設定値から動的に稼働時間を算出・逆算するのが、保守性の高い「美しいコード」の条件です。

③ 文字列による単位指定の妙

VBAからラグを設定する際、単に `predLink.Lag = 480` と数値だけを入れると、Projectはそれを「分」として解釈します。しかし、`”16h”` や `”2d”` のように単位付きの文字列を渡すと、Projectのスケジューリングエンジンが自動的にパースしてくれます。
これを利用すると、単位のブレによるバグを劇的に減らすことができます。

4. よくあるエラーと回避の知見

実務でこのコードや類似のロジックを動かす際、必ず遭遇する「壁」と、その回避策を授けます。

  • エラー:「このオブジェクトはプロパティまたはメソッドをサポートしていません」
  • 原因: 削除されたタスク(空のインデックス)や、サマリータスクに対して依存関係を操作しようとした場合に発生します。
  • 対策: `If Not t Is Nothing Then` のようなヌルチェックに加え、`If t.Summary = True Then`(サマリータスクならスキップ)といったガード節を必ず入れましょう。サマリータスクにラグは設定できません。
  • 「実行時エラー 11: ゼロで除算しました」
  • 原因: プロジェクトのカレンダー設定が破損している、あるいは稼働時間が「0分」に設定されている極端なケース。
  • 対策: コード内で行っているように、稼働時間が取得できなかった場合の「フォールバック(既定値の代入)」を必ず用意してください。

おわりに:ここをクリアすれば、Project VBAの基本はバッチリですよ!

お疲れ様でした!
「ラグタイム」という一見とっつきにくい概念も、内部データ構造(分単位での保持)とカレンダーの概念さえ理解してしまえば、VBAの強力な武器に早変わりします。

マクロの記録では絶対に辿り着けない、オブジェクトモデルの深い層を操作する感覚は掴めましたか?
この基礎さえあれば、WBSの自動生成から進捗率の連動、複雑な依存関係のバッチ処理まで、どんな巨大プロジェクトでもあなたの思い通りにコントロールできるようになります。

現場での自動化ライフを、心から応援しています。それでは、次のステージへ進みましょう!

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