<p><style_prompt></style_prompt></p>
<ul class="wp-block-list">
<li><p>専門用語を適切に用い、論理的かつ構造的な解説を行う。</p></li>
<li><p>Win32 APIの宣言には必ず <code>PtrSafe</code> を含め、64bit/32bit両対応とする。</p></li>
<li><p>コードは読みやすさと再利用性を重視し、実務的なエラーハンドリングを組み込む。</p></li>
<li><p>ユーザーの要求に忠実に従い、指示された順序で構成する。
</p></li>
</ul>
<p>本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">VBAとWMIによるリモートPC情報の一括取得:運用効率化と資産管理の自動化</h1>
<h3 class="wp-block-heading">【背景と目的】</h3>
<p>IT資産管理において、数百台のPCスペックを手作業で確認するのは非効率であり、入力ミスも避けられません。本ガイドでは、VBAからWMI(Windows Management Instrumentation)を利用し、ネットワーク経由で複数台のOS・CPU・メモリ情報を一括取得する高速なロジックを提供します。</p>
<h3 class="wp-block-heading">【処理フロー図】</h3>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["開始"] --> B["対象PCリストのループ処理"]
B --> C["WMI接続試行"]
C --> D{"接続成否?"}
D -->|成功| E["OS・CPU・メモリ情報取得"]
D -->|失敗| F["エラー内容を配列へ格納"]
E --> G["取得データを配列へ格納"]
G --> H["全PC終了?"]
H -->|No| B
H -->|Yes| I["Excelシートへ一括書き出し"]
I --> J["終了"]
</pre></div>
<h3 class="wp-block-heading">【実装:VBAコード】</h3>
<pre data-enlighter-language="generic">Option Explicit
' 64bit環境に対応したWin32 APIの宣言(ミリ秒単位の待機用)
#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
Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
If lastRow < 2 Then
MsgBox "PCリストがありません。", vbExclamation
Exit Sub
End If
' 高速化のため画面更新を停止
Application.ScreenUpdating = False
Dim pcNames As Variant
pcNames = ws.Range("A2:A" & lastRow).Value
' 結果を格納する配列 (PC名, OS, CPU, メモリ, ステータス)
Dim results() As Variant
ReDim results(1 To UBound(pcNames, 1), 1 To 5)
Dim i As Long
Dim strComputer As String
Dim objWMI As Object
Dim colOS As Object, colCPU As Object, colCS As Object
Dim objItem As Object
For i = 1 To UBound(pcNames, 1)
strComputer = pcNames(i, 1)
results(i, 1) = strComputer
' エラーハンドリング:リモートPCに接続できない場合を想定
On Error Resume Next
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If Err.Number <> 0 Then
results(i, 5) = "接続エラー: " & Err.Description
Err.Clear
Else
' OS情報の取得
Set colOS = objWMI.ExecQuery("Select * from Win32_OperatingSystem")
For Each objItem In colOS
results(i, 2) = objItem.Caption & " (" & objItem.Version & ")"
Next
' CPU情報の取得
Set colCPU = objWMI.ExecQuery("Select * from Win32_Processor")
For Each objItem In colCPU
results(i, 3) = Trim(objItem.Name)
Next
' 合計物理メモリの取得 (バイト単位をGBに変換)
Set colCS = objWMI.ExecQuery("Select * from Win32_ComputerSystem")
For Each objItem In colCS
results(i, 4) = Round(objItem.TotalPhysicalMemory / 1024 / 1024 / 1024, 2) & " GB"
Next
results(i, 5) = "成功"
End If
On Error GoTo 0
' WMIリソースの解放
Set objWMI = Nothing
Next i
' シートに一括出力
ws.Range("B2").Resize(UBound(results, 1), UBound(results, 2)).Value = results
Application.ScreenUpdating = True
MsgBox "情報取得が完了しました。", vbInformation
End Sub
</pre>
<h3 class="wp-block-heading">【技術解説】</h3>
<ol class="wp-block-list">
<li><p><strong>Late Binding(実行時結合)の採用</strong>:
<code>CreateObject</code> や <code>GetObject</code> を利用することで、特定のライブラリ(Microsoft WMI Scripting Library等)への参照設定を不要にしています。これにより、配布先での参照不可エラーを回避します。</p></li>
<li><p><strong>WMIクエリの活用</strong>:
<code>Win32_OperatingSystem</code>、<code>Win32_Processor</code>、<code>Win32_ComputerSystem</code> の各クラスをSQLライクなクエリで呼び出すことで、必要なプロパティに絞った効率的なデータ抽出を行っています。</p></li>
<li><p><strong>配列処理による高速化</strong>:
セルへの書き込みをループ内で行わず、全てのデータを一度 <code>Variant</code> 配列に格納してからシートへ出力することで、Excelのオーバーヘッドを最小限に抑えています。</p></li>
</ol>
<h3 class="wp-block-heading">【注意点と運用】</h3>
<ul class="wp-block-list">
<li><p><strong>管理者権限とRPC接続</strong>:
リモートPCから情報を取得するには、対象マシンに対する管理者権限が必要です。また、Windowsファイアウォールで「Windows Management Instrumentation (WMI)」の通信が許可されている必要があります。</p></li>
<li><p><strong>タイムアウトの考慮</strong>:
PCがオフラインの場合、<code>GetObject</code> でタイムアウトが発生し処理が一時停止します。本コードでは <code>On Error Resume Next</code> でスキップしていますが、大規模環境では事前に <code>Ping</code> による死活監視を行うロジックの追加を推奨します。</p></li>
<li><p><strong>メモリ表記の誤差</strong>:
<code>TotalPhysicalMemory</code> はハードウェアで予約された領域を除いた値を返す場合があるため、物理的な搭載容量と若干の差が出ることがあります。</p></li>
</ul>
<h3 class="wp-block-heading">【まとめ】</h3>
<ol class="wp-block-list">
<li><p><strong>権限管理</strong>: 実行ユーザーが対象PCに対して管理者権限を持っていることを確認する。</p></li>
<li><p><strong>エラー耐性</strong>: 接続失敗を前提としたエラーハンドリングを組み込み、処理を止めない設計にする。</p></li>
<li><p><strong>一括出力</strong>: セルへの書き込み回数を減らすため、必ず配列を経由して処理を高速化させる。</p></li>
</ol>
専門用語を適切に用い、論理的かつ構造的な解説を行う。
Win32 APIの宣言には必ず PtrSafe を含め、64bit/32bit両対応とする。
コードは読みやすさと再利用性を重視し、実務的なエラーハンドリングを組み込む。
ユーザーの要求に忠実に従い、指示された順序で構成する。
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBAとWMIによるリモートPC情報の一括取得:運用効率化と資産管理の自動化
【背景と目的】
IT資産管理において、数百台のPCスペックを手作業で確認するのは非効率であり、入力ミスも避けられません。本ガイドでは、VBAからWMI(Windows Management Instrumentation)を利用し、ネットワーク経由で複数台のOS・CPU・メモリ情報を一括取得する高速なロジックを提供します。
【処理フロー図】
graph TD
A["開始"] --> B["対象PCリストのループ処理"]
B --> C["WMI接続試行"]
C --> D{"接続成否?"}
D -->|成功| E["OS・CPU・メモリ情報取得"]
D -->|失敗| F["エラー内容を配列へ格納"]
E --> G["取得データを配列へ格納"]
G --> H["全PC終了?"]
H -->|No| B
H -->|Yes| I["Excelシートへ一括書き出し"]
I --> J["終了"]
【実装:VBAコード】
Option Explicit
' 64bit環境に対応したWin32 APIの宣言(ミリ秒単位の待機用)
#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
Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
If lastRow < 2 Then
MsgBox "PCリストがありません。", vbExclamation
Exit Sub
End If
' 高速化のため画面更新を停止
Application.ScreenUpdating = False
Dim pcNames As Variant
pcNames = ws.Range("A2:A" & lastRow).Value
' 結果を格納する配列 (PC名, OS, CPU, メモリ, ステータス)
Dim results() As Variant
ReDim results(1 To UBound(pcNames, 1), 1 To 5)
Dim i As Long
Dim strComputer As String
Dim objWMI As Object
Dim colOS As Object, colCPU As Object, colCS As Object
Dim objItem As Object
For i = 1 To UBound(pcNames, 1)
strComputer = pcNames(i, 1)
results(i, 1) = strComputer
' エラーハンドリング:リモートPCに接続できない場合を想定
On Error Resume Next
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If Err.Number <> 0 Then
results(i, 5) = "接続エラー: " & Err.Description
Err.Clear
Else
' OS情報の取得
Set colOS = objWMI.ExecQuery("Select * from Win32_OperatingSystem")
For Each objItem In colOS
results(i, 2) = objItem.Caption & " (" & objItem.Version & ")"
Next
' CPU情報の取得
Set colCPU = objWMI.ExecQuery("Select * from Win32_Processor")
For Each objItem In colCPU
results(i, 3) = Trim(objItem.Name)
Next
' 合計物理メモリの取得 (バイト単位をGBに変換)
Set colCS = objWMI.ExecQuery("Select * from Win32_ComputerSystem")
For Each objItem In colCS
results(i, 4) = Round(objItem.TotalPhysicalMemory / 1024 / 1024 / 1024, 2) & " GB"
Next
results(i, 5) = "成功"
End If
On Error GoTo 0
' WMIリソースの解放
Set objWMI = Nothing
Next i
' シートに一括出力
ws.Range("B2").Resize(UBound(results, 1), UBound(results, 2)).Value = results
Application.ScreenUpdating = True
MsgBox "情報取得が完了しました。", vbInformation
End Sub
【技術解説】
Late Binding(実行時結合)の採用:
CreateObject や GetObject を利用することで、特定のライブラリ(Microsoft WMI Scripting Library等)への参照設定を不要にしています。これにより、配布先での参照不可エラーを回避します。
WMIクエリの活用:
Win32_OperatingSystem、Win32_Processor、Win32_ComputerSystem の各クラスをSQLライクなクエリで呼び出すことで、必要なプロパティに絞った効率的なデータ抽出を行っています。
配列処理による高速化:
セルへの書き込みをループ内で行わず、全てのデータを一度 Variant 配列に格納してからシートへ出力することで、Excelのオーバーヘッドを最小限に抑えています。
【注意点と運用】
管理者権限とRPC接続:
リモートPCから情報を取得するには、対象マシンに対する管理者権限が必要です。また、Windowsファイアウォールで「Windows Management Instrumentation (WMI)」の通信が許可されている必要があります。
タイムアウトの考慮:
PCがオフラインの場合、GetObject でタイムアウトが発生し処理が一時停止します。本コードでは On Error Resume Next でスキップしていますが、大規模環境では事前に Ping による死活監視を行うロジックの追加を推奨します。
メモリ表記の誤差:
TotalPhysicalMemory はハードウェアで予約された領域を除いた値を返す場合があるため、物理的な搭載容量と若干の差が出ることがあります。
【まとめ】
権限管理: 実行ユーザーが対象PCに対して管理者権限を持っていることを確認する。
エラー耐性: 接続失敗を前提としたエラーハンドリングを組み込み、処理を止めない設計にする。
一括出力: セルへの書き込み回数を減らすため、必ず配列を経由して処理を高速化させる。
コメント