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

スポンサーリンク

AutoCAD VBAを掌握する:SendCommandの呪縛から脱却し、PostCommandで堅牢なワークフローを構築せよ

AutoCAD VBA開発において、初心者が必ずぶつかる壁が「コマンドの実行タイミング」です。`SendCommand`を多用し、なぜか意図した順序で動かない、あるいはタイミング次第でクラッシュする——そんな現象に頭を抱えたことはないだろうか。

結論から言うと、`SendCommand`は「非同期的な呼び出しのように見えて、実は実行キューの割り込み」という不安定な側面を持つ。本稿では、AutoCADの内部実行モデルを紐解き、`PostCommand`を用いた真に堅牢なコマンド実行手法を伝授する。

1. なぜ SendCommand は「地雷」なのか

多くの開発者が書くコードはこれだ。

‘ 悪い例:典型的な競合リスク
ThisDrawing.SendCommand “_LINE 0,0 100,100 ”
ThisDrawing.SendCommand “_REGEN ”

一見動くように見える。しかし、AutoCADはVBAの実行スレッドとコマンド入力スレッドが密接に干渉し合う。特に、`SendCommand`は「現在のVBA処理を中断してコマンドを割り込ませる」挙動をするため、複雑な処理の途中で呼び出すと、AutoCADの入力バッファが混乱し、最悪の場合、AutoCAD自体がフリーズする。

特に、外部データベースとの連携やファイルI/Oを伴う処理では、「VBAの処理が完了し、AutoCADがアイドル状態になった瞬間にコマンドを投げる」という制御が不可欠となる。ここで登場するのが `PostCommand` だ。

2. PostCommand:イベントループの賢い活用

`PostCommand` は、AutoCADのメッセージキューに対して「このコマンドを次の暇な時に実行してくれ」と予約を入れるメソッドだ。VBAの実行スレッドを即座に開放するため、AutoCAD側の処理とVBA側の処理をクリーンに分離できる。

堅牢な実装パターン:コマンド予約クラス

実務では、単発でコマンドを送るのではなく、「一連の処理が終わった後にまとめて実行する」という設計が正解だ。

‘ 【プロダクションコード例】堅牢なコマンド予約モジュール
Public Sub ExecuteProcessSafely()
‘ 1. VBA側で重い図面編集処理を行う(オブジェクト操作)
‘ この間、AutoCADのコマンドラインは操作しないこと
Dim lineObj As AcadLine
Set lineObj = ThisDrawing.ModelSpace.AddLine(StartPoint, EndPoint)

‘ 2. 処理完了後、REGENやZOOMなどのコマンドをキューに送る
‘ これにより、VBAが完全に終了した後にAutoCADがコマンドを消化する
QueueCommand “_REGEN ”
QueueCommand “_ZOOM _E ”
End Sub

‘ コマンドを予約するラッパー関数
Private Sub QueueCommand(ByVal cmdString As String)
On Error GoTo ErrHandler
‘ AutoCADの実行キューに安全にポストする
ThisDrawing.PostCommand cmdString
Exit Sub

ErrHandler:
Debug.Print “コマンド実行失敗: ” & Err.Description
End Sub

3. なぜこの設計が「プロ」の流儀なのか

非同期実行によるパフォーマンスの最適化

`SendCommand` はコマンドが終了するまでVBAをブロッキング(停止)させる。大量の図形を生成するスクリプトでこれをやると、AutoCADのGUIが反応しなくなり、ユーザーは「ソフトが落ちた」と誤認する。`PostCommand` は非同期的に処理を投げ続けるため、VBA側のループ処理を高速に完遂させ、最後に一気に再描画させるという「高速なバッチ処理」が可能になる。

データベース連携時の整合性

外部DBから属性情報を取得し、AutoCAD上のブロックを更新するようなツールにおいて、`SendCommand` を挟むと、更新途中にコマンドが割り込み、図面内の「未更新の古いデータ」を再描画してしまうことがある。`PostCommand` で全てのデータ更新を完了させてから `REGEN` を実行することで、描画の不整合を完全に排除できる。

4. 現場で避けるべき「アンチパターン」

  • コマンド実行中のPostCommand: コマンド実行中にさらに `PostCommand` を重ねることは避けよ。キューが溢れるだけでなく、実行順序が予測不可能になる。
  • 例外処理の欠如: `PostCommand` は実行結果を即座に返さない。エラーが発生してもVBA側には伝わらないため、実行予定のコマンド文字列が正しいかどうかは、事前に検証(バリデーション)しておく必要がある。

5. チーフアーキテクトからの助言

AutoCAD開発において、最も重要なのは「VBAで完結できることは、VBAでやる(ActiveX API)」ことだ。コマンドは、どうしてもAPIで実現できない機能(例:特定のダイアログ操作や複雑なビュー操作)のためにのみ切り出すべきだ。

`SendCommand` は、手軽だが「諸刃の剣」。
`PostCommand` は、少し玄人向けだが「信頼の礎」。

あなたの書くツールが、単なる「スクリプト」から、現場を止めることのない「堅牢なエンジン」へと昇華することを期待している。次回の開発では、ぜひこのコマンドキューイングの概念を取り入れてみてほしい。コードは、あなたの設計思想を映し出す鏡なのだから。

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