<p><style_prompt: technical_blog_expert="">
本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</style_prompt:></p>
<h1 class="wp-block-heading">VBA×WMI:業務アプリのプロセス監視とパフォーマンス異常検知の自動化</h1>
<h3 class="wp-block-heading">【背景と目的】</h3>
<p>複数の業務システムを並行稼働させる環境で、特定のアプリがフリーズしたり、メモリを異常消費してPC全体が重くなる課題を、VBAからWMIを叩いて自動解決します。</p>
<p>実務では「バッチ処理中のバックグラウンド落ち」や「メモリリークによるシステム遅延」が頻発しますが、これらをいちいちタスクマネージャーで確認するのは非効率です。本ツールは、VBAのみでプロセスの死活監視とリソース使用状況の可視化を実現します。</p>
<h3 class="wp-block-heading">【処理フロー図】</h3>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["監視開始"] --> B["WMIサービスへ接続"]
B --> C["Win32_Processクラスのクエリ実行"]
C --> D{"対象プロセスは存在するか?"}
D -- No --> E["プロセス停止アラート"]
D -- Yes --> F["メモリ/CPU使用率の算出"]
F --> G{"閾値を超過しているか?"}
G -- Yes --> H["異常検知アラート/ログ出力"]
G -- No --> I["正常終了"]
</pre></div>
<h3 class="wp-block-heading">【実装:VBAコード】</h3>
<p>標準モジュールに以下のコードを貼り付けてください。Win32 APIによる待機処理を含み、64bit/32bit両環境に対応しています。</p>
<pre data-enlighter-language="generic">Option Explicit
' 64bit環境を考慮したSleep関数の宣言
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
''' <summary>
''' 指定したプロセスのリソース状況を監視し、異常を検知する
''' </summary>
Public Sub MonitorProcessAnomaly()
Dim wmiService As Object
Dim processes As Object
Dim process As Object
Dim targetName As String
Dim memThresholdMB As Double
Dim isFound As Boolean
Dim msg As String
' --- 設定値 ---
targetName = "EXCEL.EXE" ' 監視対象のプロセス名
memThresholdMB = 500 ' 異常とみなすメモリ閾値 (MB)
' --------------
On Error GoTo ErrorHandler
' 高速化処理
Application.ScreenUpdating = False
' WMIサービスへの接続(遅延バインディング)
Set wmiService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
' プロセス情報の取得
Set processes = wmiService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & targetName & "'")
isFound = False
For Each process In processes
isFound = True
' ワーキングセットサイズ(物理メモリ使用量)をMB換算
Dim memUsage As Double
memUsage = Round(process.WorkingSetSize / 1024 / 1024, 2)
' ログ用メッセージ構築
msg = "Process: " & process.Name & " (ID: " & process.ProcessId & ")" & vbCrLf & _
"Memory Usage: " & memUsage & " MB"
' 異常検知ロジック
If memUsage > memThresholdMB Then
MsgBox "【警告】プロセス異常検知" & vbCrLf & vbCrLf & _
msg & vbCrLf & "閾値(" & memThresholdMB & "MB)を超過しています。", vbCritical
Else
Debug.Print "正常稼働中: " & msg
End If
Next process
If Not isFound Then
MsgBox "対象プロセス '" & targetName & "' が起動していません。", vbExclamation
End If
CleanUp:
Set processes = Nothing
Set wmiService = Nothing
Application.ScreenUpdating = True
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
</pre>
<h3 class="wp-block-heading">【技術解説】</h3>
<ol class="wp-block-list">
<li><p><strong>WMI (Windows Management Instrumentation) の活用</strong>
<code>Win32_Process</code> クラスを使用することで、タスクマネージャーに表示される情報をプログラムから取得できます。<code>WorkingSetSize</code> プロパティはプロセスが物理メモリをどれだけ占有しているかを示します。</p></li>
<li><p><strong>遅延バインディング (Late Binding)</strong>
<code>CreateObject</code> や <code>GetObject</code> を使用することで、参照設定(Microsoft WMI Scripting V1.x Library)を不要にしています。これにより、他ユーザーのPCでも環境設定なしで動作します。</p></li>
<li><p><strong>PtrSafe 宣言</strong>
<code>#If VBA7</code> 定数を使用し、Excel 2010以降の64bit版と旧来の32bit版の両方で動作する互換性を担保しています。</p></li>
<li><p><strong>リソース負荷の軽減</strong>
<code>ExecQuery</code> で最初から <code>WHERE</code> 句を使いフィルタリングすることで、全プロセスをループ処理する無駄を省き、実行速度を向上させています。</p></li>
</ol>
<h3 class="wp-block-heading">【注意点と運用】</h3>
<ul class="wp-block-list">
<li><p><strong>WMIの権限</strong>: 管理者権限が必要なプロセス情報は取得できない場合があります。標準的なユーザー権限で動作するアプリであれば問題ありません。</p></li>
<li><p><strong>サンプリング間隔</strong>: ループ内で <code>Sleep</code> を入れずに監視し続けると、VBA自体がCPU負荷を上げてしまいます。タイマー処理や、特定の処理の前後でスポット的に呼び出す運用が推奨されます。</p></li>
<li><p><strong>メモリ単位</strong>: WMIから返される <code>WorkingSetSize</code> は「バイト単位」です。人間が読みやすいよう 1024^2 で割って MB 単位に変換する必要があります。</p></li>
</ul>
<h3 class="wp-block-heading">【まとめ】</h3>
<ol class="wp-block-list">
<li><p><strong>外部参照なしで完結</strong>: WMIを利用すれば、追加ライブラリなしで高度なシステム監視が可能。</p></li>
<li><p><strong>異常の早期発見</strong>: メモリ使用量や起動状態を自動監視し、サイレント・フリーズによる業務停止を防止。</p></li>
<li><p><strong>ポータビリティ</strong>: <code>PtrSafe</code> 対応により、古い端末から最新の64bit環境まで使い回せるツールとして運用可能。</p></li>
</ol>
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBA×WMI:業務アプリのプロセス監視とパフォーマンス異常検知の自動化
【背景と目的】
複数の業務システムを並行稼働させる環境で、特定のアプリがフリーズしたり、メモリを異常消費してPC全体が重くなる課題を、VBAからWMIを叩いて自動解決します。
実務では「バッチ処理中のバックグラウンド落ち」や「メモリリークによるシステム遅延」が頻発しますが、これらをいちいちタスクマネージャーで確認するのは非効率です。本ツールは、VBAのみでプロセスの死活監視とリソース使用状況の可視化を実現します。
【処理フロー図】
graph TD
A["監視開始"] --> B["WMIサービスへ接続"]
B --> C["Win32_Processクラスのクエリ実行"]
C --> D{"対象プロセスは存在するか?"}
D -- No --> E["プロセス停止アラート"]
D -- Yes --> F["メモリ/CPU使用率の算出"]
F --> G{"閾値を超過しているか?"}
G -- Yes --> H["異常検知アラート/ログ出力"]
G -- No --> I["正常終了"]
【実装:VBAコード】
標準モジュールに以下のコードを貼り付けてください。Win32 APIによる待機処理を含み、64bit/32bit両環境に対応しています。
Option Explicit
' 64bit環境を考慮したSleep関数の宣言
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
''' <summary>
''' 指定したプロセスのリソース状況を監視し、異常を検知する
''' </summary>
Public Sub MonitorProcessAnomaly()
Dim wmiService As Object
Dim processes As Object
Dim process As Object
Dim targetName As String
Dim memThresholdMB As Double
Dim isFound As Boolean
Dim msg As String
' --- 設定値 ---
targetName = "EXCEL.EXE" ' 監視対象のプロセス名
memThresholdMB = 500 ' 異常とみなすメモリ閾値 (MB)
' --------------
On Error GoTo ErrorHandler
' 高速化処理
Application.ScreenUpdating = False
' WMIサービスへの接続(遅延バインディング)
Set wmiService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
' プロセス情報の取得
Set processes = wmiService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & targetName & "'")
isFound = False
For Each process In processes
isFound = True
' ワーキングセットサイズ(物理メモリ使用量)をMB換算
Dim memUsage As Double
memUsage = Round(process.WorkingSetSize / 1024 / 1024, 2)
' ログ用メッセージ構築
msg = "Process: " & process.Name & " (ID: " & process.ProcessId & ")" & vbCrLf & _
"Memory Usage: " & memUsage & " MB"
' 異常検知ロジック
If memUsage > memThresholdMB Then
MsgBox "【警告】プロセス異常検知" & vbCrLf & vbCrLf & _
msg & vbCrLf & "閾値(" & memThresholdMB & "MB)を超過しています。", vbCritical
Else
Debug.Print "正常稼働中: " & msg
End If
Next process
If Not isFound Then
MsgBox "対象プロセス '" & targetName & "' が起動していません。", vbExclamation
End If
CleanUp:
Set processes = Nothing
Set wmiService = Nothing
Application.ScreenUpdating = True
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
【技術解説】
WMI (Windows Management Instrumentation) の活用
Win32_Process クラスを使用することで、タスクマネージャーに表示される情報をプログラムから取得できます。WorkingSetSize プロパティはプロセスが物理メモリをどれだけ占有しているかを示します。
遅延バインディング (Late Binding)
CreateObject や GetObject を使用することで、参照設定(Microsoft WMI Scripting V1.x Library)を不要にしています。これにより、他ユーザーのPCでも環境設定なしで動作します。
PtrSafe 宣言
#If VBA7 定数を使用し、Excel 2010以降の64bit版と旧来の32bit版の両方で動作する互換性を担保しています。
リソース負荷の軽減
ExecQuery で最初から WHERE 句を使いフィルタリングすることで、全プロセスをループ処理する無駄を省き、実行速度を向上させています。
【注意点と運用】
WMIの権限: 管理者権限が必要なプロセス情報は取得できない場合があります。標準的なユーザー権限で動作するアプリであれば問題ありません。
サンプリング間隔: ループ内で Sleep を入れずに監視し続けると、VBA自体がCPU負荷を上げてしまいます。タイマー処理や、特定の処理の前後でスポット的に呼び出す運用が推奨されます。
メモリ単位: WMIから返される WorkingSetSize は「バイト単位」です。人間が読みやすいよう 1024^2 で割って MB 単位に変換する必要があります。
【まとめ】
外部参照なしで完結: WMIを利用すれば、追加ライブラリなしで高度なシステム監視が可能。
異常の早期発見: メモリ使用量や起動状態を自動監視し、サイレント・フリーズによる業務停止を防止。
ポータビリティ: PtrSafe 対応により、古い端末から最新の64bit環境まで使い回せるツールとして運用可能。
ライセンス:本記事のテキスト/コードは特記なき限り
CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
コメント