【テクニカル・上級編】【実務中級者向け】図面オープン時の「プロキシオブジェクト」警告ダイアログをシステム変数で抑制する – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD自動化の壁を砕く:プロキシ警告を無力化し、DWG処理を完全自動化する極意

AutoCADの自動化において、最も忌むべきは「処理の停止」だ。
アドオンソフトで作成された未知のオブジェクト、あるいは他社から送られてくる素性の知れない図面。これらを開く際に画面を覆う「プロキシ情報」のダイアログは、我々エンジニアにとっての死神だ。

バッチ処理を仕掛けた翌朝、出社してみれば画面がダイアログで埋め尽くされ、処理が開始から数秒で停止している……そんな惨状を経験したことはないだろうか。

今回は、この「見えない壁」をシステム変数で完封し、さらにメモリアロケーションの観点から安定性を極限まで高める方法を伝授する。

—

1. プロキシ抑制の正攻法:システム変数の「真の制御」

プロキシダイアログを止めるには `PROXYNOTICE` を制御するのが定石だが、実はこれだけでは不十分だ。環境によっては `PROXYGRAPHICS` や `FILEDIA` が絡み合い、意図せぬ挙動を引き起こす。

真のアーキテクトは、単に値を書き換えるのではなく、「処理開始前の状態を記憶し、終了後に確実に復帰させる」というプロトコルを遵守する。

実装コード:堅牢なオープン処理の定石

‘ AutoCAD VBA: プロキシ警告を無力化して図面をサイレントオープンする
Public Sub OpenDrawingSecurely(ByVal filePath As String)
Dim acadApp As Object
Dim acadDoc As Object

‘ 既存のシステム変数を退避(スタック構造のシミュレーション)
Dim originalProxyNotice As Integer
Dim originalFileDia As Integer

Set acadApp = Application

‘ プロキシ警告を抑制 (0: 非表示)
originalProxyNotice = acadApp.GetVariable(“PROXYNOTICE”)
acadApp.SetVariable “PROXYNOTICE”, 0

‘ ファイルダイアログを抑制 (0: コマンドライン実行)
originalFileDia = acadApp.GetVariable(“FILEDIA”)
acadApp.SetVariable “FILEDIA”, 0

On Error GoTo ErrorHandler

‘ 図面を開く
Set acadDoc = acadApp.Documents.Open(filePath)

‘ 【重要】処理が終わったら即座にリセット
‘ ここで例外が発生しても復帰できるよう、処理の整合性を担保する

Cleanup:
acadApp.SetVariable “PROXYNOTICE”, originalProxyNotice
acadApp.SetVariable “FILEDIA”, originalFileDia
Exit Sub

ErrorHandler:
MsgBox “図面オープン中に致命的なエラーが発生しました: ” & Err.Description
Resume Cleanup
End Sub

—

2. メモリ最適化:VBAが抱える「ゾンビオブジェクト」を消し去れ

VBAはガベージコレクションが脆弱だ。AutoCADのCOMオブジェクトは、明示的に `Nothing` を代入しても、内部のポインタが解放されないケースが多々ある。特にループ内で `Documents.Open` を繰り返す処理では、メモリリークが蓄積し、数千枚の図面処理で必ずAutoCADはクラッシュする。

極限の知見:オブジェクトのライフサイクル管理

`Set acadDoc = Nothing` だけで満足してはいけない。以下の手法を取り入れることで、メモリ消費の安定化を図る。

  • 明示的なメモリフラッシュ: `DoEvents` を適切に挟み、Windows OSへのコンテキストスイッチを促す。
  • クリーンアップの徹底: 処理終了後は `acadDoc.Close False` を行い、ドキュメントのライフサイクルを強制終了させる。

—

3. レガシー環境への配慮:Windows APIの介入

もし、どうしてもシステム変数が効かない特殊な環境(古いAutoCADやカスタマイズされた垂直アプリケーション)に遭遇した場合は、Windows APIを使用してダイアログのウィンドウハンドル(HWND)を直接探し出し、プログラム的に「閉じる」という荒技が必要になる。

これを行うには `FindWindow` や `SendMessage` を駆使するが、これは最終手段だ。

‘ APIを使用したウィンドウ強制クローズの概念
Private Declare PtrSafe Function FindWindow Lib “user32” Alias “FindWindowA” _
(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
‘ ※注意:AutoCADのダイアログクラス名はバージョンにより変動するため、
‘ Spy++等で調査した上で実装すること。

—

チーフアーキテクトの提言

自動化の現場において「例外」は必ず発生する。我々が書くコードは、正常系を動かすためのものではなく、「異常系をいかに無音で通過させるか」のために存在する。

1. システム変数は必ずバックアップを取れ。
2. ループ処理では必ず `DoEvents` を使い、OSの息継ぎをさせろ。
3. ダイアログは表示される前に「存在」を封じ込めろ。

この3点を守るだけで、君のAutoCAD自動化システムは、夜通し止まることのない強固なエンジンへと進化するはずだ。技術は裏切らない。コードの隅々にまで、君の意志を刻み込め。

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