【テクニカル・上級編】【初心者向け】FILEDIAシステム変数の制御:VBA実行中にファイル選択ダイアログで処理が止まるのを防ぐ方法 – AutoCAD VBA解析バイブル

スポンサーリンク

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

【第1回】FILEDIAの支配:ファイル選択ダイアログの呪縛を断ち、完全バックグラウンド処理を実現せよ

AutoCAD VBAによる業務自動化において、最も初歩的でありながら、最も多くの開発者が実務の現場で絶望の淵に立たされる瞬間がある。それが、`Open` メソッドや `SaveAs` メソッドを実行した瞬間に、突如として画面上に現れる「ファイル選択ダイアログ」だ。

「夜間に数百枚の図面をバッチ処理する仕組みを作ったはずが、朝出社したら最初の1枚目のダイアログで処理がフリーズ(停止)していた」
「ユーザーの操作ミスを誘発し、予期せぬパスにファイルが上書き保存されてしまった」

これらは、AutoCADのコアアーキテクチャに対する理解の欠如が生んだ人災に他ならない。
今回は、図面ファイル(DWG/DXF)のオープン・セーブ・バージョン互換制御における極限の知見として、システム変数 `FILEDIA` を完全に手懐け、ダイアログの呪縛を断ち切るための実践的アプローチを解説する。

—

なぜ `FILEDIA` は業務自動化の最大の障壁なのか?

AutoCADの内部には、ユーザーインタフェース(UI)の挙動を制御する数多のシステム変数が存在する。その中でも `FILEDIA` は、ファイルダイアログボックスの表示・非表示を切り替えるスイッチである。

  • `FILEDIA = 1` (デフォルト):コマンドラインからのファイル操作時に、Windowsの標準的なファイル選択ダイアログを表示する。
  • `FILEDIA = 0`:ダイアログを一切表示せず、すべてコマンドライン(またはVBAのコード内)からのテキストベースの入力を受け付ける。

VBAから `Documents.Open` や `Document.SaveAs` を実行する際、適切なメソッドや引数を使用していれば本来はダイアログは回避できる。しかし、古いレガシーコードの流用、あるいは `SendCommand` を併用する泥臭い実装において、この `FILEDIA` が `1` のまま放置されていると、AutoCADは容赦なくGUIスレッドをブロックし、VBAの実行を完全に停止させる。

シニアエンジニアたる者、UIスレッドのブロックは「バグ」と同義であると心得よ。自動化スクリプトは、常に無人(ヘッドレス)環境での完結を前提に設計されなければならない。

—

実装パターン:`FILEDIA` 制御のベストプラクティス

単に `FILEDIA` を `0` にすれば良いわけではない。VBAの実行中にエラーが発生した場合や、予期せぬ中断が起きた際、システム変数が `0` のまま固定されてしまうと、翌日からの通常業務でユーザーが図面を開けなくなるという致命的な二次災害を引き起こす。

したがって、「例外処理(Error Handling)を伴う確実なステート管理」が必須となる。

以下に、実務の現場で即座に採用できる、堅牢性を極めたコードを示す。

Option Explicit

”’

”’ 指定したフォルダ内の全DWGファイルをサイレント(ダイアログなし)で開き、
”’ 特定の処理を行って別名で保存する実務特化型プロシージャ
”’

Public Sub BatchProcessDrawings()
Dim targetFolder As String
Dim targetFile As String
Dim doc As AcadDocument

‘ 制御対象のフォルダパス(環境に合わせて変更すること)
targetFolder = “C:\AutoCAD_Work\Target\”

‘ — 【重要】現在のシステム変数を退避 —
Dim originalFileDia As Integer
Dim originalCmdEcho As Integer

originalFileDia = ThisDrawing.GetVariable(“FILEDIA”)
originalCmdEcho = ThisDrawing.GetVariable(“CMDECHO”)

‘ エラーハンドラーの有効化(環境復旧の担保)
On Error GoTo ErrorHandler

‘ — 【核心】UIブロックの無効化 —
ThisDrawing.SetVariable “FILEDIA”, 0
ThisDrawing.SetVariable “CMDECHO”, 0

‘ フォルダ内のDWGファイルをループ処理
targetFile = Dir(targetFolder & “.dwg”)

Do While targetFile <> “”
‘ ダイアログを出さずにバックグラウンドで図面を開く
Set doc = Documents.Open(targetFolder & targetFile)

‘ — ここに図面に対する処理を記述 —
‘ 例: 画層の整理や属性情報の抽出など
Call ExecuteCustomLogic(doc)

‘ 上書き保存(またはバージョンを指定した名前付け保存)
‘ FILEDIA = 0 の環境下では、SaveAsはダイアログを出さずに実行される
doc.SaveAs targetFolder & “Processed_” & targetFile

‘ ドキュメントの明示的なクローズ(メモリリーク防止の極意)
doc.Close False
Set doc = Nothing

‘ 次のファイルへ
targetFile = Dir
Loop

CleanUp:
‘ — 【極限の作法】システム変数の確実な原状復帰 —
ThisDrawing.SetVariable “FILEDIA”, originalFileDia
ThisDrawing.SetVariable “CMDECHO”, originalCmdEcho
Exit Sub

ErrorHandler:
‘ 予期せぬ例外発生時でも確実にAutoCADの状態を復元する
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “AutoCAD VBA Error”
Resume CleanUp

End Sub

Private Sub ExecuteCustomLogic(ByRef targetDoc As AcadDocument)
‘ 渡されたドキュメントオブジェクトに対する操作を記述
‘ 例: targetDoc.ModelSpace へのアクセスなど
Debug.Print “Processing: ” & targetDoc.Name
End Sub

—

シニアエンジニアが知るべき「裏の仕様」とメモリマネジメント

上記のコードにおいて、単に動くというレベルを超えた「プロの知見」をいくつか共有しよう。

1. `Documents.Open` と `Document.Open` の違い

AutoCAD VBAには、アプリケーションレベルの `Documents.Open` と、ドキュメントレベルの操作が存在する。バッチ処理で複数ファイルを扱う場合、親アプリケーション側(`Application.Documents`)から開くのが定石だ。この際、`FILEDIA` が `0` であれば、AutoCADの内部メモリスペースに非表示、あるいは最小限の描画負荷でドキュメントがロードされる。

2. オブジェクトの明示的解放(`Set doc = Nothing`)

AutoCADのCOMラッパーは、VBAのガベージコレクション(GC)だけではメモリを完全に解放しきれないケースが多々ある。特に大量の図面をループ処理するバッチにおいて、`doc.Close` の後に必ず `Set doc = Nothing` を挟み、さらに数千回に一度は `VBA.DoEvents` を挟んでOS側のメモリスタックを解放する配慮が、安定稼働するシステムを生む。

3. バージョン互換制御との合わせ技

`SaveAs` メソッドを使用する際、古いAutoCAD形式(例: AutoCAD 2004図面形式など)で保存したい場合は、`SaveAs` の第二引数に `ac2004_DWG` などの定数を渡すことになる。この際も `FILEDIA = 0` が効いているため、バージョン競合に関する警告ダイアログすらも完全にバイパスされ、高速な機械的変換が可能となる。

—

結びにかえて

自動化の本質は「人間を単純作業から解放すること」である。しかし、ダイアログという名の「人間への問いかけ」がプログラムの途中に挟まるだけで、その自動化は完全な崩壊を迎える。

`FILEDIA` の制御は、AutoCAD VBAを使いこなす上での「リトマス試験紙」にすぎない。システム変数を制する者が、AutoCADのライフサイクルを制す。この知見をあなたの開発環境に即座に組み込み、真のノーウォーカー・オートメーションを実現してほしい。

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