【入門編】【上級】AcadApplication.Evalメソッドの魔術:VBAからAutoLISP関数を呼び出しAPIの限界を突破する – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAの限界を突破せよ:AcadApplication.EvalでAutoLISPの「魔術」を操る

こんにちは。AutoCADの自動化の世界へようこそ。
日々VBAで業務効率化に取り組んでいると、必ずと言っていいほど「VBAのAPIだけでは手が届かない領域」にぶつかります。「あのアドオンやコマンドでしか取得できない情報が、VBAから取れればいいのに……」と悔しい思いをしたことはありませんか?

今日は、そんな壁を軽々と乗り越えるための「裏技」――`AcadApplication.Eval` メソッドについて解説します。これを知れば、あなたはVBAの制約から解放され、AutoCADの全機能を掌握するエンジニアへの第一歩を踏み出せます。

1. なぜ「Eval」が必要なのか?

AutoCADには二つの顔があります。

  • VBA (ActiveX Automation): オブジェクト指向で扱いやすいが、機能が限定的。
  • AutoLISP: AutoCADの歴史そのものであり、コマンドの深淵部やシステム変数、特異な図形情報へのアクセスが極めて強力。

VBAでどうしても解決できない「痒い所」は、AutoLISPなら一行で書けることが多々あります。`Eval`メソッドは、VBAという言語の中から、AutoLISPのエンジンを直接呼び出し、結果をVBAに持ち帰るための「架け橋」なのです。

2. 禁断の魔術:Evalの基本構造

`Eval`は、文字列として渡されたAutoLISP式を評価し、その結果をVBA(バリアント型)として返します。

実践:図面上のシステム変数を取得する

例えば、VBAの`GetVariable`では取得しにくい特殊な情報を、LISP式を介して取得してみましょう。

Sub GetLispValue()
Dim acadApp As Object
Set acadApp = ThisDrawing.Application

‘ LISP式を文字列として組み立てる(ここでは例として現在の作図モードを取得)
‘ ※LISPの (getvar “…”) を実行する式
Dim lispExpression As String
lispExpression = “(getvar “”OSMODE””)”

‘ Evalで実行し、結果をVBAで受け取る
Dim result As Variant
result = acadApp.Eval(lispExpression)

MsgBox “現在のOSNAP設定値は: ” & result
End Sub

このコードの「魂」

  • Evalは文字列を食べる: 渡すのはあくまで「文字列」です。LISPの構文ルール(括弧の閉じ忘れなど)には細心の注意を払ってください。
  • 戻り値はVariant: LISP側が返すデータ型(整数、実数、文字列、リスト)によって戻り値が変わります。`VarType`関数などで型をチェックする癖をつけると、エラーを未然に防げます。

3. 陥りやすい罠:エラーを回避する「賢者の心得」

Evalを使う際、初学者が最もハマるポイントは「エラーハンドリングの欠如」です。

1. 構文エラー: LISPのカッコが足りないとAutoCAD自体が沈黙したり、VBAが実行時エラーを吐きます。必ず`On Error Resume Next`を局所的に使い、実行結果が期待通りか確認してください。
2. 型変換の不一致: LISPはリスト `(list 1 2 3)` を返すことがよくあります。VBA側でこれを単純な変数に代入しようとすると失敗します。配列として受け取る準備を忘れないでください。

4. 応用編:VBAの限界を突破する実戦コード

例えば、「画層のロック状態を一括で取得したい」といった場合、VBAでループを回すより、LISPで全画層の情報をリストとして一気に引き抜いた方が圧倒的に高速です。

‘ 応用: LISPで複雑な処理をしてVBAに結果を渡す例
Sub GetLayerInfo()
‘ 全画層の名前を取得するLISP式
‘ (mapcar ‘cdr (cdr (entget (tblnext “LAYER” T)))) は一例です
Dim lispCode As String
lispCode = “(mapcar ‘(lambda (x) (cdr (assoc 2 (entget x)))) (ssnamex (ssget “”X””)))”

On Error Resume Next
Dim result As Variant
result = ThisDrawing.Application.Eval(lispCode)

If Err.Number <> 0 Then
MsgBox “LISP式の実行に失敗しました。構文を確認してください。”
Exit Sub
End If

‘ 取得したリストをVBAで処理
Dim i As Long
For i = LBound(result) To UBound(result)
Debug.Print “画層名: ” & result(i)
Next i
End Sub

最後に:エンジニアとして成長するために

`AcadApplication.Eval`は強力な武器ですが、「なんでもかんでもLISPで書けばいい」わけではありません。 メンテナンス性を考えると、できる限りVBAの標準オブジェクトモデルを優先し、どうしても手が届かない「最後の手段」としてEvalを使うのが、洗練されたアーキテクトの流儀です。

ここをクリアしたあなたは、もう「マクロの記録」に頼る初心者ではありません。AutoCADの内部構造を理解し、言語の垣根を超えて制御できるプロフェッショナルです。

さあ、次はどんな自動化に挑戦しますか? 困ったことがあれば、またいつでも聞きに来てくださいね。応援しています!

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