【実務・中級編】【実務中級者向け】図面オープン時の「プロキシオブジェクト」警告を完全に沈黙させるシステム変数操作 – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見

【実務中級者向け】図面オープン時の「プロキシオブジェクト」警告を完全に沈黙させるシステム変数操作

アーキテクトの君なら、日々のバッチ処理や自動化スクリプトの実行中に、こんな悪夢に直面したことがあるはずだ。

「よし、数百枚の図面を一括処理するマクロを走らせた。これで定時で帰れる……」
翌朝、出社してディスプレイを確認すると、処理は最初の1枚目で完全にフリーズしている。原因は、Civil 3Dや他社製アドオンオブジェクトが含まれる図面を開いたときにポップアップする、あの忌々しい「プロキシ情報」の警告ダイアログだ。

人間がクリックしなければ1歩も進まないこのダイアログは、完全自動化の最大の敵である。
今回は、AutoCADの内部ライフサイクルとシステム変数の機微を完全に掌握し、この割り込み地獄をコードの力で完全に沈黙させる極限のテクニックを伝授しよう。

—

なぜ `Workbooks.Open` のような単純なコードでは防げないのか?

Excel VBAであれば `Application.DisplayAlerts = False` を挟むだけで大抵の警告は消せる。しかし、AutoCAD VBA(ActiveX Automation)の領域において、この甘い考えは命取りになる。

AutoCADのドキュメントオープン処理(`Documents.Open`)は、COMの境界を越えてネイティブの図面データベースローダを呼び出す。この時、図面内に「現在の環境にないオブジェクト(プロキシオブジェクト)」が検出されると、AutoCADのコアエンジンは律儀にユーザーへの確認ダイアログを強制発動させる。

ここで重要なのは、「図面を開いた後」にシステム変数を変更しても遅すぎるという事実だ。ダイアログは図面がロードされる「その瞬間」にポップアップするため、ロード処理そのものをコントロールする要塞を築く必要がある。

—

制御の要:レジストリとセッション変数 `PROXYNOTICE` / `PROXYSHOW`

この現象を制御する鍵は、以下の2つのシステム変数にある。

1. `PROXYNOTICE`(プロキシ警告の表示制御)

  • `0`: プロキシが検出されても警告ダイアログを出さない。
  • `1`: プロキシが検出された場合に警告ダイアログを表示する(デフォルト)。

2. `PROXYSHOW`(プロキシの視覚表現制御)

  • `0`: プロキシオブジェクトを表示しない。
  • `1`: バウンディングボックス(枠)を表示する。
  • `2`: 通常通りプレビュー表示する。

ここでプロフェッショナルとして知っておくべき極限の知見がある。
`PROXYNOTICE` は図面ごとの設定(レジストリまたはDWG内保持)ではなく、AutoCADセッション全体の環境変数(レジストリ)として機能する側面を持つが、図面オープン時の判定には「図面データベース読み込み時のグローバルステータス」が強く影響する。

したがって、ファイルを `Open` する直前に、アプリケーションスコープでこれらのシステム変数を明示的に書き換え、処理終了後には必ず元の状態にロールバックするという厳格なトランザクション管理が求められる。

—

プロダクションコード:堅牢な一括図面オープン&自動処理エンジン

現場のトラブルシューティングでそのまま使える、洗練されたプロダクションコードを提示する。エラーハンドリング(トランザクションの確実な復元)を組み込んだ、バグの起きない設計だ。

Option Explicit

” =================================================================
” 概要: プロキシ警告ダイアログを完全抑制し、安全に図面を一括処理するエンジン
” ターゲット: AutoCAD 2020以降 / VBA
” =================================================================
Public Sub BatchProcessDrawingsWithNoProxyAlerts()
Dim targetFolder As String
targetFolder = “C:\AutoCAD_Data\TargetDrawings\” ‘ 処理対象のフォルダパス

If Dir(targetFolder, vbDirectory) = “” Then
MsgBox “指定されたフォルダが存在しません。”, vbCritical, “パスエラー”
Exit Sub
End If

‘ — 1. 退避すべきシステム変数の初期値をキャプチャ —
Dim originalProxyNotice As Integer
Dim originalProxyShow As Integer
Dim originalAlerts As Integer

On Error GoTo ErrorHandler

‘ アプリケーションの動作安定化のため、画面描画とアラートを一時停止
originalProxyNotice = ThisDrawing.GetVariable(“PROXYNOTICE”)
originalProxyShow = ThisDrawing.GetVariable(“PROXYSHOW”)

‘ — 2. 鉄壁の防御体制:システム変数を「警告沈黙モード」に変更 —
ThisDrawing.SetVariable “PROXYNOTICE”, 0 ‘ プロキシ警告ダイアログを出さない
ThisDrawing.SetVariable “PROXYSHOW”, 0 ‘ 無駄なグラフィック計算を省き高速化

Dim fileName As String
fileName = Dir(targetFolder & “.dwg”)

Dim doc As AcadDocument
Dim processedCount As Long
processedCount = 0

‘ — 3. メインループ:安全なドキュメントライフサイクル管理 —
Do While fileName <> “”
Dim fullPath As String
fullPath = targetFolder & fileName

Debug.Print “処理中: ” & fileName

‘ 読込専用(ReadOnly = True)で安全にオープン
‘ ここでPROXYNOTICE=0が効いているため、Civil 3D図面であってもダイアログは一切出ない
Set doc = Application.Documents.Open(fullPath, True)

‘ ———————————————————
‘ ここに図面に対する実際の自動化処理を記述する
‘ 例: 独自のレイヤ追加、属性データの抽出など
‘ ———————————————————
Call ExecuteCustomDrawingLogic(doc)

‘ 変更を保存せずに(読込専用のため)安全にクローズ
doc.Close False
Set doc = Nothing

processedCount = processedCount + 1
fileName = Dir() ‘ 次のファイルへ
Loop

‘ — 4. 正常終了時のシステム変数復元 —
Call RestoreSystemVariables(originalProxyNotice, originalProxyShow)

MsgBox “バッチ処理が正常に完了しました。” & vbCrLf & _
“処理ファイル数: ” & processedCount & “件”, vbInformation, “完了”
Exit Sub

ErrorHandler:
‘ 異常終了時でも必ずシステム変数を元に戻す(死活管理の鉄則)
Call RestoreSystemVariables(originalProxyNotice, originalProxyShow)

If Not doc Is Nothing Then
On Error Resume Next
doc.Close False
Set doc = Nothing
End If

MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “異常終了”
End Sub

” —————————————————————–
” プライベートヘルパー: カスタム処理の分離(単一責任の原則)
” —————————————————————–
Private Sub ExecuteCustomDrawingLogic(ByRef targetDoc As AcadDocument)
‘ 例として、モデル空間の図形数をイミディエイトに出力
Dim entCount As Long
entCount = targetDoc.ModelSpace.Count
Debug.Print ” -> エンティティ数: ” & entCount
End Sub

” —————————————————————–
” プライベートヘルパー: システム変数の確実なリストア
” —————————————————————–
Private Sub RestoreSystemVariables(ByVal proxyNoticeVal As Integer, ByVal proxyShowVal As Integer)
On Error Resume Next
ThisDrawing.SetVariable “PROXYNOTICE”, proxyNoticeVal
ThisDrawing.SetVariable “PROXYSHOW”, proxyShowVal
On Error GoTo 0
End Sub

—

チーフアーキテクトからの実務アドバイス:なぜこの設計なのか?

1. エラーハンドリングにおける「状態の保証」
もしマクロの途中で予期せぬエラー(メモリ不足や不正なDWGファイル等)が発生した場合、`PROXYNOTICE` が `0` のまま放置されると、将来的に通常のオペレーションでユーザーが図面を開いた際、本来気づくべきプロキシの存在を見落とすという重大なヒューマンエラー誘発リスクを生む。
上記のコードでは、`ErrorHandler` を必ず経由させて環境を元の状態にリストアする設計(RAIIイディオムのVBA的解釈)を徹底している。

2. `Documents.Open` の第2引数(ReadOnly)の活用
自動化スクリプトでファイルをオープンする際、書き込み権限を保持したまま開く必要はほとんどない。`True`(読込専用)を指定することで、ファイルロックの競合を防ぎ、ネットワークドライブ経由での処理速度を劇的に向上させることができる。

—

まとめ

プロキシ警告ごときに、君の大切な開発工数や夜間バッチの安定性を奪われてはならない。
システム変数のライフサイクルをコードで完全に支配下置き、誰の手も煩わせない真の「完全無人化パイプライン」を構築してほしい。

次回の極限の知見もお楽しみに。

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