プロジェクトを死なせない「ALAP」の極意:VBAで実現する納期逆算型スケジューリングの設計思想
世の中にはびこる「とりあえず動くVBA」は、たいていプロジェクトの後半で破綻する。特にスケジュール計算エンジンを自作する場合、場当たり的なループ処理はデータ整合性を破壊する爆弾だ。
今回は、Project VBAの核心である「ALAP(As Late As Possible:可能な限り遅く)」制約を攻略する。納期から逆算するロジックをどう堅牢に組み込むか。そのアーキテクチャを伝授しよう。
—
1. なぜ「前向き計算」ではいけないのか
多くの開発者は、開始日から終了日を求める(ASAP)順方向計算でツールを作る。だが、ビジネスの現場で真に価値があるのは「納期から逆算する(ALAP)」ロジックだ。
「いつまでに始めれば納期に間に合うか」を算出できないツールは、単なる表計算に過ぎない。ALAP制約を実装することで、タスクの「猶予期間(スラック)」が明確になり、ボトルネックを可視化できる。これをVBAで実装する際、最も避けるべきは「ワークシート上のセルを直接叩き続ける」ことだ。
2. 堅牢な設計:データ構造の抽象化
VBAで複雑なスケジュールを組むなら、「計算モデル(メモリ上の配列/クラス)」と「出力先(Excelシート)」を完全に分離せよ。
セルに計算結果を書き込みながら次のタスクを計算してはならない。計算の途中で再計算イベントが走り、パフォーマンスが著しく低下する上に、循環参照や予期せぬエラーの温床になる。
設計の鉄則
1. データ抽出: 全タスクを一度メモリ(二次元配列)に読み込む。
2. 逆算エンジン: メモリ上で計算を完結させる。
3. 一括出力: 計算結果をシートに一括転記する。
—
3. 実装:ALAP計算エンジンのコアコード
以下は、タスクの納期(Deadline)を起点に、先行タスクの開始日を逆算するプロダクション品質のロジックだ。
‘ ALAP計算エンジン:納期逆算ロジック
‘ 依存関係を考慮し、再帰的またはトポロジカルソート済みリストを逆順に処理する
Public Sub CalculateALAPSchedule(ByRef taskData As Variant)
‘ taskData: 0:ID, 1:Duration, 2:Deadline, 3:CalcStart, 4:CalcFinish
Dim i As Long
‘ 逆順ループで逆算を行う(後工程から前工程へ)
For i = UBound(taskData, 1) To LBound(taskData, 1) Step -1
‘ 終了日(CalcFinish)の初期値は納期(Deadline)
taskData(i, 4) = taskData(i, 2)
‘ 開始日 = 終了日 – 工数
‘ ※週末や祝日を除外する場合は、ここにカレンダー制御関数を噛ませる
taskData(i, 3) = DateAdd(“d”, -taskData(i, 1), taskData(i, 4))
‘ 後続タスクが存在する場合、その開始日を自身の終了日として制約を伝播させる
‘ ここでは簡易的に直前のタスクを後続と見なすロジック
If i < UBound(taskData, 1) Then
taskData(i, 4) = taskData(i + 1, 3)
taskData(i, 3) = DateAdd("d", -taskData(i, 1), taskData(i, 4))
End If
Next i
End Sub
このコードのポイント
- 非依存型設計: `DateAdd`関数をカレンダー判定関数に差し替えるだけで、休日補正対応に即座に拡張できる。
- メモリ完結: シートアクセスを最小化しているため、数千行のタスクでも瞬時に計算が終わる。
—
4. 運用上の注意点:データベース連携と同期
VBAツールが「個人のPCで完結するおもちゃ」で終わらないためには、データソースの管理が重要だ。
- ExcelをDB代わりにするな: 複数人での同時編集は、ファイル破損の引き金になる。Excelはあくまで「UI」であり、データはSharePoint上のリストやSQL Serverから取得・更新するアーキテクチャを推奨する。
- バリデーションの徹底: 納期が先行タスクの終了日より早いなど、論理的に矛盾するデータ(制約違反)を投入された際、計算エンジンが無限ループに陥らないよう、必ず事前にデータ整合性チェックを通すこと。
—
5. 最後に:エンジニアとしての矜持
ツールを作る目的は、単に計算を自動化することではない。「納期までに何をするべきか」という問いに対し、根拠あるデータで即座に答えを出すことだ。
ALAP制約を理解し、計算エンジンを制御下に置くことは、プロジェクトの舵取りを握ることに等しい。このコードをベースに、君自身の業務のボトルネックを特定し、排除してほしい。
もしコードが期待通りに動かないとしたら、それはエンジンの問題ではない。君が定義した「タスクの依存関係」というビジネスルールそのものに欠陥がある証拠だ。その時こそ、エンジニアとしての真価が問われる。
さあ、コードを書こう。そして、納期に追われる側から、スケジュールを支配する側へと回るのだ。
