本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBA×WMI:特定業務プロセスの生存監視とメモリ異常検知の自動化
【背景と目的】
基幹システムのフリーズや予期せぬ終了によるデータ損失を防ぐため、WMIを用いてプロセスの動作状況とメモリ使用量をリアルタイムで監視する仕組みを構築します。
【処理フロー図】
graph TD
A["開始"] --> B["WMIオブジェクトの初期化"]
B --> C["対象プロセスのクエリ実行"]
C --> D{"プロセスは存在するか?"}
D -- No --> E["異常検知アラート/ログ記録"]
D -- Yes --> F["メモリ使用量の取得"]
F --> G{"閾値を超過しているか?"}
G -- Yes --> H["警告フラグ設定"]
G -- No --> I["正常ステータス記録"]
H --> J["Excelシートへ一括書き出し"]
I --> J
J --> K["待機(Sleep)"]
K --> C
【実装:VBAコード】
Option Explicit
' 64bit/32bit両対応のSleep宣言
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
' 監視設定定数
Private Const TARGET_PROCESS As String = "Excel.exe" ' 監視対象プロセス名
Private Const MEM_THRESHOLD_MB As Double = 500 ' 異常検知メモリ閾値(MB)
Private Const INTERVAL_MS As Long = 5000 ' 監視間隔(ミリ秒)
Sub StartProcessMonitoring()
Dim objWMIService As Object
Dim colProcesses As Object
Dim objProcess As Object
Dim ws As Worksheet
Dim lastRow As Long
Dim results(1 To 1, 1 To 4) As Variant ' 高速化のため配列を使用
Set ws = ThisWorkbook.Sheets(1)
' 初期描画抑制
Application.ScreenUpdating = False
On Error Resume Next
' WMIサービスへの接続
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
On Error GoTo 0
If objWMIService Is Nothing Then
MsgBox "WMIの初期化に失敗しました。", vbCritical
Exit Sub
End If
Debug.Print "監視を開始します... (Ctrl+Pauseで停止)"
Do
' プロセス情報の取得(WQL)
Set colProcesses = objWMIService.ExecQuery _
("SELECT * FROM Win32_Process WHERE Name = '" & TARGET_PROCESS & "'")
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
If colProcesses.Count = 0 Then
' プロセスが見つからない場合
results(1, 1) = Now
results(1, 2) = TARGET_PROCESS
results(1, 3) = "未検出"
results(1, 4) = "CRITICAL: プロセスが停止しています"
ws.Cells(lastRow, 1).Resize(1, 4).Value = results
Else
For Each objProcess In colProcesses
Dim memUsage As Double
memUsage = Round(objProcess.WorkingSetSize / 1024 / 1024, 2) ' MB換算
results(1, 1) = Now
results(1, 2) = objProcess.Name & " (ID:" & objProcess.ProcessId & ")"
results(1, 3) = memUsage & " MB"
If memUsage > MEM_THRESHOLD_MB Then
results(1, 4) = "WARNING: メモリ使用量過多"
Else
results(1, 4) = "正常"
End If
' 配列からシートへ一括書き込み(高速化)
ws.Cells(lastRow, 1).Resize(1, 4).Value = results
lastRow = lastRow + 1
Next
End If
' バッファのクリアと待機
DoEvents
Sleep INTERVAL_MS
' 無限ループ対策(特定のセルが空でなければ継続など、運用に合わせて調整)
If ws.Range("Z1").Value = "STOP" Then Exit Do
Loop
Application.ScreenUpdating = True
MsgBox "監視を終了しました。", vbInformation
End Sub
【技術解説】
WMI (Windows Management Instrumentation): Windows OSの管理情報を取得する業界標準インターフェースです。
Win32_Processクラスを使用することで、実行中のプロセス名、ID、メモリ使用量(WorkingSetSize)などをSQLライクな構文(WQL)で抽出できます。PtrSafe Sleep: VBA標準の
Waitメソッドは1秒単位でしか制御できず、かつExcel全体をフリーズさせるため、Win32 APIのSleepを使用してミリ秒単位の制御とCPU負荷の抑制を行っています。配列による書き出し: ループ内で直接セルに書き込むのではなく、一旦配列(
results)に格納してからシートへ一括出力することで、画面更新負荷を最小化しています。
【注意点と運用】
参照設定不要:
GetObjectを使用する実行時バインディング(Late Binding)を採用しているため、配布時の参照設定トラブルを回避しています。無限ループの停止:
DoEventsを挟むことで実行中のExcel操作を可能にしていますが、強制終了用に「特定のセルにSTOPと入力されたら終了」などの脱出フラグを設けることが実務上不可欠です。権限: 他のユーザーが実行しているプロセスを詳細に監視する場合、管理者権限での実行が必要になるケースがあります。
【まとめ】
WMIを活用すれば、外部ツールなしでWindowsプロセスの死活監視が可能。
SleepAPIと配列処理の組み合わせにより、Excelのパフォーマンス低下を防ぐ。異常検知時のログ出力を自動化することで、システムトラブルの早期発見に貢献する。

コメント