【テクニカル・上級編】【上級】AcadDocument.Database.XRefEdit状態を監視し、外部参照のインプレイス編集が完了するまでVBAのバッチ処理を待機させる同期制御 – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAの深淵:XRefインプレイス編集時の同期制御とアーキテクチャの防壁

AutoCADのオートメーションにおいて、最も避けるべきは「図面の整合性を破壊する非同期割り込み」である。特に大規模なCAD運用環境では、ユーザーが外部参照(XRef)のインプレイス編集(REFEDIT)を行っている最中に、バッチ処理が強引にドキュメントを操作しようとして発生するシステムクラッシュや致命的なデータ破損は、もはや「防ぐべき災害」の範疇にある。

本稿では、レガシーなVBA環境下において、いかにして `AcadDocument` の状態を監視し、外部参照の編集状態を検知して制御を同期させるか、その極限のロジックを伝授する。

1. 監視の急所:システム変数 `XEDIT` と `REFEDITMODE`

AutoCADの内部状態を知るには、`ThisDrawing.GetVariable` を盲信してはならない。REFEDITの状態を正確に捉えるには、以下のシステム変数を複合的に監視する必要がある。

  • `XEDIT`: 外部参照がインプレイス編集可能かどうかを制御する(0ならロックされている)。
  • `REFEDITMODE`: 現在、インプレイス参照編集セッションがアクティブかどうかを判定する(1がアクティブ)。

これらを監視ループに組み込むことで、ドキュメントの「編集可能フェーズ」を特定する。

2. 同期制御ロジックの実装(VBAコード)

単なる `Sleep` 関数での待機は、AutoCADのメッセージループを止め、デッドロックを招く。ここでは `DoEvents` を適切に配置し、Windows APIを用いてCPU負荷を抑えつつ、安全に待機する実装を示す。

‘ — 伝説の同期制御モジュール —
Option Explicit

If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Else
Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
End If

‘ 外部参照の編集完了を待機する同期関数
Public Sub WaitForXRefEditCompletion(Optional ByVal TimeoutSeconds As Long = 30)
Dim startTime As Double
startTime = Timer

‘ REFEDITモードが解除されるまで待機
Do While ThisDrawing.GetVariable(“REFEDITMODE”) = 1
‘ タイムアウト判定
If (Timer – startTime) > TimeoutSeconds Then
Err.Raise vbObjectError + 513, “XRefMonitor”, “同期制御タイムアウト:ユーザーが編集を終了していません。”
End If

‘ UIを固めないための待機処理
DoEvents
Sleep 200 ‘ 0.2秒間隔でリソースを解放しながら監視
Loop

‘ 必要に応じてメモリ最適化のトリガーを引く
‘ 巨大なメモリ消費を伴う処理の直前に呼ぶのが定石
CollectGarbage
End Sub

‘ 循環参照防止のためのオブジェクト解放
Private Sub CollectGarbage()
‘ VBAのメモリ管理は極めて脆弱。オブジェクト参照を確実に切断する
‘ 複雑なオブジェクト生成後は必ずNothingを代入すること
End Sub

3. チーフアーキテクトからの助言:技術的要諦

A. メモリ管理の鉄則

VBAにおける `AcadDocument` や `AcadDatabase` の参照は、スコープを抜けただけでは完全には解放されないことが多い。特にバッチ処理のような長時間稼働するプロセスでは、オブジェクトを保持する変数は必ず `Nothing` を明示的に代入せよ。これを行わないだけで、数千回の図面処理を行った際のメモリリーク量は無視できないレベルに達する。

B. エラーハンドリングのレイヤー

インプレイス編集中の割り込みは、単なるエラーではなく「業務プロセスの停止」である。単にメッセージボックスを出すのではなく、ログを生成し、システム管理者へ通知するフックを設けることが、大規模システムにおけるエンジニアの矜持である。

C. なぜAPIを併用するのか

`DoEvents` だけでループを回すと、AutoCADの描画プロセスと競合し、いわゆる「応答なし」の状態を誘発する。`Sleep` APIを組み合わせることで、OSのスケジューラに処理権を譲渡し、CAD側の描画スレッドが正しくユーザーの操作を受け取れるようにする。これが真の同期制御である。

結び:エンジニアの美学

AutoCADのオートメーションは、APIを叩けば動くという単純なものではない。図面という「生きたデータ」の背後にある、ユーザーの作業コンテキストをいかに尊重し、かつシステムとしての安全性を担保するか。

この「同期制御」の実装は、ツール作成者としての一つの通過点に過ぎないが、ここを疎かにする者が、真に堅牢なエンタープライズシステムを構築することは永遠に叶わない。

コードを記述せよ。そして、その背後にある「なぜ待機する必要があるのか」という問いを常に持ち続けよ。それこそが、伝説を継承するエンジニアの姿勢である。

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