【テクニカル・上級編】VBAを用いた「制約条件の可視化」:ガントチャート上のアイコン制御と色分け – Project VBA解析バイブル

スポンサーリンク

現場の制約を「可視化」せよ:VBAによるガントチャート・インジケーター制御の極意

プロジェクト管理において、ASAP(可能な限り早く)やALAP(可能な限り遅く)、あるいは固定日付制約といった「制約条件」は、スケジューリングの生命線だ。しかし、これらをExcelのガントチャート上で単なるセル値として放置してはいないか?

真のエンジニアは、データを目で追わない。「状態」を「形状(UI)」へ即座に変換し、異常値を直感的に排除する。 今回は、VBAを用いてガントバーの動的制御とインジケーター配置を行う、システムアーキテクト視点の実装論を伝授する。

—

1. 制約条件の抽象化とイベント駆動の罠

多くの稚拙な実装は、セルが更新されるたびにシート全体を再描画するような、計算負荷の塊のようなコードを書く。これを解決するには、`Worksheet_Change`イベントの厳密なフィルタリングと、`Application.ScreenUpdating`の適切な制御が不可欠だ。

制約条件の可視化において、メモリリークを避けるための鉄則は「オブジェクトの完全解放」と「描画スタックの管理」にある。

—

2. 実装の核心:Shapeオブジェクトによるインジケーター制御

ガントバーの色分けだけでなく、特定の制約(例:日付固定)がある場合にのみ「警告アイコン」をオーバーレイさせる手法が、現場の運用ミスを激減させる。

Option Explicit

‘ メモリ最適化のための定数定義
Private Const SHAPE_PREFIX As String = “ConstraintIcon_”

Public Sub UpdateGanttUI(ByVal TargetRow As Long, ByVal ConstraintType As String)
Dim ws As Worksheet
Set ws = ActiveSheet

‘ 描画の極限高速化
Application.ScreenUpdating = False

‘ 既存のインジケーターをクリーンアップ(メモリリーク防止)
RemoveExistingIcons ws, TargetRow

‘ 制約条件に基づく動的生成
If ConstraintType <> “” Then
AddConstraintIcon ws, TargetRow, ConstraintType
End If

Application.ScreenUpdating = True
End Sub

Private Sub AddConstraintIcon(ws As Worksheet, rowIdx As Long, cType As String)
Dim shp As Shape
Dim cell As Range
Set cell = ws.Cells(rowIdx, 5) ‘ ガントバーの開始位置列

‘ Shapeの生成とプロパティ設定
Set shp = ws.Shapes.AddShape(msoShapeWarningSign, cell.Left, cell.Top, 15, 15)
With shp
.Name = SHAPE_PREFIX & rowIdx
.Fill.ForeColor.RGB = IIf(cType = “Fixed”, RGB(255, 0, 0), RGB(255, 165, 0))
.OnAction = “ShowConstraintDetail” ‘ コンテキストメニュー的な挙動の実装
End With
End Sub

—

3. レガシー環境でのパフォーマンスチューニング

Windows APIを活用することで、VBAの標準機能では到達できないUI制御が可能になる。例えば、`LockWindowUpdate`を呼び出すことで、複雑な再描画プロセスをユーザーの目から完全に隠蔽し、画面のチラつきを皆無にできる。

If VBA7 Then
Private Declare PtrSafe Function LockWindowUpdate Lib “user32” (ByVal hwndLock As LongPtr) As Long
Else
Private Declare Function LockWindowUpdate Lib “user32” (ByVal hwndLock As Long) As Long
End If

‘ 使用例:描画更新を物理的にフリーズさせる
‘ Call LockWindowUpdate(Application.hWnd)
‘ … 高負荷な処理 …
‘ Call LockWindowUpdate(0)

このAPI呼び出しは、大規模なプロジェクトデータ(数千行規模)を扱う際、VBAの描画エンジンが悲鳴を上げるのを防ぐための最終防衛ラインだ。

—

4. アーキテクトからの提言:保守性の担保

この実装において最も避けるべきは、「どのShapeがどのタスクに属しているか」という依存関係の崩壊だ。

1. 名前付けの正規化: `SHAPE_PREFIX & RowID` のような命名規則を厳格化し、`Collection`や`Dictionary`で管理する習慣をつけろ。
2. イベントの疎結合化: 制約条件の算出ロジックと、UI描画ロジックを分離すること。計算エンジンはクラスモジュールへ、描画処理は標準モジュールへ追い出せ。
3. オブジェクトの解放: ループ処理内で `Set shp = Nothing` を忘れるな。VBAのガベージコレクションは頼りにならない。

結びに

制約条件の可視化は、単なる「見栄え」の問題ではない。「エンジニアが抱える認知負荷をどれだけUI側へオフロードできるか」という、システムデザインそのものだ。

ガントチャートのバーが赤く染まり、警告アイコンが点滅する。その瞬間、システムは単なる計算機から、プロジェクトの「守護者」へと昇華する。コードを信じろ。そして、最も無駄のない論理を実装せよ。

次回の講義では、この制約条件を外部API(Project ServerやREST API)と同期させる、非同期通信の極意について解説する予定だ。準備はいいか。

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