AutoCAD VBAを掌握する極限の知見
第4回:プロキシオブジェクト警告の完全制圧 ―― システム変数制御とライフサイクル管理の極意
—
はじめに:なぜプロキシ警告は実務の自動化を殺すのか
大規模なプラント図面、意匠・構造が入り交じる統合モデル、あるいは外部の協力会社から受領したDWGファイル。これらをAutoCAD VBAによるバッチ処理で一括オープンしようとした瞬間、背筋が凍るような経験をしたことはないだろうか。
画面の向こうで静かに佇む「プロキシオブジェクトの警告ダイアログ」。
このモーダルウィンドウが出現した瞬間、VBAの実行スレッドは完全に凍結し、夜間バッチは止まり、エンジニアの自動化への夢は儚く散る。AutoDesk製以外のサードパーティ製アドオン(Architecture, MEP, Civil 3Dなど)で作成されたカスタムオブジェクトが含まれる図面を開く際、AutoCADは親切心からこの警告を出す。しかし、無人運用(Headless Operation)が前提となるエンタープライズ環境において、この「親切心」はシステム障害そのものである。
今回は、このプロキシ警告の根源をシステム変数とAutoCADの内部ライフサイクルから解き明かし、実務で絶対に破綻しない完全自動オープン・ルーチンを構築する。
—
1. プロキシ警告のメカニズムと `EXPERT` の真実
多くの初学者は、エラーハンドリング(`On Error Resume Next`)でこのダイアログをやり過ごそうとするが、無駄だ。モーダルダイアログはVBAのエラーハンドリングの枠外、つまりAutoCADのエディタセッションそのものをブロックする。
ここで鍵となるのが、AutoCADの動作を制御する中枢システム変数 `EXPERT` である。
`EXPERT` 変数の挙動マトリクス
`EXPERT` は、AutoCADが通常ユーザーに確認を求める「危険な操作」や「警告」をどの程度サイレントに処理するかを決定する。
- `EXPERT = 0`: すべてのプロンプトと警告を表示する(デフォルト)。
- `EXPERT = 1`: 「本当に図面を上書きしますか?」などのファイル保存時の警告を抑制する。
- `EXPERT = 3`: LISP等の `UNDO` グループに関連する警告を抑制する。
- `EXPERT = 5`: プロキシオブジェクトの警告、および消去に関する警告を完全に抑制し、デフォルトの動作(通常は「プロキシを表示する」)を強制する。
実務におけるバッチ処理では、図面を開く直前に `EXPERT` を `5`(または環境によってはより厳格な `4` や `5`)に引き上げ、処理完了後(あるいはエラー発生時のクリーンアップブロック)に必ず元の値へ復元するアプローチが鉄則となる。
—
2. 【実装コード】プロキシ警告を完全に無効化する安全なドキュメントオープナー
以下に提供するコードは、単に `EXPERT` を書き換えるだけではない。予期せぬエラーやVBAの強制終了時にも AutoCAD の環境が汚染されないよう、エントリポイントでの状態保存と確実な復元(RAIIパターンを模したエラータスク管理)を実装したプロダクション品質のコードである。
Option Explicit
‘ ==============================================================================
‘ モジュール名: mProxyAutoOpener
‘ 概要: プロキシオブジェクトの警告を完全に抑制し、安全にDWGを開く実務向けルーチン
‘ 著者: チーフアーキテクト
‘ ==============================================================================
Public Sub OpenDrawingWithoutProxyWarning(ByVal targetFilePath As String)
Dim originalExpert As Integer
Dim originalDisplayAlerts As Boolean
Dim targetDoc As Document
‘ 1. ファイルの存在確認 (FileSystemObjectによる堅牢なチェック)
If Not CheckFileExists(targetFilePath) Then
MsgBox “指定された図面ファイルが存在しません: ” & targetFilePath, vbCritical, “致命的エラー”
Exit Sub
End If
‘ 2. 現在の環境状態を退避 (State Preservation)
On Error GoTo ErrorHandler
‘ AutoCADのシステム変数 EXPERT を退避
originalExpert = CInt(ThisDrawing.GetVariable(“EXPERT”))
‘ Excel等から操作している場合を考慮し、AutoCADのアラート表示設定も退避
originalDisplayAlerts = Application.DisplayAlerts
‘ 3. 領域の厳格化(プロキシ警告の抑制とサイレントモード移行)
‘ EXPERTを5に設定することで、プロキシオブジェクトに関するダイアログを黙殺する
ThisDrawing.SetVariable “EXPERT”, 5
Application.DisplayAlerts = False
‘ 4. ドキュメントのオープン実行
‘ Documents.Open メソッドは既存のセッションに新しいドキュメントをロードする
Set targetDoc = Application.Documents.Open(targetFilePath)
‘ 5. 開いたドキュメントに対する初期処理(必要に応じて記述)
‘ 例: ログの記録や、特定レイヤの確認など
Call ExecuteBatchProcessOnDocument(targetDoc)
‘ 正常終了時のクリーンアップへ
GoTo SafeExit
ErrorHandler:
‘ 異常系ハンドリング: ログ出力や管理システムへの通知をここに記述
MsgBox “図面のオープン中に致命的な例外が発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー説明: ” & Err.Description, vbCritical, “AutoCAD VBA 実行エラー”
SafeExit:
‘ 6. 環境の復元 (State Restoration) – いかなる場合も必ず実行されること
‘ エラーが発生していようとも、CADの環境を元の状態に戻すのはシニアの責務である。
On Error Resume Next
ThisDrawing.SetVariable “EXPERT”, originalExpert
Application.DisplayAlerts = originalDisplayAlerts
‘ オブジェクト変数の明示的解放 (Memory Hygiene)
Set targetDoc = Nothing
On Error GoTo 0
End Sub
Private Function CheckFileExists(ByVal filePath As String) As Boolean
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
CheckFileExists = fso.FileExists(filePath)
Set fso = Nothing
End Function
Private Sub ExecuteBatchProcessOnDocument(ByRef doc As Document)
‘ ここにドキュメントに対して行う実処理を記述
‘ 例: doc.SaveAs など
Debug.WriteLine “処理中: ” & doc.Name
End Sub
—
3. チーフアーキテクトが指摘する「メモリ管理とライフサイクル」の急所
上記のコードにおいて、単なる「動くコード」と「プロフェッショナルなコード」を分ける境界線はどこにあるか。それはオブジェクトのライフサイクル管理と環境変数のスコープ管理にある。
A. オブジェクトの明示的解放 (`Set targetDoc = Nothing`)
VBAのランタイムはガベージコレクション(GC)の挙動が曖昧である。特にAutoCADのCOMオブジェクト(`Document`, `AcadDatabase`など)は背後にC++の重厚なARX/ObjectARXのオブジェクトツリーを抱えている。
`targetDoc` 変数を適切に解放せずスコープを抜けると、COM RCW(Runtime Callable Wrapper)の参照カウントが宙ぶらりんになり、メモリリークを引き起こすだけでなく、次回の図面オープン時に「Lockfileが解除されない」「ファイルが使用中である」という致命的なI/Oロックエラーを引き起こす。処理の終端では必ず `Set targetDoc = Nothing` を行い、COM参照を断ち切るべきだ。
B. エラー時における環境の「汚染」防止
もし、`EXPERT = 5` に設定した状態で何らかのVBAランタイムエラーが発生し、`ErrorHandler` をスルーしてプログラムが停止したらどうなるか?
ユーザーのAutoCADセッションは `EXPERT = 5` のまま放置される。この状態では、ユーザーが手動で危険な操作(全エンティティの削除や不正なスキーマのインポートなど)を行っても、AutoCADは一切警告を発しなくなる。これはCAD管理者にとって悪夢のようなセキュリティホールであり、データ破損の温床となる。
ゆえに、前述のコードのように `On Error Resume Next` を挟んだ厳格な `SafeExit` ブロックで確実に元の値を復元させなければならない。
—
4. レガシー環境とバージョン互換への配慮
AutoCAD VBAを運用する上で避けて通れないのが、「異なるAutoCADバージョン(例: AutoCAD 2018 と AutoCAD 2024)が混在する環境」での動作保証である。
サードパーティ製オブジェクトのプロキシグラフィックスは、バージョンが変わるごとにスキーマ定義が微妙に異なる場合がある。
もし特定のバージョン(例:Civil 3Dのオブジェクトを純粋なAutoCADで開くなど)で `EXPERT = 5` でも防ぎきれないダイアログが発生する場合、AutoCADのもう一つの強力なシステム変数 `PROXYNOTICE` を併用する必要がある。
- `PROXYNOTICE`: プロキシが検出されたときに通知バルーン(トレイ通知)を表示するかどうかを制御する(`0`で非表示)。
必要に応じて、オープンの直前に以下の一行を追加することで、GUIの揺らぎを完全に排除できる。
‘ プロキシが検出された際のトレイ通知すらも完全に抹殺する
ThisDrawing.SetVariable “PROXYNOTICE”, 0
—
総括
自動化システムの信頼性は、華やかなアルゴリズムや複雑な処理ロジックではなく、こうした「予期せぬ割り込み(ダイアログや例外)をいかにして完全に排除するか」という泥臭い環境制御の精度によってのみ担保される。
プロキシ警告ごときに夜間バッチを止められる時代は終わった。
システム変数を掌握し、オブジェクトのライフサイクルを支配した者だけが、真の「安定稼働するAutoCAD自動化基盤」を手に入れることができる。
次回の極限知見にも期待してほしい。
