こんにちは!Project VBAの世界へようこそ。
マクロの記録から一歩踏み出し、「もっと実務でバリバリ動く、本格的な自動化ツールを作りたい!」という熱意、すばらしいですね。
今回は、Project VBAにおける「リソースオブジェクトのメモリ管理と安定化」という、プログラミング中級者へのステップアップに欠かせない極意を伝授します。
「えっ、VBAってメモリ管理なんて意識しなきゃいけないの?」と思ったそこのあなた。
実は、MS Projectを相手に何百件、何千件ものリソース(人や機材)を操作する巨大なマクロを組むとき、このリソースの「お片付け(メモリ解放)」をサボると、Excelがフリーズしたり、突然マクロが強制終了する「恐怖のエラー」を引き起こす原因になります。
ここをクリアすれば、あなたの書くVBAコードはプロの領域に到達します。一緒に優しく、深く、学んでいきましょう!
—
なぜProject VBAでは「リソースの解放」が重要なのか?
MS Projectというソフトは、背後で巨大なデータベース(プロジェクトデータ)をガッチリと掴んでいます。
VBAから `ActiveProject.Resources` や `Resource` オブジェクトを呼び出すとき、あなたのパソコンのメモリ上には「Projectのデータを操作するための通路(参照)」が新しく作られます。
[VBAの変数] ──(参照)──> [MS Projectのリソースオブジェクト]
この通路、使い終わったらちゃんと「お片付け(=変数を `Nothing` にしてメモリを解放)」してあげないと、メモリのゴミ屋敷になってしまいます。特に、ループ処理の中で何度もリソースを呼び出すコードを書く場合、お片付けをしないとメモリがパンクしてしまいます。
—
現場で即役立つ!安全なリソース登録・割り当ての基本コード
それでは、実際に安全なリソースの登録と、使い終わったあとの確実なメモリ解放を行うコードを見てみましょう。
今回は、プロジェクトに新しいリソース(例:「シニアエンジニア」)を安全に登録し、綺麗に後始末をするサンプルコードです。
Sub RegisterResourceSafely()
‘ —————————————————————-
‘ 目的: 新規リソースを安全に登録し、メモリリークを防ぐプロの作法
‘ —————————————————————-
Dim targetProject As Project
Dim newResource As Resource
‘ 1. アクティブなプロジェクトを明示的に取得
Set targetProject = ActiveProject
On Error GoTo ErrorHandler ‘ エラー時のトラップを準備
‘ 2. すでに同じ名前のリソースがないか確認するなどの前処理(省略)
‘ 3. リソースの新規追加
‘ Resourcesコレクションに対してAddメソッドを実行します
Set newResource = targetProject.Resources.Add(Name:=”シニアエンジニア”)
‘ 4. リソースの詳細プロパティを設定
With newResource
.StandardRate = 5000 ‘ 標準単価(例: 5,000円/h)
.MaxUnits = 1 ‘ 最大稼働ユニット数 (100%)
.EmailAddress = “engineer@example.com”
End With
MsgBox “リソースの登録が完了しました!”, vbInformation, “成功”
CleanUp:
‘ ================================================================
‘ 【超重要】オブジェクト変数のメモリ解放(ライフサイクルの完結)
‘ ================================================================
‘ 使ったオブジェクトは必ずNothingを代入してメモリから消去します。
Set newResource = Nothing
Set targetProject = Nothing
Exit Sub
ErrorHandler:
‘ エラーが発生した場合はここにジャンプ
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “異常終了”
Resume CleanUp ‘ エラーが起きても必ずメモリ解放を通るようにする
End Sub
コードのここがポイント!
- `On Error GoTo ErrorHandler` と `CleanUp` ラベル
VBAで最も恐ろしいのは、途中でエラーが起きてプログラムが止まったとき、メモリを開放するコード(`Set newResource = Nothing`)がスキップされてしまうことです。この「どんな時でも必ず片付けをして終わる」仕組み(クリーンアップパターン)を組むのがプロの鉄則です。
- `Set 〇〇 = Nothing`
使い終わったオブジェクト変数に `Nothing` を入れることで、Windowsに「もうこのメモリ領域は使わないよ、返却するね」と伝えています。
—
陥りがちな罠:ループ処理でのメモリリーク
次によくあるのが、次のような「リソースの稼働率を一括調整する」ループ処理です。
❌ やってはいけないNGコード
Sub BadResourceLoop()
Dim r As Resource
‘ ループの中で毎回オブジェクトを取得し、解放していない!
For Each r In ActiveProject.Resources
If Not r Is Nothing Then
r.MaxUnits = 0.8 ‘ 稼働率を80%に一括変更
End If
‘ 次のループへ行くが、変数 r の参照が溜まり続けてメモリリークに!
Next r
End Sub
このようなコードを巨大なプロジェクトで回すと、処理がだんだん重くなり、最悪の場合はProjectが強制終了します。
⭕ 正しいプロの書き方
Sub GoodResourceLoop()
Dim targetProject As Project
Dim r As Resource
Set targetProject = ActiveProject
‘ コレクションを安全に回す
For Each r In targetProject.Resources
If Not r Is Nothing Then
r.MaxUnits = 0.8
End If
‘ ループの都度、変数をリフレッシュする意識を持つと完璧です
Next r
‘ 最後に大本のプロジェクトも解放
Set r = Nothing
Set targetProject = Nothing
MsgBox “すべてのリソースの稼働率調整が完了しました。”, vbInformation
End Sub
—
ここをクリアすれば、Project VBAの基本はバッチリですよ!
お疲れ様でした!
「オブジェクトを変数にセットしたら、最後は必ず `Nothing` で解放する」
「エラーが起きても必ずお片付けのルートを通るようにする(`On Error GoTo` の活用)」
この2つを意識するだけで、あなたの書くProjectマクロは見違えるほど安定し、長時間の連続稼働にも耐えられる強靭なツールへと生まれ変わります。
マクロの記録の先にある、美しく堅牢なVBAの世界へようこそ。
明日からの実務での自動化ビルド、ぜひこの知見を活かして無双してくださいね!応援しています!
