【テクニカル・上級編】AutoCAD図面を開かずに情報を取得!AcadApplicationの活用で図面管理を効率化 – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:図面を開かずに情報を取得する『AcadApplication』の極意

図面を100枚開いて情報を集める。そんな前時代的なバッチ処理を、未だにあなたのPCで実行していないだろうか。

シニアエンジニアや社内システム管理者であれば誰もが直面する課題がある。それは「膨大な数のDWGファイル群から、特定の属性情報やレイアウト名、ブロックの存在有無を高速に吸い上げたい」という要求だ。AutoCADのGUIを立ち上げ、`Documents.Open`をループさせるアプローチは、メモリを喰らい、描画処理にCPUを奪われ、最終的には致命的なメモリリークでAutoCADごとクラッシュする。

AutoCAD VBAの本質は、CADを「お絵描きソフト」としてではなく、「ヘッドレスで動作する強力な幾何学演算・データベースエンジン」として使い倒すことにある。

今回は、図面を一切画面に表示させず(完全非表示モード)、裏側のCOMサーバー上で超高速に情報を取得・集計する『AcadApplication』の極限活用術を、メモリ管理とアーキテクチャの観点から徹底解説する。

1. なぜ「図面を開く」アプローチは破綻するのか

図面管理システムや設計チェッカーを構築する際、初心者が陥る最大の罠がこれだ。

‘ 【アンチパターン】絶対にやってはいけない実装
Dim doc As AcadDocument
Set doc = ThisDrawing.Application.Documents.Open(“C:\Data\Drawing1.dwg”)
‘ 何らかの処理
doc.Close False

このコードの何が問題か。
1. 視覚的オーバーヘッド: AutoCADのメインウィンドウ(GUI)がアクティブになり、グラフィックボードとCPUの描画スレッドが不必要に占有される。
2. イベントの暴走: 図面を開くたびに `AcadDocument` のイベントやロード時のLISP、外部参照の解決試行などが走り、処理が重くなる。
3. COMオブジェクトの残骸: ループ内で適切に参照を断ち切らないと、裏で `acad.exe` のゾンビプロセスが大量発生し、PCを再起動する羽目になる。

これを解決するのが、非表示のインスタンス生成と、ドキュメントコレクションを通した軽量アクセスである。

2. AcadApplicationのライフサイクルと非表示インスタンスの生成

AutoCADのCOMインターフェースは、`AcadApplication` オブジェクトを独立して生成できる。これにより、現在作業中のCADとは完全に切り離された「バックグラウンド・ワーカー」としてのAutoCADを起動可能だ。

以下に、図面を「画面に見せない(Visible = False)」状態で完全に制御し、確実にメモリを解放する堅牢な実装を示す。

実装コード:ヘッドレス図面情報スキャナー

Option Explicit

‘ 外部図面を非表示で解析し、情報を取得するメインプロシージャ
Public Sub BatchExtractDrawingInfo()
Dim acadApp As AcadApplication
Dim targetDir As String
Dim fso As Object
Dim targetFile As Object
Dim startTime As Double

startTime = Timer
targetDir = “C:\CAD_Data\TargetDrawings\” ‘ 対象フォルダ

‘ 1. バックグラウンドでAutoCADの独立インスタンスを生成
On Error Resume Next
Set acadApp = GetObject(, “AutoCAD.Application”)
If acadApp Is Nothing Then
Set acadApp = New AutoCAD.Application
End If
On Error GoTo 0

If acadApp Is Nothing Then
MsgBox “AutoCADの起動に失敗しました。”, vbCritical
Exit Sub
End If

‘ 【重要】GUIを描画させないことで、処理速度を最大化する
acadApp.Visible = False

Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FolderExists(targetDir) Then
MsgBox “指定されたフォルダが存在しません: ” & targetDir, vbCritical
Exit Sub
End If

‘ 2. フォルダ内のDWGファイルをイテレート
For Each targetFile In fso.GetFolder(targetDir).Files
If LCase(fso.GetExtensionName(targetFile.Name)) = “dwg” Then
Call ProcessSingleDrawing(acadApp, targetFile.Path)
End If
Next targetFile

‘ 3. クリーンアップ
acadApp.Quit
Set acadApp = Nothing
Set fso = Nothing

MsgBox “処理完了。実行時間: ” & Format(Timer – startTime, “0.00”) & “秒”, vbInformation
End Sub

‘ 個別図面の解析と厳格なメモリ管理を行うサブルーチン
Private Sub ProcessSingleDrawing(ByRef acadApp As AcadApplication, ByVal filePath As String)
Dim acadDoc As AcadDocument
Dim layoutName As Variant
Dim blockObj As AcadBlock

On Error GoTo ErrorHandler

‘ 【核心】非表示のままドキュメントコレクションに読み込む
‘ 第2引数を True (読み取り専用) にすることで、ロックを回避し高速化する
Set acadDoc = acadApp.Documents.Open(filePath, True)

Debug.Print “—————————————-”
Debug.Print “ファイル名: ” & acadDoc.Name

‘ レイアウト名の列挙(図面を開かずにレイアウト構造を把握)
For Each layoutName In acadDoc.Layouts
Debug.Print ” – レイアウト: ” & layoutName.Name
Next layoutName

‘ 特定のブロック(例: “TITLE_BLOCK”)の存在確認と属性抽出
For Each blockObj In acadDoc.Blocks
If blockObj.Name = “TITLE_BLOCK” Then
Debug.Print ” -> 図枠ブロックを発見”
‘ ここで属性(Attribute)の値を読み取るロジックを展開可能
End If
Next blockObj

‘ 4. ドキュメントの明示的な閉局(変更破棄: False)
acadDoc.Close False
Set acadDoc = Nothing
Exit Sub

ErrorHandler:
Debug.Print “【エラー】ファイル処理失敗: ” & filePath & ” (Error: ” & Err.Description & “)”
If Not acadDoc Is Nothing Then
acadDoc.Close False
Set acadDoc = Nothing
End If
End Sub

3. シニアエンジニアが知るべき「メモリ最適化」と「COMの罠」

VBAにおけるCOMオブジェクトの操作は、ガベージコレクションの挙動に依存するため、放置すれば確実にメモリリークを引き起こす。特にAutoCADのAPIを大量のループ内で回す場合、以下の鉄則を遵守しなければならない。

① ループ内でのオブジェクト変数の完全解放

VBAはプロシージャが終了するまでローカル変数の参照を保持し続ける。数百、数千の図面を処理する際、`Set acadDoc = Nothing` を明示的に行わなければ、COMの参照カウントが落ちず、メモリが枯渇する。

② `Documents.Open` の第2引数(ReadOnly)の活用

API仕様として、`Documents.Open(Path, [Password], [ReadOnly])` の第3引数(または実装環境によるオーバーロード)に `True` を指定することで、ファイル共有違反を防ぎ、ネットワーク越しの図面であっても排他制御の競合なしに高速読み込みが可能となる。

③ ゾンビプロセスの防止

万が一VBAの実行中にエラー(トラップされない例外など)が発生した場合、バックグラウンドの `acad.exe` がタスクマネージャー上に残り続ける。これを防ぐためには、エントリポイントで必ず既存のインスタンスをハンドルするか、Windows API (`TerminateProcess` など) を組み合わせたガーデニングロジックを組み込むのが、真のプロフェッショナルエンジニアの仕事である。

4. システム間連携への昇華:VBAから.NET / 別システムへの布石

VBAによるヘッドレスAutoCAD制御をマスターしたのなら、次はこれを社内ニッチなシステム(WebアプリケーションやDBサーバー)のバックエンドワーカーへと昇華させよう。

Excel VBAからこのマクロをキックし、抽出した図面情報を自動的にSQLiteやSQL Serverに流し込む。あるいは、WindowsタスクスケジューラからExcel(またはWSH/VBScript)をヘッドレスで起動し、上記のVBAコードを叩かせる。

このアーキテクチャにより、「AutoCADライセンスを保有するサーバー端末で、夜間に全図面の改訂履歴やタイトルブロックの整合性を自動チェックし、不整合があればTeamsやSlackにアラートを飛ばす」といった、高度なBIM/CADインフラストラクチャをノーコスト(既存のAutoCAD資産のみ)で構築できる。

図面は「開いて見るもの」ではない。「プログラムに読ませてデータを搾り取るもの」だ。
このパラダイムシフトをあなたの開発現場に導入し、図面管理のボトルネックを完全に破壊してほしい。

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