こんにちは!プロジェクトマネジメントの現場で、日々MS Projectと格闘お疲れ様です。
「マクロの記録」ボタンを押してVBAを覗いてみたものの、Excelとは一味違う独特のオブジェクトモデルに戸惑っていませんか?
「特定の条件に合うタスクだけをパッと画面に出したいのに、毎回手動でフィルターを設定するのは面倒……」
「VBAでスマートに条件を指定して、一発で絞り込みたい!」
今回は、そんな現場の悩みを鮮やかに解決する「ProjectのフィルターをVBAで動的作成する極意」を伝授します。ここをクリアすれば、あなたも脱・初学者!Project VBAの基本と、オブジェクトを操る心地よさがグッと身につきますよ。
—
1. MS Project VBAの「フィルター」の正体を知る
まず、Excel VBAの感覚のまま突っ走ると、ここで盛大に躓きます。Excelのオートフィルターは「セル範囲の簡易的な絞り込み」ですが、MS Projectのフィルターは「プロジェクトデータベースに対するクエリ定義」そのものです。
Projectには、あらかじめ用意された「組み込みフィルター」の他に、ユーザーが独自に定義する「カスタムフィルター」が存在します。
VBAから動的にフィルターをかける場合の流れはこうです。
1. 既存のカスタムフィルターを上書き(または新規作成)する:`FilterEdit`メソッド
2. 作ったフィルターを現在のビューに適用する:`FilterApply`メソッド
この「定義する」と「適用する」の2ステップを頭に叩き込んでおくことが、Project VBAを制する第一歩です。
—
2. 現場で即戦力!動的フィルター作成マクロの全貌
それでは早速、実際のコードを見てみましょう。
今回は、「まだ完了しておらず(%=100ではない)、かつ、特定の担当者(リソース名)がアサインされているタスク」を動的に抽出し、画面に表示するマクロを作成します。
Sub ApplyDynamicTaskFilter()
Dim targetResource As String
Dim filterName As String
‘ 1. ユーザーに担当者名を入力してもらう(動的要素)
targetResource = InputBox(“抽出したい担当者の名前を入力してください:”, “動的フィルター検索”, “山田 太郎”)
‘ キャンセルされた場合は処理を中断
If targetResource = “” Then Exit Sub
‘ フィルターの名前(ユニークな名称にする)
filterName = “temp_DynamicFilter”
p
On Error GoTo ErrorHandler
‘ 2. 画面の更新を一時停止してパフォーマンスを爆上げする(超重要テクニック)
Application.ScreenUpdating = False
‘ 3. FilterEditメソッドでフィルターを動的定義する
‘ 引数が非常に多いため、名前付き引数(:=)を使って意図を明確にします。
FilterEdit _
Name:=filterName, _
TaskFilter:=True, _
Create:=True, _
OverwriteExisting:=True, _
ShowInMenu:=False, _
Operation:=”And”, _
FieldName:=Array(“%=100”, “リソース名”), _
Test:=”equals”, _
Value:=Array(“いいえ”, targetResource)
‘ 4. 定義したフィルターを現在のタスクビューに適用する
FilterApply Name:=filterName, Highlight:=False
‘ 後片付け:画面更新を再開
Application.ScreenUpdating = True
MsgBox “「 ” & targetResource & ” 」の未完了タスクを抽出しました。”, vbInformation, “完了”
Exit Sub
ErrorHandler:
Application.ScreenUpdating = True
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “エラー”
End Sub
—
3. コードのキモを優しく解説!
初心者の方にとって、上記のコード、特に `FilterEdit` の部分は呪文のように見えるかもしれません。でも大丈夫、一つずつ分解すれば怖くありません。
① 配列(Array)を使った複数条件の指定
FieldName:=Array(“%=100”, “リソース名”), _
Test:==”equals”, _
Value:=Array(“いいえ”, targetResource)
ここが今回のハイライトです!`FilterEdit` では、`Array` 関数を使うことで、複数の条件(AND / OR)を同時に定義できます。
- 1つ目の条件:`%=100` (百分率完了)が `いいえ`(完了していない)
- 2つ目の条件:`リソース名` が `targetResource`(InputBoxで入力した名前)に等しい (`equals`)
これらが `Operation:=”And”` によって結合され、「未完了かつ、指定した担当者のタスク」という強力なフィルターが爆誕します。
② プロフェッショナルな作法:`ScreenUpdating = False`
MS Projectは、VBAからビューやフィルター操作を行うと、画面の再描画(画面のちらつき)が発生して処理が重くなります。コードの前後で `ScreenUpdating` を制御するのは、大規模なプロジェクトを扱うシニアエンジニアの常識です。ぜひ真似してくださいね。
—
4. 陥りやすい罠とエラー回避の知見
実務でこのコードを組み込む際、多くの人が以下の「落とし穴」にハマります。
1. フィールド名のローカライズ問題
MS Projectは、OSやOfficeの言語設定によってフィールド名が日本語になったり英語になったりします(例:日本語版の「リソース名」は、英語版では「Resource Names」になります)。
汎用的なツールを作る場合は、フィールド名を生の文字列で指定するのではなく、PjField列挙体(例: `pjTaskResourceNames`)を使うのが真のプロの作法です。(今回は直感的に分かりやすい文字列指定にしていますが、多言語対応が必要な現場では注意してください!)
2. フィルターのゴミ問題
`Create:=True` と `OverwriteExisting:=True` をセットにしておかないと、「すでに同じ名前のフィルターが存在します」というエラーでマクロがクラッシュします。必ず上書き設定を有効にしましょう。
—
まとめ:ここをクリアすればProject VBAは怖くない!
今回は、`FilterEdit` と `FilterApply` を駆使して、ユーザーの入力に応じた動的フィルターを作成する手法を解説しました。
- 「定義」 (`FilterEdit`) と「適用」 (`FilterApply`) の2ステップを理解する
- `Array` を使って複数条件をスマートに組み合わせる
- 画面更新の抑制でパフォーマンスに配慮する
この基本さえ押さえておけば、複雑なWBSの中から「今、自分が本当に見るべきタスク」をワンクリックで引き出す神マクロが作れるようになります。
日々の定型作業を自动化して、空いた時間をプロジェクトの本当のマネジメント(リスク管理やメンバーとのコミュニケーション)に使いましょう!
あなたのProject VBAライフが素晴らしいものになるよう、応援しています。それではまた!
