AutoCAD VBAを掌握する極限の知見
図面オープン時の「プロキシオブジェクト」警告を完全沈黙させるシステム変数操作
AutoCAD VBAによる大規模な図面バッチ処理を構築する際、最も厄介で、かつシステムを完全に停止させる「見えない壁」は何か。それは、エラートラップでは捕捉できない「割り込みダイアログ」である。
特に、Civil 3Dや業界特化型アドオン(AutoCAD Architectureなど)で生成された図面を、プレーンなAutoCAD環境でバッチ処理しようとした瞬間、あの忌々しい「プロキシ情報」ダイアログが画面にポップアップする。
「この図面には、このアプリケーションでは認識できないオブジェクトが含まれています……」
このダイアログが現れた時点で、VBAの実行スレッドは完全に凍結する。夜間に走らせた何千枚もの図面変換・検図バッチが、最初の1枚目のオープンで永久停止している光景を、私は幾度となく目撃してきた。
今回は、このプロキシオブジェクトにまつわるレガシーな仕様の核心に迫り、システム変数を極限まで制御して完全無人化を実現するアーキテクチャを解説する。
—
プロキシオブジェクトの正体とVBAの無力さ
プロキシオブジェクト(Proxy Object)とは、専用のオブジェクトARXアプリケーションが存在しない環境で、その図面データ構造を維持・表示するために生成される「代理の殻」である。
問題は、これが単なるデータ上の存在にとどまらず、図面オープン(`Documents.Open`)の瞬間にAutoCADのコアエンジンが自動的に整合性チェック走り、GUIスレッドへダイアログの表示を強制する点にある。
VBAの `On Error Resume Next` や、アプリケーションレベルのイベント監視であっても、この「モーダルダイアログの割り込み」はAutoCADのメインプロセス内部で発生するため、VBA側から直接フックして「OKボタンを押す」といった制御は極めて困難、あるいは不安定である。
したがって、アプローチは一つしかない。「ダイアログを出させるな。その前にシステム変数を沈黙させよ」。
—
制御すべき核心のシステム変数
AutoCADには、プロキシの挙動を制御するための極めて重要なシステム変数が存在する。これらはレジストリや図面ファイル(DWG)内部に状態として保持されるが、VBAから動的にねじ伏せることで、警告を完全にバイパスできる。
1. `PROXYNOTICE`(プロキシ通知)
- 役割:未知のプロキシオブジェクトが検出されたときに、警告ダイアログを表示するかどうかを決定する。
- 設定値:`0`(通知しない)、`1`(初回のみ通知)、`2`(毎回通知・デフォルト)
- 極限の知見: バッチ処理においては、これを必ず `0` に設定しなければならない。
2. `PROXYSHOW`(プロキシ表示)
- 役割:プロキシグラフィックスを画面上にどのように表現・描画するかを制御する。
- 設定値:`0`(表示しない・メモリ軽量化)、番地 `1`(バウンディングボックス表示)、`2`(完全表示)
- 極限の知見: 処理速度(パフォーマンス)を極限まで高めたい場合、これを `0` にして不要なジオメトリ計算のオーバーヘッドを排除する。
—
実装コード:完全沈黙型バッチオープナー
以下のコードは、単にファイルを開くだけではない。図面が開かれる「その瞬間」のメモリ安全性と、環境汚染(システム変数の意図しない変更の残留)を防ぐための、シニアエンジニア仕様の堅牢な実装である。
Option Explicit
‘ ==============================================================================
‘ módulo: mProxySilenceController
‘ 概要: プロキシ警告を完全に排除し、安全かつ高速にDWGを開くためのプロシージャ
‘ ==============================================================================
Public Sub OpenDrawingSafely(ByVal targetFilePath As String)
Dim originalProxyNotice As Integer
Dim originalProxyShow As Integer
Dim targetDoc As Document
‘ 1. エラーハンドリングの要塞化
On Error GoTo ErrorHandler
‘ 2. AutoCADの図面環境が存在するかチェック
If Dir(targetFilePath) = “” Then
Err.Raise 53, “OpenDrawingSafely”, “指定されたファイルが存在しません: ” & targetFilePath
End If
‘ 3. 現在のシステム変数を退避(環境汚染の防止)
‘ ※レジストリに保存される変数のため、処理終了後の復元が必須
originalProxyNotice = ThisDrawing.GetVariable(“PROXYNOTICE”)
originalProxyShow = ThisDrawing.GetVariable(“PROXYSHOW”)
‘ 4. 極限設定の適用:プロキシ関連の割り込みを完全封殺
ThisDrawing.SetVariable “PROXYNOTICE”, 0 ‘ 警告ダイアログを一切出さない
ThisDrawing.SetVariable “PROXYSHOW”, 0 ‘ プロキシ図形の描画を抑制しメモリを節約
‘ 5. アプリケーションの画面更新を一時停止(パフォーマンスの極限最適化)
Application.ScreenUpdating = False
‘ 6. 図面のオープン実行
‘ DOCUMENTS コレクションに追加することで、モーダル割り込みを回避しつつバックグラウンドで開く
Set targetDoc = Application.Documents.Open(targetFilePath, False)
‘ — ここに図面に対する実務処理(レイヤー操作、エンティティ抽出など)を記述 —
‘ Debug.Print targetDoc.Name & ” の処理を実行中…”
‘ 7. 処理完了後のクローズ(変更を保存せずに閉じる場合は False)
‘ targetDoc.Close False
GoTo Finally
ErrorHandler:
‘ 致命的な例外が発生した場合のログ出力や緊急処理
MsgBox “図面オープン中に致命的なエラーが発生しました: ” & Err.Description, vbCritical, “API Executor Error”
Finally:
‘ 8. システム変数の原状復帰(極めて重要:これを怠るとユーザーの通常作業環境が破壊される)
On Error Resume Next
ThisDrawing.SetVariable “PROXYNOTICE”, originalProxyNotice
ThisDrawing.SetVariable “PROXYSHOW”, originalProxyShow
‘ 9. 画面描画の復元
Application.ScreenUpdating = True
‘ 10. オブジェクト参照の明示的解放(VBAの肥大化したCOMコンテキストをクリーンに保つ)
Set targetDoc = Nothing
On Error GoTo 0
End Sub
—
アーキテクチャの深層:なぜ「このコード」でなければならないのか
A. システム変数のスコープと揮発性
`PROXYNOTICE` はレジストリ(あるいはアプリケーションのセッション)に書き込まれるシステム変数である。バッチ処理の途中で異常終了(Crash)が発生した場合、`originalProxyNotice` を戻す処理がバイパスされ、ユーザーが後ほど通常操作を行う際に「プロキシ警告が出ない」というセキュリティホールやオペレーションミスを誘発する。
そのため、必ず `On Error GoTo` を活用した Try-Finally パターン をVBAで模倣し、いかなる例外が生じようとも環境変数が元通りになる防壁を張らなければならない。
B. `Application.ScreenUpdating = False` によるメモリと描画の分離
他アプリケーション(Civil 3D等)で生成された巨大なDWGには、膨大なカスタムオブジェクトや未定義のディクショナリが含まれていることが多い。これをプレーンなAutoCADがデフォルト設定(`PROXYSHOW = 1` または `2`)のまま読み込もうとすると、画面の再描画(Viewportの再計算)とオブジェクトの代替グラフィックス生成が同時に走り、メモリリークやフリーズの原因となる。
オープン処理の直前に画面描画を停止させ、プロキシの描画を無効化することで、CPUサイクルとメモリ消費量を最小限(限界値)に抑えることが可能となる。
C. COMオブジェクトのライフサイクル管理
`Set targetDoc = Application.Documents.Open(…)` によって返される `Document` オブジェクトは、AutoCADのC++コアプロセスとVBAのCOMブリッジを跨いで生成される。
処理の最後で `Set targetDoc = Nothing` を明示的に呼び出すことは、VBAランタイムのガベージコレクションに依存せず、COM参照カウンタを即座にデクリメントするためのシニアエンジニアの必須作法である。これを怠ると、大量の図面をループ処理した際に、AutoCAD VBA特有の「メモリ不足(Out of Memory)」エラーに必ず直面することになる。
—
結びにかえて
自動化エンジニアの仕事とは、単に動くコードを書くことではない。「例外が起きる余地そのものをコードの構造で焼き尽くす」ことである。
プロキシオブジェクトの警告という、一見するとGUIの制限に阻まれたように見える問題も、AutoCADの内部アーキテクチャとシステム変数のライフサイクルを正しく理解していれば、完全に無力化できる。この知見をあなたの自動化パイプラインに組み込み、真の「完全無人・24時間稼働」の図面処理基盤を完成させてほしい。
