Access VBAでWMI Win32_Process監視

Tech

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

Access VBAでWMI Win32_Process監視

はじめに

企業のIT環境では、基幹システムや特定のアプリケーションが常に稼働しているか、そのリソース使用状況が健全であるかを監視するニーズが頻繁に発生します。Windows Management Instrumentation (WMI) は、Windows OSの管理情報にアクセスするための強力なインターフェースを提供し、VBAからこれを利用することで、外部ライブラリに依存せずシステム状態を監視することが可能です。

本稿では、Access VBAを用いてWMIの Win32_Process クラスを監視し、特定のプロセスの稼働状況やリソース使用状況を取得・記録する具体的な方法を解説します。特に、VBAの標準機能とCOMオブジェクト WbemScripting.SWbemLocator を利用し、参照設定不要でWMIサービスに接続する手法に焦点を当てます。これにより、外部ライブラリの追加インストールを禁止する厳格な環境でも、システム監視ソリューションを構築できます。

監視の対象は以下の要件を満たします。

  • 特定のプロセス(例: EXCEL.EXEoutlook.exe)の存在確認。

  • 実行中のプロセスの詳細情報(プロセスID、実行パス、CPU/メモリ使用率、起動時刻など)の取得。

  • 取得した情報をAccessデータベースに記録し、履歴管理を可能にする。

  • 大量データ処理を想定した性能チューニングを組み込む。

設計

監視の目的と対象

特定の重要プロセスが予期せず終了していないか、または過剰なリソースを消費していないかを監視し、異常を検知することを目的とします。監視対象は Win32_Process クラスから得られる以下の情報とします。

  • ProcessId: プロセスを一意に識別するID。

  • Name: プロセス名(例: EXCEL.EXE)。

  • CommandLine: プロセスを起動したコマンドライン。

  • ExecutablePath: 実行ファイルのフルパス。

  • CreationDate: プロセスの起動時刻 (UTC)。

  • KernelModeTime: カーネルモードで費やされた時間 (マイクロ秒単位)。

  • UserModeTime: ユーザーモードで費やされた時間 (マイクロ秒単位)。

  • WorkingSetSize: プロセスが現在使用している物理メモリ量 (バイト単位)。

  • VirtualSize: プロセスが使用している仮想メモリ量 (バイト単位)。

処理フロー

監視の基本的な処理は、WMIサービスへの接続、WQL (WMI Query Language) を用いた情報取得、そして取得したデータの処理・記録となります。

graph TD
    A["開始"] --> B{"Access VBAアプリ起動"};
    B --> C{"WMIサービス接続"};
    C --> D{"監視対象プロセス指定"};
    D --> E{"WQLクエリ作成"};
    E --> F{"ExecQuery実行"};
    F --> G{"結果セット取得"};
    G --|プロセス情報あり| H["情報抽出と整形"];
    G --|プロセス情報なし| I["ログ記録: プロセス不在"];
    H --> J["Accessテーブルへ書き込み"];
    J --> K{"次の監視タイミングまで待機"};
    K --> E;
    I --> K;
    K --> L{"終了条件?"};
    L --|はい| M["終了"];
    L --|いいえ| E;

図1: WMIプロセス監視フローチャート

データモデル

監視結果を保存するためのAccessテーブルを設計します。

フィールド名 データ型 説明
ID オートナンバー 主キー
監視日時 日付/時刻 レコードが記録されたJST日時
プロセス名 短いテキスト プロセス名(例: EXCEL.EXE
プロセスID 長整数 ProcessId
実行パス 長いテキスト ExecutablePath
コマンドライン 長いテキスト CommandLine
起動日時 日付/時刻 CreationDate (UTCをJSTに変換)
カーネル時間 長整数 KernelModeTime (マイクロ秒)
ユーザー時間 長整数 UserModeTime (マイクロ秒)
物理メモリ 長整数 WorkingSetSize (バイト)
仮想メモリ 長整数 VirtualSize (バイト)

パフォーマンス考慮点

  • WMIクエリの最適化: 必要なプロパティのみを SELECT 句で指定し、WHERE 句で絞り込むことで、WMIサービスからのデータ転送量を最小限に抑えます。

  • 配列バッファ: WMIから取得したデータを一度配列に格納し、その配列のデータをまとめてAccessテーブルに書き込むことで、DAO/ADOのI/Oオーバーヘッドを削減します。

  • トランザクション処理: 複数のレコードをAccessテーブルに書き込む場合、トランザクションを使用することで書き込み速度を大幅に向上させ、データの整合性を保証します。

実装

Access VBAでのWMI利用は、GetObject 関数を通じて WbemScripting ライブラリのCOMオブジェクトにアクセスします。これはVBAがデフォルトで提供する機能であり、別途参照設定や外部ライブラリのインストールは不要です。よって、「外部ライブラリ禁止」の要件を満たします。Declare PtrSafe については、WMI自体はCOM経由でアクセスするため直接の必要はありませんが、Win32 APIを呼び出す際に必須となる点として補足します。

コード1: 特定プロセスの存在確認と基本情報取得

この例では、EXCEL.EXE プロセスが存在するか確認し、その基本情報をデバッグウィンドウに表示します。

' 標準モジュール (例: Module1) に記述

Option Compare Database
Option Explicit

' Access 64bit環境での互換性のため、Win32 APIを宣言する場合はPtrSafeが必要だが、
' WMIはCOMオブジェクト経由のため、この関数自体はDeclare PtrSafeを必要としない。
' 以下の宣言は、Win32 APIを使用する際の例示であり、本WMI監視には直接使用しない。
' Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long

Sub MonitorSpecificProcess()
    Dim objWMIService As Object
    Dim colProcesses As Object
    Dim objProcess As Object
    Dim strComputer As String
    Dim strProcessName As String
    Dim strWQL As String
    Dim ws As Object ' WScript.Shell (時間計測用として利用するが必須ではない)
    Dim dblStartTime As Double
    Dim dblEndTime As Double

    strComputer = "." ' ローカルPC
    strProcessName = "EXCEL.EXE" ' 監視したいプロセス名

    Set ws = CreateObject("WScript.Shell")

    On Error GoTo ErrorHandler

    ' --- 性能計測開始 ---
    dblStartTime = Timer

    ' WMIサービスに接続
    ' GetObjectはVBAの標準機能で、別途参照設定不要なCOMオブジェクトへのアクセスを可能にする
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

    ' WQLクエリで特定のプロセス情報を取得
    ' 必要なプロパティのみSELECTすることで、データ転送量を削減
    strWQL = "SELECT ProcessId, Name, CommandLine, ExecutablePath, CreationDate, " & _
             "KernelModeTime, UserModeTime, WorkingSetSize, VirtualSize FROM Win32_Process WHERE Name = '" & strProcessName & "'"
    Set colProcesses = objWMIService.ExecQuery(strWQL)

    Debug.Print "--- " & strProcessName & " 監視結果 (" & Format(Now, "yyyy/mm/dd hh:nn:ss") & ") ---"

    If colProcesses.Count > 0 Then
        For Each objProcess In colProcesses
            Debug.Print "  プロセスID: " & objProcess.ProcessId
            Debug.Print "  プロセス名: " & objProcess.Name
            Debug.Print "  コマンドライン: " & objProcess.CommandLine
            Debug.Print "  実行パス: " & objProcess.ExecutablePath
            Debug.Print "  起動日時 (UTC): " & WMIStringToDate(objProcess.CreationDate)
            Debug.Print "  カーネル時間 (ms): " & objProcess.KernelModeTime / 10000 ' マイクロ秒からミリ秒
            Debug.Print "  ユーザー時間 (ms): " & objProcess.UserModeTime / 10000 ' マイクロ秒からミリ秒
            Debug.Print "  物理メモリ (MB): " & Format(objProcess.WorkingSetSize / (1024 * 1024), "0.00")
            Debug.Print "  仮想メモリ (MB): " & Format(objProcess.VirtualSize / (1024 * 1024), "0.00")
            Debug.Print "--------------------------------------------------"
        Next objProcess
    Else
        Debug.Print "  プロセス '" & strProcessName & "' は実行されていません。"
    End If

    ' --- 性能計測終了 ---
    dblEndTime = Timer
    Debug.Print "処理時間: " & Format(dblEndTime - dblStartTime, "0.000") & " 秒"

Exit_Sub:
    Set objProcess = Nothing
    Set colProcesses = Nothing
    Set objWMIService = Nothing
    Set ws = Nothing
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
    Resume Exit_Sub
End Sub

' WMIのUTC日付文字列をVBAのDate型に変換するヘルパー関数
' WMI日付フォーマット: yyyymmddHHMMSS.ffffff(+/-)zzz
Function WMIStringToDate(ByVal WMI_Date_String As String) As Date
    Dim Year As Integer, Month As Integer, Day As Integer
    Dim Hour As Integer, Minute As Integer, Second As Integer
    Dim MicroSecond As Long
    Dim TimeZoneOffset As Integer ' 分単位

    Year = CInt(Mid(WMI_Date_String, 1, 4))
    Month = CInt(Mid(WMI_Date_String, 5, 2))
    Day = CInt(Mid(WMI_Date_String, 7, 2))
    Hour = CInt(Mid(WMI_Date_String, 9, 2))
    Minute = CInt(Mid(WMI_Date_String, 11, 2))
    Second = CInt(Mid(WMI_Date_String, 13, 2))
    ' マイクロ秒は精度のため省略、必要なら利用
    ' MicroSecond = CLng(Mid(WMI_Date_String, 16, 6))

    TimeZoneOffset = CInt(Mid(WMI_Date_String, 20, 3)) ' タイムゾーンオフセット(分)

    WMIStringToDate = DateSerial(Year, Month, Day) + TimeSerial(Hour, Minute, Second)

    ' UTCからローカルタイムゾーン (JST) への変換
    ' Accessは通常JSTで動作するため、WMIのUTC時刻をそのまま利用するとJST-9hとなる。
    ' WMIStringToDate = DateAdd("n", -TimeZoneOffset, WMIStringToDate) ' WMIのタイムゾーンを考慮
    ' シンプルに現在のシステムタイムゾーンのオフセットを加減する
    WMIStringToDate = DateAdd("h", 9, WMIStringToDate) ' UTCをJSTに変換 (日本の標準時+9時間)

End Function

コード1: 特定プロセスの情報取得

コード1の実行手順:

  1. Accessデータベースを開き、Alt + F11キーでVBAエディタを開きます。

  2. 左側のプロジェクトエクスプローラで、データベース名の下の「Microsoft Access オブジェクト」を右クリックし、「挿入」→「標準モジュール」を選択します。

  3. 新しいモジュールに上記のVBAコードをコピー&ペーストします。

  4. MonitorSpecificProcess プロシージャ内にカーソルを置き、F5キーを押して実行します。

  5. 結果はVBAエディタの下部にある「イミディエイトウィンドウ」(表示されていない場合はCtrl + Gで表示)に表示されます。

コード2: 複数のプロセスを定期的に監視し、Accessテーブルに履歴を記録

この例では、複数の特定のプロセスを定期的に監視し、取得したリソース使用状況をAccessテーブルに記録します。Form_Timer イベントと連携させることで、自動的な定期監視を実現します。

準備:

  1. Accessデータベースに、以下の構造を持つテーブル ProcessMonitorLog を作成します。

    • ID: オートナンバー、主キー

    • 監視日時: 日付/時刻 (短い日付形式)

    • プロセス名: 短いテキスト (255)

    • プロセスID: 長整数

    • 実行パス: 長いテキスト

    • コマンドライン: 長いテキスト

    • 起動日時: 日付/時刻 (短い日付形式)

    • カーネル時間: 長整数

    • ユーザー時間: 長整数

    • 物理メモリ: 長整数

    • 仮想メモリ: 長整数

  2. 新しいフォームを作成し、名前を frmProcessMonitor とします。

  3. フォームのプロパティで タイマー間隔60000 (60秒 = 1分) に設定します。

  4. フォームにボタンなどを配置せず、非表示で実行することも可能です。

' 標準モジュール (例: Module1) に記述

Option Compare Database
Option Explicit

' WMIのUTC日付文字列をVBAのDate型に変換するヘルパー関数
' (コード1と同じなので省略、Module1に既に存在することを前提)
' Function WMIStringToDate(...) As Date
'   ...
' End Function

Sub StartProcessMonitoringForm()
    ' 監視フォームを非表示で開く (Timerイベントが実行される)
    DoCmd.OpenForm "frmProcessMonitor", acNormal, , , , acHidden
End Sub

Sub StopProcessMonitoringForm()
    ' 監視フォームを閉じる
    DoCmd.Close acForm, "frmProcessMonitor"
End Sub

' フォームモジュール (frmProcessMonitor) に記述

Option Compare Database
Option Explicit

Private Const PROCESS_LIST As String = "'EXCEL.EXE','OUTLOOK.EXE','WINWORD.EXE','chrome.exe'"
Private Const MAX_BATCH_SIZE As Long = 50 ' バッチ処理の最大レコード数

Private Sub Form_Load()
    Me.TimerInterval = 60000 ' 60秒 (1分) ごとにTimerイベント発生
    Debug.Print "プロセス監視を開始しました。(" & Format(Now, "yyyy/mm/dd hh:nn:ss") & ")"
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Debug.Print "プロセス監視を停止しました。(" & Format(Now, "yyyy/mm/dd hh:nn:ss") & ")"
End Sub

Private Sub Form_Timer()
    Dim objWMIService As Object
    Dim colProcesses As Object
    Dim objProcess As Object
    Dim strWQL As String
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim varProcessData() As Variant ' 配列バッファ
    Dim lngCounter As Long
    Dim lngRow As Long
    Dim dblStartTime As Double
    Dim dblEndTime As Double

    ' --- 性能計測開始 ---
    dblStartTime = Timer

    On Error GoTo ErrorHandler

    ' 画面更新を停止し、フォームの処理を高速化
    ' Excel.Application.ScreenUpdating に相当する機能はAccessにはないが、
    ' ここではレコードセット操作を高速化する。
    Application.SetOption "Confirm Record Changes", False
    Application.SetOption "Confirm Document Deletions", False
    Application.SetOption "Confirm Action Queries", False

    Set db = CurrentDb

    ' WMIサービスに接続
    Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")

    ' 監視対象プロセスをWHERE句で指定
    strWQL = "SELECT ProcessId, Name, CommandLine, ExecutablePath, CreationDate, " & _
             "KernelModeTime, UserModeTime, WorkingSetSize, VirtualSize FROM Win32_Process WHERE Name IN (" & PROCESS_LIST & ")"
    Set colProcesses = objWMIService.ExecQuery(strWQL)

    ' 配列バッファの初期化
    ' 取得するプロパティ数: 10
    ReDim varProcessData(0 To colProcesses.Count - 1, 0 To 9)
    lngCounter = 0

    ' --- 取得データを配列に格納 ---
    For Each objProcess In colProcesses
        varProcessData(lngCounter, 0) = Now() ' 監視日時 (JST)
        varProcessData(lngCounter, 1) = objProcess.Name
        varProcessData(lngCounter, 2) = objProcess.ProcessId
        varProcessData(lngCounter, 3) = objProcess.ExecutablePath
        varProcessData(lngCounter, 4) = objProcess.CommandLine
        varProcessData(lngCounter, 5) = WMIStringToDate(objProcess.CreationDate) ' UTCをJSTに変換
        varProcessData(lngCounter, 6) = objProcess.KernelModeTime
        varProcessData(lngCounter, 7) = objProcess.UserModeTime
        varProcessData(lngCounter, 8) = objProcess.WorkingSetSize
        varProcessData(lngCounter, 9) = objProcess.VirtualSize
        lngCounter = lngCounter + 1
    Next objProcess

    If lngCounter > 0 Then
        ' --- DAOトランザクションとバッチ処理で高速書き込み ---
        db.BeginTrans
        Set rs = db.OpenRecordset("ProcessMonitorLog", dbOpenDynaset)

        For lngRow = 0 To lngCounter - 1
            rs.AddNew
            rs!監視日時 = varProcessData(lngRow, 0)
            rs!プロセス名 = varProcessData(lngRow, 1)
            rs!プロセスID = varProcessData(lngRow, 2)
            rs!実行パス = varProcessData(lngRow, 3)
            rs!コマンドライン = varProcessData(lngRow, 4)
            rs!起動日時 = varProcessData(lngRow, 5)
            rs!カーネル時間 = varProcessData(lngRow, 6)
            rs!ユーザー時間 = varProcessData(lngRow, 7)
            rs!物理メモリ = varProcessData(lngRow, 8)
            rs!仮想メモリ = varProcessData(lngRow, 9)
            rs.Update

            ' 一定数ごとにトランザクションをコミット (メモリ消費を抑えつつ高速化)
            If (lngRow + 1) Mod MAX_BATCH_SIZE = 0 Then
                db.CommitTrans
                db.BeginTrans
            End If
        Next lngRow

        ' 残りのレコードをコミット
        db.CommitTrans
        Debug.Print lngCounter & " 件のプロセス情報をデータベースに記録しました。"
    Else
        Debug.Print "監視対象プロセスは実行されていませんでした。"
    End If

    ' --- 性能計測終了 ---
    dblEndTime = Timer
    Debug.Print "処理時間: " & Format(dblEndTime - dblStartTime, "0.000") & " 秒"

Exit_Form_Timer:
    ' 元の設定に戻す
    Application.SetOption "Confirm Record Changes", True
    Application.SetOption "Confirm Document Deletions", True
    Application.SetOption "Confirm Action Queries", True

    Set rs = Nothing
    Set db = Nothing
    Set objProcess = Nothing
    Set colProcesses = Nothing
    Set objWMIService = Nothing
    Exit Sub

ErrorHandler:
    If db.Transactions Then ' エラー時はトランザクションをロールバック
        db.Rollback
    End If
    MsgBox "プロセス監視中にエラーが発生しました: " & Err.Description, vbCritical
    Resume Exit_Form_Timer
End Sub

コード2: 定期監視とデータベースへの記録

性能チューニングの数値効果 (例):

  • 配列バッファとトランザクションなしの場合: 1000レコードの挿入に約 500ms ~ 1000ms かかることがあります。

  • 配列バッファとトランザクションありの場合: 1000レコードの挿入に約 50ms ~ 100ms で完了することが可能です。

  • バッチ処理: MAX_BATCH_SIZE を設定することで、トランザクションの粒度を調整し、メモリ使用量とI/O効率のバランスを取ることができます。今回の例では、MAX_BATCH_SIZE = 50 の場合、1回のコミットで50件ずつ書き込むため、大規模なデータセットでも安定したパフォーマンスを期待できます。

コード2の実行手順:

  1. 上記「準備」で述べたテーブル ProcessMonitorLog とフォーム frmProcessMonitor を作成します。

  2. Module1WMIStringToDate 関数(コード1に記載)と StartProcessMonitoringFormStopProcessMonitoringForm プロシージャをコピー&ペーストします。

  3. frmProcessMonitor のフォームモジュールに Form_LoadForm_UnloadForm_Timer イベントプロシージャをコピー&ペーストします。

  4. Module1StartProcessMonitoringForm を実行することで、フォームが非表示で開き、1分ごとにプロセス監視が開始され、結果が ProcessMonitorLog テーブルに記録されます。

  5. 監視を停止するには、Module1StopProcessMonitoringForm を実行します。

ロールバック方法:

  • テーブルデータ: DELETE FROM ProcessMonitorLog; SQLクエリを実行することで、記録されたすべてのデータを削除できます。

  • VBAコード: 作成した標準モジュールやフォームモジュールのVBAコードを削除します。

  • データベースオブジェクト: 作成したテーブル ProcessMonitorLog とフォーム frmProcessMonitor をAccessのナビゲーションウィンドウから削除します。

検証

  1. プロセスの起動・停止確認:

    • コード1を実行し、EXCEL.EXE が起動している場合と停止している場合の両方で動作を確認します。

    • コード2を開始し、監視対象のプロセスを起動・終了させて、ProcessMonitorLog テーブルに正確な情報が記録されるか、またはプロセス不在のログが適切に出力されるかを確認します。

  2. リソース情報の取得:

    • 取得された WorkingSetSizeVirtualSize が、タスクマネージャーで表示される値とおおよそ一致するか確認します。

    • CreationDate がプロセスの起動時刻と一致するか確認します(WMIStringToDate関数によるJST変換が正しいか)。

  3. 性能確認:

    • 大量のプロセスを監視対象に含めるか、監視間隔を短くして、ProcessMonitorLog テーブルへの書き込み速度が十分に速いかを確認します。イミディエイトウィンドウに出力される「処理時間」を参考にします。

    • 数百件以上のレコードが追加されたテーブルに対して、トランザクション処理が有効に機能していることを体感します。

  4. エラーハンドリング:

    • WMIサービスが停止している状態で実行し、適切にエラーメッセージが表示されるか確認します。

    • 存在しないコンピュータ名を strComputer に設定した場合の動作を確認します。

運用

定期実行のスケジュール設定

Accessアプリケーションを定期的に起動し、監視を開始するためには、Windowsのタスクスケジューラを利用するのが効果的です。

手順:

  1. AccessデータベースをMDB/ACCDB形式で保存し、監視用フォーム frmProcessMonitor が自動的に起動するように設定します。例えば、データベース起動時に StartProcessMonitoringForm を呼び出すマクロをAutoExecに設定するか、データベースの起動オプションで特定のフォームを開くようにします。

  2. タスクスケジューラの作成:

    • タスクスケジューラ を開き、「基本タスクの作成」を選択。

    • タスク名と説明を入力。

    • トリガーを「毎日」や「週ごと」など、監視間隔に合わせて設定します。

    • 操作で「プログラムの開始」を選択し、プログラム/スクリプトmsaccess.exe のフルパスを、引数の追加 に監視対象のAccessデータベースファイル (.accdb または .mdb) のフルパスを指定します。

ログ管理

ProcessMonitorLog テーブルは時間の経過とともに肥大化するため、定期的なログのアーカイブや削除ポリシーを確立することが重要です。

  • 古いレコード(例: 3ヶ月以上前のデータ)を別のアーカイブテーブルに移動または削除するVBAプロシージャを作成し、タスクスケジューラで月に一度実行します。

  • テーブルサイズが一定値を超えた場合に警告するロジックを追加することも検討します。

監視アラート

プロセスが予期せず停止した場合や、リソース使用率が異常に高くなった場合に、メール通知やポップアップアラートを発信する機能を実装することで、より実用的な監視システムとなります。

  • Outlook COMオブジェクトを利用してメールを送信するVBAコードを追加します。

  • 特定の閾値を超えた場合に、そのイベントをトリガーとしてアラートを発動させます。

落とし穴と対策

  1. WMIクエリのパフォーマンス問題:

    • 落とし穴: SELECT * FROM Win32_Process のようにすべてのプロパティを取得するクエリは、WMIサービスへの負荷が高く、結果セットが大きくなり、VBAでの処理時間も長くなります。特に大量のプロセスが実行されている環境では顕著です。

    • 対策: 常に必要なプロパティのみを SELECT 句で指定し、WHERE 句で監視対象を明確に絞り込みます。例えば WHERE Name = 'EXCEL.EXE'WHERE ProcessId = 1234 のようにします。

  2. セキュリティ設定と権限:

    • 落とし穴: WMIサービスへのアクセスには適切な権限が必要です。特にリモートコンピュータのWMIを監視する場合、権限不足でアクセスが拒否されることがあります。

    • 対策: ローカルPCでの監視は通常問題ありませんが、リモート監視の場合は適切なユーザーアカウントとパスワード (objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") のように接続文字列を調整) を指定するか、DCOM設定を確認します。

  3. WMIサービスの停止:

    • 落とし穴: WMIサービス自体が停止している場合、監視は機能しません。エラーハンドリングで適切に処理しないと、アプリケーションがクラッシュする可能性があります。

    • 対策: WMIサービス接続時にエラーが発生した場合 (On Error GoTo ErrorHandler)、その旨をユーザーに通知し、プログラムを安全に終了させるか、WMIサービスの再起動を試みるなどの対応を検討します。

  4. 64bit VBA環境とCOMオブジェクト:

    • 落とし穴: 32bit環境で動作していたコードが64bit Accessで動作しない場合があります。特にWin32 APIの Declare ステートメントには PtrSafe が必須です。

    • 対策: 本記事で用いた GetObject によるCOMオブジェクトの利用は、VBAのネイティブ機能として提供されるため、通常32bit/64bit環境の違いを意識する必要はありません。ただし、もしWin32 APIを直接呼び出す場合は、必ず Declare PtrSafe を使用します。

まとめ

本稿では、Access VBAを用いてWMI Win32_Process クラスを監視し、特定のプロセスの稼働状況やリソース使用状況をデータベースに記録する実践的な方法を解説しました。外部ライブラリを使用せず、VBAの標準機能とCOMオブジェクトを駆使することで、厳格な環境下でもシステム監視ソリューションを構築できることを示しました。

特に、以下の点を強調しました。

  • GetObject 関数によるWMIサービスへの容易なアクセス。

  • WQLクエリによる効率的なプロセス情報取得。

  • 配列バッファとDAOトランザクションを組み合わせた、Accessデータベースへの高速なデータ書き込み。

  • Form_Timer イベントを活用した定期的な監視の実現。

これらの手法を応用することで、Access VBAの汎用性を活かし、業務プロセス監視、リソース使用状況の傾向分析、異常検知アラートなど、さまざまなニーズに対応する強力な管理ツールを構築することが可能です。システムの安定稼働に貢献するため、ぜひ本記事のコードと知見をご活用ください。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました