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という巨大なエンジンの「呼吸」を読み取るのだ。
君のコードが、今日もどこかで誰かの作業時間を削り、最適化されていることを願う。健闘を祈る。
