<p><style_prompt></style_prompt></p>
<ul class="wp-block-list">
<li><p>専門用語を適切に用い、実務に即した具体的で無駄のない解説。</p></li>
<li><p>コード解説は構造的かつ論理的に行い、保守性を重視。</p></li>
<li><p>Win32 API使用時は必ずPtrSafe宣言を含め、64bit/32bit両対応を保証。</p></li>
<li><p>ユーザーの「今すぐ使いたい」に応えつつ、技術的背景も補完。
</p></li>
</ul>
<p>本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">VBA×WMIによるWindowsプロセス監視:業務停止を防ぐ異常検知の自動化</h1>
<h2 class="wp-block-heading">【背景と目的】</h2>
<p>業務アプリのハングアップや特定プロセスの異常なメモリ消費を、VBAでリアルタイムに監視。システム遅延による業務停滞や予期せぬエラーを早期に検知・記録します。</p>
<h2 class="wp-block-heading">【処理フロー図】</h2>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["開始"] --> B["WMIサービスへ接続"]
B --> C["Win32_Processから情報を取得"]
C --> D{"閾値チェック"}
D -->|異常あり| E["Excelシートへログ出力"]
D -->|正常| F["次回の実行を待機"]
E --> F
F --> G["終了判断"]
G -->|継続| B
G -->|停止| H["終了"]
</pre></div>
<h2 class="wp-block-heading">【実装:VBAコード】</h2>
<pre data-enlighter-language="generic">Option Explicit
' 64bit/32bit両対応の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>
''' WMIを利用したプロセス監視および異常検知メインルーチン
''' </summary>
Public Sub MonitorProcesses()
Dim objWMIService As Object
Dim colProcesses As Object
Dim objProcess As Object
Dim ws As Worksheet
Dim lastRow As Long
Dim thresholdMemory As Double
' --- 設定値 ---
thresholdMemory = 500 * 1024 * 1024 ' 閾値:500MB (バイト単位)
Set ws = ThisWorkbook.Sheets(1)
' 高速化設定
On Error GoTo ErrorHandler
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' WMIサービスへの接続(レイトバインドで参照設定不要)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
' 見出しの設定
ws.Cells.Clear
ws.Range("A1:E1").Value = Array("取得日時", "プロセス名", "PID", "メモリ使用量(MB)", "判定")
Do
' プロセス一覧の取得
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objProcess In colProcesses
' メモリ使用量(WorkingSetSize)のチェック
Dim memSizeMB As Double
memSizeMB = Round(CDbl(objProcess.WorkingSetSize) / 1024 / 1024, 2)
' 異常(閾値超過)または特定の重要プロセスを監視する場合の条件分岐
If memSizeMB > (thresholdMemory / 1024 / 1024) Then
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
' 配列を介さず直接書き込むが、頻度を抑える設計
ws.Cells(lastRow, 1).Value = Now
ws.Cells(lastRow, 2).Value = objProcess.Name
ws.Cells(lastRow, 3).Value = objProcess.ProcessId
ws.Cells(lastRow, 4).Value = memSizeMB
ws.Cells(lastRow, 5).Value = "MEMORY ALERT"
ws.Cells(lastRow, 5).Font.Color = vbRed
End If
Next
' イベント待機(CPU負荷軽減のため5秒スリープ)
DoEvents
Sleep 5000
' 連続稼働させる場合はループ、デモ用に1回で抜ける場合は以下をコメントアウト
' Exit Do
Loop
CleanUp:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
</pre>
<h2 class="wp-block-heading">【技術解説】</h2>
<ol class="wp-block-list">
<li><p><strong>WMI (Windows Management Instrumentation)</strong>:
Windowsの管理情報を取得するための標準インターフェースです。<code>Win32_Process</code> クラスを使用することで、タスクマネージャーに表示されるプロセスの詳細情報をSQLライクなクエリで取得できます。</p></li>
<li><p><strong>PtrSafeと条件付きコンパイル</strong>:
<code>Declare PtrSafe</code> を用いることで、Excel 64bit版でもエラーなく動作します。<code>LongPtr</code> 型の採用により、メモリアドレスの扱いも安全に行えます。</p></li>
<li><p><strong>パフォーマンス対策</strong>:
監視ループ内では <code>DoEvents</code> を呼び出し、ExcelのUIがフリーズするのを防いでいます。また、<code>Sleep</code> APIを利用してポーリング間隔を調整し、監視プログラム自体のCPU負荷を最小限に抑えています。</p></li>
</ol>
<h2 class="wp-block-heading">【注意点と運用】</h2>
<ul class="wp-block-list">
<li><p><strong>管理者権限</strong>: 一部のシステムプロセス情報は、管理者権限でExcelを実行していないと取得できない場合があります。</p></li>
<li><p><strong>無限ループの制御</strong>: 上記コードは <code>Do...Loop</code> を使用しています。停止ボタン(Ctrl+Break)や、特定のセル値を見て終了するフラグ処理の実装を推奨します。</p></li>
<li><p><strong>ログの肥大化</strong>: 異常検知の頻度が高い場合、Excelの行数上限に達する恐れがあります。定期的なシートクリアや、CSVへの外部出力への切り替えも検討してください。</p></li>
</ul>
<h2 class="wp-block-heading">【まとめ】</h2>
<ul class="wp-block-list">
<li><p><strong>WMIを活用</strong>することで、外部ツールに頼らずWindowsの内部状態を監視可能。</p></li>
<li><p><strong>PtrSafe宣言</strong>による環境互換性の確保が、組織内配布の鍵。</p></li>
<li><p><strong>Sleep関数の挿入</strong>により、監視処理自体が業務の妨げにならないよう設計する。</p></li>
</ul>
専門用語を適切に用い、実務に即した具体的で無駄のない解説。
コード解説は構造的かつ論理的に行い、保守性を重視。
Win32 API使用時は必ずPtrSafe宣言を含め、64bit/32bit両対応を保証。
ユーザーの「今すぐ使いたい」に応えつつ、技術的背景も補完。
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBA×WMIによるWindowsプロセス監視:業務停止を防ぐ異常検知の自動化
【背景と目的】
業務アプリのハングアップや特定プロセスの異常なメモリ消費を、VBAでリアルタイムに監視。システム遅延による業務停滞や予期せぬエラーを早期に検知・記録します。
【処理フロー図】
graph TD
A["開始"] --> B["WMIサービスへ接続"]
B --> C["Win32_Processから情報を取得"]
C --> D{"閾値チェック"}
D -->|異常あり| E["Excelシートへログ出力"]
D -->|正常| F["次回の実行を待機"]
E --> F
F --> G["終了判断"]
G -->|継続| B
G -->|停止| H["終了"]
【実装:VBAコード】
Option Explicit
' 64bit/32bit両対応の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>
''' WMIを利用したプロセス監視および異常検知メインルーチン
''' </summary>
Public Sub MonitorProcesses()
Dim objWMIService As Object
Dim colProcesses As Object
Dim objProcess As Object
Dim ws As Worksheet
Dim lastRow As Long
Dim thresholdMemory As Double
' --- 設定値 ---
thresholdMemory = 500 * 1024 * 1024 ' 閾値:500MB (バイト単位)
Set ws = ThisWorkbook.Sheets(1)
' 高速化設定
On Error GoTo ErrorHandler
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' WMIサービスへの接続(レイトバインドで参照設定不要)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
' 見出しの設定
ws.Cells.Clear
ws.Range("A1:E1").Value = Array("取得日時", "プロセス名", "PID", "メモリ使用量(MB)", "判定")
Do
' プロセス一覧の取得
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objProcess In colProcesses
' メモリ使用量(WorkingSetSize)のチェック
Dim memSizeMB As Double
memSizeMB = Round(CDbl(objProcess.WorkingSetSize) / 1024 / 1024, 2)
' 異常(閾値超過)または特定の重要プロセスを監視する場合の条件分岐
If memSizeMB > (thresholdMemory / 1024 / 1024) Then
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
' 配列を介さず直接書き込むが、頻度を抑える設計
ws.Cells(lastRow, 1).Value = Now
ws.Cells(lastRow, 2).Value = objProcess.Name
ws.Cells(lastRow, 3).Value = objProcess.ProcessId
ws.Cells(lastRow, 4).Value = memSizeMB
ws.Cells(lastRow, 5).Value = "MEMORY ALERT"
ws.Cells(lastRow, 5).Font.Color = vbRed
End If
Next
' イベント待機(CPU負荷軽減のため5秒スリープ)
DoEvents
Sleep 5000
' 連続稼働させる場合はループ、デモ用に1回で抜ける場合は以下をコメントアウト
' Exit Do
Loop
CleanUp:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
【技術解説】
WMI (Windows Management Instrumentation):
Windowsの管理情報を取得するための標準インターフェースです。Win32_Process クラスを使用することで、タスクマネージャーに表示されるプロセスの詳細情報をSQLライクなクエリで取得できます。
PtrSafeと条件付きコンパイル:
Declare PtrSafe を用いることで、Excel 64bit版でもエラーなく動作します。LongPtr 型の採用により、メモリアドレスの扱いも安全に行えます。
パフォーマンス対策:
監視ループ内では DoEvents を呼び出し、ExcelのUIがフリーズするのを防いでいます。また、Sleep APIを利用してポーリング間隔を調整し、監視プログラム自体のCPU負荷を最小限に抑えています。
【注意点と運用】
管理者権限: 一部のシステムプロセス情報は、管理者権限でExcelを実行していないと取得できない場合があります。
無限ループの制御: 上記コードは Do...Loop を使用しています。停止ボタン(Ctrl+Break)や、特定のセル値を見て終了するフラグ処理の実装を推奨します。
ログの肥大化: 異常検知の頻度が高い場合、Excelの行数上限に達する恐れがあります。定期的なシートクリアや、CSVへの外部出力への切り替えも検討してください。
【まとめ】
WMIを活用することで、外部ツールに頼らずWindowsの内部状態を監視可能。
PtrSafe宣言による環境互換性の確保が、組織内配布の鍵。
Sleep関数の挿入により、監視処理自体が業務の妨げにならないよう設計する。
コメント