【上級】AcadApplication.Evalメソッドの魔術:AutoLISPとの境界を突破する極限の技術
AutoCAD VBAを極めようとする者にとって、標準API(ActiveX Automation)の壁にぶつかるのは通過儀礼だ。「なぜ、このプロパティが公開されていないのか?」「なぜ、この複雑な図形情報の取得にこれほどコストがかかるのか?」――その苛立ちは正しい。VBAのAPIは、AutoCADの全機能の6割程度しかカバーしていないからだ。
しかし、我々には「裏口」がある。それが `AcadApplication.Eval` メソッドだ。このメソッドは、AutoCADの魂であるLISPインタープリタをVBAから直接叩くための「橋頭堡」である。
—
1. Evalメソッドの真髄:LISPを武器にする理由
VBAが不得手とする「図形定義データの直接参照(DXFグループコードの高速抽出)」や「AutoCAD内部変数の動的制御」は、LISPの独壇場だ。`Eval` を使えば、VBAの快適な開発環境を維持したまま、LISPのパワーを召喚できる。
この連携の核心は、「文字列として構築したLISP式を、いかに安全かつ高速に実行するか」に集約される。
2. 実装:VBAからLISPを制御するアーキテクチャ
単に `Eval` を呼ぶだけでは素人だ。真のエンジニアは、戻り値の型変換とエラーハンドリング、そしてメモリの解放までを制御する。
以下は、`Eval` を用いて、標準APIでは取得が困難な「特定のシステム変数」や「図形データ」を取得するためのラッパー関数である。
‘ 伝説的なチーフアーキテクトによるEvalラッパー
‘ 戻り値の型をVariantで受け取り、LISPのリスト構造をVBAで解釈する
Public Function ExecuteLisp(ByVal lispStatement As String) As Variant
Dim acadApp As Object
Set acadApp = ThisDrawing.Application
On Error GoTo ErrHandler
‘ EvalはLISPの実行結果をVariantで返す
‘ 文字列として構築されたLISP式をコンテキストに送り込む
ExecuteLisp = acadApp.Eval(lispStatement)
Exit Function
ErrHandler:
‘ LISP実行時の構文エラーや未定義関数をトラップ
Debug.Print “LISP Execution Error: ” & Err.Description
ExecuteLisp = Null
End Function
‘ 使用例:現在のドキュメントの「保存されていない変更」状態をLISP経由で取得
Sub GetDocStatus()
Dim result As Variant
‘ (getvar “DBMOD”) はVBAのAPIで取得しにくい情報を一発で射抜く
result = ExecuteLisp(“(getvar “”DBMOD””)”)
If Not IsNull(result) Then
MsgBox “現在のDBMOD値: ” & result
End If
End Sub
—
3. メモリとオブジェクトのライフサイクル:伝説のエンジニアの流儀
`Eval` を多用すると、AutoCAD内部のメモリ領域(LISPヒープ)を圧迫する可能性がある。また、VBA側のオブジェクト参照が滞留すれば、AutoCADのプロセスは瞬く間に肥大化する。
- 明示的解放の徹底: `Set acadApp = Nothing` は必須。特にCOMオブジェクトをループ内で何度も取得するのは、パフォーマンス上の自殺行為だ。
- 文字列の構築コスト: `Eval` に渡す文字列を頻繁に生成する場合、`StringBuilder` のようなロジック(VBAでは文字列連結の最適化)を意識すること。
- 例外処理の構造化: LISP側でエラーが発生した場合、VBA側まで巻き込まれて落ちるのを防ぐため、必ず `(vl-catch-all-apply …)` をLISP式側に組み込むこと。
LISP側での安全策の例:
;; VBAから呼ぶときは必ずエラーを包む
(vl-catch-all-apply ‘your-function-name (list arg1 arg2))
—
4. 限界を突破せよ:業務自動化への視座
この手法を習得した諸君は、もはや「APIにある機能」だけでシステムを考える必要はない。
- レガシー環境の保守: 古いAutoCADバージョンでAPIが貧弱な場合でも、LISPの `entget` や `ssget` を駆使すれば、最新のAPI並みのデータ抽出が可能になる。
- システム間連携: ExcelからVBAを介し、AutoCADのLISP環境を制御することで、CAD図面を単なる図形から「構造化されたデータベース」へと昇華させることができる。
最後に:諸君への警告
`Eval` は強力な「魔術」だが、乱用すれば保守性は崩壊する。「VBAで完結できることはVBAでやる。VBAにできないことだけをLISPに委託する」という原則を忘れてはならない。
コードは、常にシンプルで、かつ泥臭い現場の要求に応えられる強靭さを持つべきだ。貴殿の構築するシステムが、次の10年を生き抜くアーキテクチャであることを期待している。
――健闘を祈る。
