【テクニカル・上級編】【初心者向け】AcadApplication.Visible = False 時の「ダイアログ停止」対策:エキスパート変数を駆使した完全バックグラウンド処理 – AutoCAD VBA解析バイブル

スポンサーリンク

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

【第1回】`AcadApplication.Visible = False` 時の「ダイアログ停止」対策:エキスパート変数を駆使した完全バックグラウンド処理

レガシー環境からモダンなインフラへの移行期において、AutoCADのバッチ処理がいかにフラストレーションの溜まる作業であるかは、現場のエンジニアであれば痛いほど理解しているはずだ。

「夜間に数百枚の図面を一括変換するタスクを組んだのに、朝出社したら未保存の変更に対する警告ダイアログでプロセスが丸一日ハングアップしていた」

この悪夢のような現象は、AutoCAD VBAをバックグラウンド(`Visible = False`)で稼働させた際に見落としがちな、オブジェクトモデルの盲点を突いている。今回は、この致命的なダイアログ停止を完全に封殺し、完全無人のバックグラウンド処理を実現するための「プロの定石」を授けよう。

—

なぜバックグラウンド処理はダイアログで止まるのか?

AutoCADは本質的に「対話型(Interactive)」のCADエンジンである。COM(Component Object Model)経由で `AcadApplication` をインスタンス化し、`Visible = False` に設定したとしても、それはGUI描画レイヤーが隠蔽されたに過ぎない。

エンジン内部のステートマシンは依然としてユーザーからの入力を待ち続けている。

  • 上書き保存時の「ファイルは既に存在します。上書きしますか?」
  • 破損したフォントや外部参照(Xref)が見つからない時の警告
  • 監査(AUDIT)コマンド実行時の「図面のエラーを修正しますか?」

これらはすべて、モーダルダイアログを画面上にポップアップさせようとする。しかし、`Visible = False` の環境下ではダイアログを描画するウィンドウハンドルが存在しないため、プロセスは無限の応答待ち(デッドロック)に陥る。

—

エキスパート変数とファイルダイアログ制御の極意

この問題を解決するには、AutoCADのシステム変数をプログラム側から完全に掌握し、対話プロンプトを強制的に抑制(Suppress)しなければならない。

ここで登場するのが、以下の3つの極秘変数・設定である。

1. `EXPERT` システム変数
通常は「本当に実行しますか?」と聞いてくるコマンドラインのプロンプトを強制的にスルーし、デフォルトの「はい(Yes)」を選択させる。値を `5` に設定するのが定石だ。
2. `FILEDIA` システム変数
ファイル選択ダイアログの表示を強制的に無効化し、コマンドラインからの文字列入力のみでファイル入出力を行わせる(`0`に設定)。
3. `CMDECHO` システム変数
コマンド実行時のログ出力を抑制し、処理速度の向上とメモリ消費の最適化を図る(`0`に設定)。

これらをVBAのコード内で安全に操作し、かつ処理中のエラーや異常終了時であっても確実に元の状態へ復元する(ステートのリストア)設計が、シニアエンジニアに求められる必須要件である。

—

実装コード:完全バックグラウンド・バッチ処理テンプレート

以下のコードは、エラーハンドリングとシステム変数の厳密な退避・復元(トランザクション的なアプローチ)を実装した、実戦投入可能なプロダクションコードだ。

Option Explicit

‘ —————————————————————–
‘ 担当: チーフアーキテクト
‘ 概要: AutoCADを完全非表示で起動し、ダイアログ停止を完全排除してバッチ処理を実行する
‘ —————————————————————–
Public Sub ExecuteHeadlessBatchProcessing()
Dim acadApp As Object
Dim acadDoc As Object
Dim targetFiles As Collection
Dim filePath As Variant

‘ 処理対象ファイルのリストアップ(例としてコレクションを使用)
Set targetFiles = New Collection
targetFiles.Add “C:\CAD_Data\DrawingA.dwg”
targetFiles.Add “C:\CAD_Data\DrawingB.dwg”

On Error GoTo ErrorHandler

‘ 1. AutoCADインスタンスの生成(既存セッションに依存しない独立プロセス)
Set acadApp = CreateObject(“AutoCAD.Application.24”) ‘ バージョンに応じて調整 (24 = AutoCAD 2023/2024)

‘ 2. 画面非表示化(必ずインスタンス化直後に実行)
acadApp.Visible = False

‘ 3. バックグラウンド処理の実行
For Each filePath In targetFiles
‘ 図面を開く(読み取り専用または通常)
Set acadDoc = acadApp.Documents.Open(CStr(filePath), True)

‘ ———————————————————
‘ 【最重要】環境変数の退避と極限設定
‘ ———————————————————
Dim orgExpert As Integer
Dim orgFiledia As Integer
Dim orgCmdecho As Integer

orgExpert = acadApp.GetSystemVariable(“EXPERT”)
orgFiledia = acadApp.GetSystemVariable(“FILEDIA”)
orgCmdecho = acadApp.GetSystemVariable(“CMDECHO”)

‘ ダイアログおよびプロンプトの完全封殺
acadApp.SetSystemVariable “EXPERT”, 5 ‘ すべての警告に「はい」と答える
acadApp.SetSystemVariable “FILEDIA”, 0 ‘ ダイアログを出さずコマンドライン処理にする
acadApp.SetSystemVariable “CMDECHO”, 0 ‘ コマンドエコーバック停止

‘ — ここに実際のバッチ処理を記述 —
‘ 例: 監査実行とパージ
acadDoc.SendCommand “_AUDIT _Y ”
acadDoc.SendCommand “_PURGE _A _N ”

‘ 変更を保存して閉じる
acadDoc.Save
acadDoc.Close False ‘ 変更破棄つきクローズ(Save済みのためFalseで安全に解放)

‘ ———————————————————
‘ 環境変数の即時復元(ドキュメント単位でのクリーンアップ)
‘ ———————————————————
acadApp.SetSystemVariable “EXPERT”, orgExpert
acadApp.SetSystemVariable “FILEDIA”, orgFiledia
acadApp.SetSystemVariable “CMDECHO”, orgCmdecho

Set acadDoc = Nothing
Next filePath

‘ 正常終了処理
acadApp.Quit
Set acadApp = Nothing

MsgBox “すべてのバックグラウンド処理が正常に完了しました。”, vbInformation
Exit Sub

ErrorHandler:
‘ ———————————————————
‘ 異常系ハンドリング:プロセス遺棄(ゾンビプロセス)の防止
‘ ———————————————————
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical

‘ エラー時も可能な限り環境変数を戻し、AutoCADを強制終了させる
On Error Resume Next
If Not acadDoc Is Nothing Then
acadDoc.Close False
Set acadDoc = Nothing
End If

If Not acadApp Is Nothing Then
acadApp.Quit
Set acadApp = Nothing
End If

Err.Clear
End Sub

—

アーキテクトからの警鐘:ゾンビプロセスの恐怖

`AcadApplication.Visible = False` を用いた開発において、最も恐ろしいのは「タスクマネージャーの裏で生き残り続けるゾンビプロセス(Acad.exe)」である。

VBAの実行中に予期せぬエラー(メモリ不足、不正な図面データによるクラッシュなど)が発生し、そのままオブジェクト変数がスコープ外に出ると、Windowsのメモリ上にAutoCADの幽霊プロセスが居座り続ける。これが蓄積すると、サーバーやクライアントPCのメモリリソースを食いつぶし、次回のバッチ処理起動時に致命的な競合を引き起こす。

対策:

1. オブジェクト変数の明示的な解放 (`= Nothing`)
スコープを抜ける前、あるいはエラーハンドラ内では、必ず `AcadDocument` -> `AcadApplication` の逆順で `Nothing` を代入し、COM参照カウントを確実にデクリメントすること。
2. プロセス監視とクリーンアップスクリプトの併用
タスクスケジューラー等でバッチを回す場合は、処理の開始前後に `taskkill /f /im acad.exe` などの安全装置(フェイルセーフコマンド)を挟む運用を強く推奨する。

—

総括

ダイアログ停止という些細に見える問題は、背後にあるAutoCADのアーキテクチャ(対話型エンジンのCOM化)を理解していれば、`EXPERT` と `FILEDIA` の制御によって完全かつエレガントに制圧できる。

コードの行数を削ることよりも、「異常系においてシステムがどう振る舞うべきか」を定義することこそが、プロフェッショナルな業務自動化エンジニアの仕事である。この知見をあなたのシステムに組み込み、真の「完全自動化」を達成してほしい。

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