【テクニカル・上級編】【初心者向け】タスクの「名前」をキーにして、特定のタスクを検索・取得する高速なFindメソッド活用法 – Project VBA解析バイブル

スポンサーリンク

Project VBAを掌握せよ:タスク検索の「正道」とメモリの深淵

VBAでProjectのタスクを操作する際、多くの開発者が陥る罠がある。それは「ループによる全走査」だ。`For Each`で数千のタスクを回し、名前を比較する。小規模なスケジュールならそれで十分だろう。だが、数万行規模のWBSを扱うエンタープライズ環境において、それは「死」を意味する。

今回は、Project VBAにおけるタスク検索の最適解、すなわち`Find`メソッドを使いこなし、メモリの断片化を回避しつつ、高速にオブジェクトを特定する技術を伝授する。

1. なぜ「Findメソッド」なのか:O(N)からの脱却

`Tasks.Item(“タスク名”)`という直感的な参照は、裏側で毎回インデックスの検索が走る。繰り返せばパフォーマンスは崩壊する。ここで活用すべきは、Projectの`Task`オブジェクトが持つネイティブな`Find`メソッドだ。

このメソッドは、Projectの内部エンジンが管理するインデックスを直接叩くため、手動でループを回すよりも桁違いに速い。

高速検索の実装例

‘ 伝説的なチーフアーキテクトが推奨する、高速タスク検索関数
Public Function FindTaskByName(ByVal taskName As String) As Task
Dim t As Task

‘ ActiveProject.Tasks.Find は検索条件に合致する最初のタスクを返す
‘ 速度の要諦は、無駄なオブジェクト生成を避けることにある
Set t = ActiveProject.Tasks.Find(Field:=”Name”, Value:=taskName)

If Not t Is Nothing Then
Set FindTaskByName = t
End If

‘ メモリの解放:VBAにおいてSet Nothingは必須の作法ではないが、
‘ オブジェクトの参照カウントを意識する姿勢が、大規模開発ではバグを未然に防ぐ
Set t = Nothing
End Function

2. メモリの深淵:オブジェクトのライフサイクルと解放の真実

VBAはガベージコレクションを備えていない。オブジェクト参照を放置することは、メモリリークの温床であり、特に`Project.Application`を外部から制御するようなアーキテクチャでは、ExcelやProjectのゾンビプロセスを生成する原因となる。

安定性を高めるための「明示的解放」

大量のタスクを更新するループ処理では、必ず参照変数を初期化せよ。

Sub UpdateTaskDependencies()
Dim t As Task
Dim targetTask As Task

‘ カレントタスクを走査する際、参照カウントに注意を払う
For Each t In ActiveProject.Tasks
If Not t Is Nothing Then
‘ プロパティ操作後に即座に参照を解除する意識を持つ
‘ これにより、大規模なメモリリークを未然に防ぐ
t.Predecessors = “1,2,3”
End If
Next t

‘ スコープを抜ける前に明示的に解放
Set t = Nothing
End Sub

3. レガシー環境への配慮:Windows APIとの連携

Project VBAの限界に直面したとき、Windows APIの呼び出しは、最後の切り札だ。例えば、大規模なタスク処理中に画面の描画を停止させ、パフォーマンスを極限まで引き上げる手法がある。

これは`LockWindowUpdate` APIを使用する手法だが、これをVBAで制御することで、ユーザー体験(UIのチラつき防止)と処理速度の両立を図る。

‘ API宣言(モジュールレベルで記述)
If VBA7 Then
Private Declare PtrSafe Function LockWindowUpdate Lib “user32” (ByVal hwndLock As LongPtr) As LongPtr
Else
Private Declare Function LockWindowUpdate Lib “user32” (ByVal hwndLock As Long) As Long
End If

‘ 処理開始時にLockWindowUpdate(Application.hWnd)を呼び出し、
‘ 終了時にLockWindowUpdate(0)で解放する。
‘ これにより、再描画のオーバーヘッドが劇的に減少する。

4. 最後に:アーキテクトからの助言

技術とは「動くこと」がスタートラインであり、「いかに美しく、いかに堅牢に、いかに予測可能であるか」がゴールだ。

  • 名前をキーにするな: 可能な限り `UniqueID` をキーにせよ。名前は人間が読むためのメタデータであり、システムが識別するためのIDではない。
  • 例外処理は必須: `Find`がNothingを返すケースを常に想定せよ。`If Not t Is Nothing`を省略するコードは、プロの書くものではない。
  • アーキテクチャを見据えよ: プロジェクト単体で完結するVBAを書くのではなく、将来的に外部DLLや.NETコンポーネントへ移植可能な抽象度を保つことが、真の技術的負債を防ぐ唯一の道だ。

コードは嘘をつかない。君が書いたその一行が、数年後の誰かの運命を決定するかもしれない。その気概を持って、Projectを掌握せよ。

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