【テクニカル・上級編】【実務中級】AcadDocument.PostCommandを活用した、SendCommandに代わる安全なコマンド実行 – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAの呪縛を解く:SendCommandの悪夢とPostCommandによる「非同期」の美学

AutoCADのオートメーションにおいて、`SendCommand`は諸刃の剣だ。多くの初学者は、これを「外部からコマンドを打つ魔法の杖」と誤解するが、シニアなエンジニアであれば、その背後にある「同期の罠」と「入力スタックの汚染」に幾度となく苦しめられてきたはずだ。

なぜ、あなたのVBAは時として沈黙するのか? なぜ、特定の環境で突然ハングアップするのか?
答えは単純だ。`SendCommand`は、呼び出し元の処理をブロックし、AutoCADのメッセージキューを無理やり占有しようとするからだ。

今日は、このレガシーな呪縛を断ち切り、堅牢なシステムを構築するための『PostCommand』という名の最適解を伝授する。

1. SendCommandの何が罪深いのか

`SendCommand`は、現在のVBA実行スレッドがAutoCADのコマンドラインに文字列を直接流し込む。一見、素直な挙動に見えるが、これには致命的な欠陥が二つある。

1. 同期の強制: 呼び出し側(VBA)は、コマンドが完了するまで完全に停止する。もしコマンドがユーザー入力待ち(PAUSE)に陥れば、VBAはゾンビと化す。
2. 実行タイミングの不確定性: 複雑な描画更新やレイヤー操作の直後に実行すると、AutoCAD内部のトランザクションが完了する前にコマンドが走り、エラーや未反映を引き起こす。

我々が求めるのは、「VBAの処理を安全に完了させ、その後でAutoCADに主導権を渡す」という設計思想だ。

2. PostCommandがもたらす「非同期」の真髄

`PostCommand`は、コマンドを即座に実行するのではなく、AutoCADのメッセージキューの末尾にコマンドを「投函(Post)」する。

VBAの処理が終わり、CPUが解放された直後、AutoCADはキューを確認し、積まれたコマンドを順次実行する。これにより、VBAのメモリ解放プロセスとAutoCADの描画再開プロセスが、完璧な調和を保って共存できるのだ。

実装例:安全なREGEN実行のテンプレート

以下のコードは、単なるREGENではなく、システムの状態をクリーンに保つための設計図だ。

‘ 伝説的なチーフアーキテクトによる、PostCommandの実装パターン
Public Sub SafeRegenOperation()
Dim acadDoc As AcadDocument
Set acadDoc = Application.ActiveDocument

On Error GoTo ErrorHandler

‘ 1. VBScript側で前処理(図形操作など)を先行させる
‘ ここでオブジェクトの更新が確定する
Debug.Print “データ処理開始…”

‘ 2. メモリ最適化:不要なオブジェクトは明示的にNothingへ
‘ VBAのガベージコレクションを待たず、即座にリソースを解放する
Dim obj As AcadObject
‘ … (何らかの処理)
Set obj = Nothing

‘ 3. PostCommandによる非同期コマンド送出
‘ VBScript側の実行が完全に終了してからREGENが発行される
acadDoc.PostCommand “_REGEN ”

Debug.Print “コマンドをキューに追加しました。VBAは解放されます。”

Exit Sub

ErrorHandler:
MsgBox “エラー発生: ” & Err.Description, vbCritical
End Sub

3. なぜ「PostCommand」でなければならないのか

実務における「システム間連携」を想定してほしい。AutoCAD上の図面を更新し、その結果を外部データベースへ書き出し、最後に画面を再描画する。

もしここで`SendCommand`を多用すれば、AutoCADはコマンドが完了するまで「反応なし」になる。しかし、`PostCommand`であれば、VBAは即座にデータベース処理へ移行できる。

堅牢性を極めるための3つの掟

1. コマンドラインの制御: `PostCommand`に渡す文字列には必ず末尾にスペースか改行コードを含めろ。これは「Enterキー」を意味する。
2. エラーハンドリングの徹底: `PostCommand`自体は非同期ゆえ、失敗してもVBA側では検知できない。コマンドが確実に実行されるか不安な場合は、`Utility.Prompt`を用いて実行ログをコマンドラインに出力し、トレースできるようにせよ。
3. レガシー環境への配慮: 古いバージョンのAutoCADでは、`PostCommand`が未実装の場合がある。その場合はWindows APIの`SendMessage`または`PostMessage`を用いて、AutoCADのウィンドウハンドル(`HWND`)に対し、コマンドライン文字列を直接送り込むという「最終手段」を準備しておくのが、シニアエンジニアの嗜みだ。

結びに:エンジニアの誇りとして

AutoCAD VBAは、もはや枯れた技術かもしれない。しかし、枯れた技術だからこそ、その挙動を完全に制御し、メモリを管理し、非同期処理の機微を理解している者が、圧倒的な生産性を叩き出せる。

`SendCommand`で満足するな。`PostCommand`の向こう側にある、AutoCADという巨大なエンジンの「呼吸」を読み取るのだ。

君のコードが、今日もどこかで誰かの作業時間を削り、最適化されていることを願う。健闘を祈る。

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