AutoCAD VBAを掌握する極限の知見:プロキシオブジェクト警告の完全制圧
開発プロジェクトのリーダーである私のもとに、よくこんな相談が持ち込まれる。
「VBAで何百枚ものDWGファイルを一括処理するマクロを作ったのだが、外部製CADのカスタムオブジェクトが含まれる図面を開くたびに『プロキシオブジェクト』の警告ダイアログが出て処理が止まってしまう。夜間バッチが組めない」
――非常によくある現場のボトルネックだ。
AutoCADは、Civil 3DやArchitecture、あるいはサードパーティ製アドオンで作成された独自オブジェクト(カスタムエンティティ)が含まれる図面を標準外の環境で開こうとすると、親切心(あるいは安全策)からダイアログを表示する。しかし、完全自動化を目指す我々にとって、この「親切な警告」は業務を停止させる最大の障害(バグ)に他ならない。
今回は、このプロキシオブジェクト警告をシステム変数の深部からハックし、一滴の人間介入も許さない堅牢な自動化パイプラインを構築する極意を伝授する。
—
なぜ「単純に開くだけ」のコードでは破綻するのか?
多くの初中級者が陥る罠がこれだ。
‘ 【アンチパターン】これではプロキシ警告のダイアログを防げない
Dim doc As AcadDocument
Set doc = Documents.Open(“C:\Data\sample.dwg”)
`Documents.Open`メソッドをただ実行したところで、AutoCADのコアエンジンは図面データベースを読み込む際にプロキシの有無を検知し、即座にUIスレッドへ警告ダイアログを描画する。VBAの実行権限はそこで凍結され、ユーザーが「OK」ボタンを押すまでマクロは沈黙する。
ここで重要なのは、「ダイアログを消す」のではなく、「ダイアログを出させない状態にAutoCADの環境を調律する」というアプローチをとる点だ。その鍵を握るのが、システム変数 `EXPERT` および関連するコントロール群である。
—
プロキシ警告を沈黙させるシステム変数の要件
プロキシオブジェクトの振る舞いを制御する上で、ターゲットとなる設定は主に以下の2つだ。
1. `EXPERT` (システム変数)
- コマンドプロンプトや警告プロンプトの表示レベルを制御する。
- 値を `5` 以上に設定することで、いくつかの重大な警告や確認プロンプトを強制的にサイレント(デフォルト動作)にすることが可能。
2. `PROXYNOTICE` (システム変数)
- 図面にプロキシオブジェクトが含まれている場合に、警告通知を最初に表示するかどうかを制御する。
- `0` に設定することで、そもそもプロキシに関する通知ダイアログ自体を出発させない。
しかし、実務の現場では、これらをスクリプトの最初で変更し、エラー発生時や処理終了時に必ず元の状態へ復元(クリーンアップ)するロジックが不可欠だ。これを怠ると、ユーザーの通常作業時にCADの挙動が変わってしまい、クレームの元となる。
—
【プロダクションコード】堅牢なDWG一括処理モジュール
以下に、実務の現場でそのまま組み込める、エラーフリートで堅牢なプロシージャを公開する。
環境の退避・復元(トランザクション的な概念)を `On Error` 構文で確実に担保している点に注目してほしい。
Option Explicit
‘ ==============================================================================
‘ 概要: プロキシオブジェクト警告を完全に抑制し、安全にDWGファイルを開いて処理を行う
‘ 著者: シーフアーキテクト
‘ ==============================================================================
Public Sub BatchProcessWithProxyControl()
Dim targetPath As String
targetPath = “C:\DWG_Storage\TargetDrawing.dwg”
‘ ファイルの存在確認(基本中の基本)
If Dir(targetPath) = “” Then
MsgBox “指定された図面が存在しません: ” & targetPath, vbCritical
Exit Sub
End If
‘ — 1. 環境変数の退避とサイレントモードへの移行 —
Dim originalExpert As Integer
Dim originalProxyNotice As Integer
On Error GoTo ErrorHandler
‘ 現在のシステム変数を退避
originalExpert = ThisDrawing.GetVariable(“EXPERT”)
originalProxyNotice = ThisDrawing.GetVariable(“PROXYNOTICE”)
‘ 【重要】警告とプロキシ通知を強制抑制
‘ EXPERTを5にすることで、通常はユーザー入力を求める危険なプロンプトをバイパス
ThisDrawing.SetVariable “EXPERT”, 5
‘ PROXYNOTICEを0にすることで、プロキシ検出時のポップアップを完全無効化
ThisDrawing.SetVariable “PROXYNOTICE”, 0
‘ — 2. ターゲット図面のオープン —
Dim targetDoc As AcadDocument
Dim openAttempts As Long
‘ 非同期やロック競合を防ぐための堅牢なオープン処理
Set targetDoc = Application.Documents.Open(targetPath)
‘ — 3. 業務ロジックの実行(ここに実際の処理を記述) —
Call ExecuteBusinessLogic(targetDoc)
‘ — 4. クリーンアップ (保存せずに閉じる場合の例) —
‘ targetDoc.Close False ‘ 保存して閉じる場合は True
‘ 環境変数の復元
ThisDrawing.SetVariable “EXPERT”, originalExpert
ThisDrawing.SetVariable “PROXYNOTICE”, originalProxyNotice
MsgBox “図面の自動処理が正常に完了しました。”, vbInformation
Exit Sub
ErrorHandler:
‘ — 異常系ハンドリング: 何があっても環境変数を元に戻す —
On Error Resume Next
ThisDrawing.SetVariable “EXPERT”, originalExpert
ThisDrawing.SetVariable “PROXYNOTICE”, originalProxyNotice
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “Execution Error”
End Sub
‘ 実際の業務処理をカプセル화したモジュール(例)
Private Sub ExecuteBusinessLogic(ByRef doc As AcadDocument)
‘ 例: 図面内のレイアウト数を出力するだけ
Debug.Print “処理中ファイル: ” & doc.Name
Debug.Print “レイアウト数: ” & doc.Layouts.Count
‘ ここにレイヤー操作やブロック置換などの重い処理を記述する
End Sub
—
現場でエンジニアが気をつけるべき「データベースの罠」
プロキシオブジェクトの警告を消去したからといって、「プロキシオブジェクト自体が消えるわけではない」という点に絶対的な注意を払う必要がある。
Civil 3D等のカスタムオブジェクトは、それを生成したアドオンソフト(ARXアプリケーション)がメモリ上にロードされていない環境(純粋な純生AutoCADやVBAの裏側)では、中身が「グラフィック表現を失った、単なるデータの殻(Proxy Entity)」として扱われる。
この状態で図面を上書き保存(`Save` / `Close True`)してしまうと、本来保持されていた高度なCADデータやカスタムプロパティが消失・破損し、元図面が使い物にならなくなるという致命的なデータベース破損事故(サイレントデータコラプション)に繋がる。
リーダーからの厳格な開発指針
1. 読み取り専用(ReadOnly)の原則
プロキシを含む図面を自動処理する場合は、原則として `Application.Documents.Open(Path, True)` のように読み取り専用で開くこと。
2. 無闇な上書き保存の禁止
データを改変するバッチ処理であっても、プロキシが含まれていることが分かっている図面に対しては、意図しないセーブを行わないフロー設計を義務付けること。
—
総括
システム変数の操作は、AutoCAD VBAの自動化において「諸刃の剣」である。
しかし、その挙動を完全に理解し、`On Error` による環境復元の担保と、データベース構造へのリスペクト(読み取り専用の活用など)を持てば、人間の手を一切煩わせない最高峰の業務効率化エンジンが完成する。
ダイアログに阻まれる日々は今日で終わりにしよう。あなたのコードで、真の自動化を現場にもたらしてほしい。
