AutoCAD VBAでAutoLISPを実行する|AutoCAD VBAマクロの作成方法
AutoCADでは自動化する方法としてVBA以外にもLISPという言語がサポートされています。これらはコードの書き方が違うだけで同じ処理を行うことも可能ですが、VBAにしかできないこと、LISPにしかできないことがそれぞれ存在します。AutoCAD VBAはLISPを実行する関数が用意されているため、VBAで実現できない処理でもLISPを経由することで再現可能なものとなる場合があります。
本ページではAutoCAD VBAからAutoLISPアプリケーションファイル(.lsp)をロードして、LISPファイル内に定義されている自作の関数を実行する方法を紹介していきます。
本ページで学べる内容は以下のとおりです。
VBAでLISPファイルを読み込む方法
VBAでLISPファイル内の関数を実行する方法
VBAでAutoLISP読み込み
LISPファイルの読み込み
LISPファイル(.lsp)を実行するためにはまずファイルをAutoCADに読み込ませる必要があります。LISPファイルを読み込ませるにはAutoCAD画面下部にあるコマンドラインに下記のコマンド文字列を打ち込み[Enter]を押下することで指定のLISPファイルを読み込ませることができます。
(load “C:/…/tmp.lsp”)
LISPファイルを読み込むには上記の通りAutoLISPのload関数を使います。load関数の引数として読み込ませたいLISPファイルのパスを入力することで、指定したLISPファイルが読み込まれます。このとき、指定するパスの区切り文字はスラッシュ[/]もしくは2つの円マーク[\\]にする必要があります。1つの円マークやバックスラッシュの場合、ファイル読み込みに失敗するので注意が必要です。
また、LISPファイルが読み込まれるのはアクティブな図面内であり、複数の図面データが開いていたとしてもアクティブな図面以外の図面には読み込まれません。他の図面にもLISPファイルを読み込ませたい場合は図面ごとにload関数を適用する必要があります。
VBAでコマンドライン操作
コマンドラインからLISPファイルを読み込む前項の方法は、手作業で直接コマンドを入力することでも実現が可能です。AutoCAD VBAではこのコマンドラインに指定のコマンド文字列を送信するための関数が用意されているため、前項の内容をそのままVBAの処理で行うことが可能です。
VBAでコマンドラインに指定のコマンド文字列を送信するにはAcadDocumentオブジェクトのSendCommandメソッドを使います。SendCommandメソッドはその名の通り、指定の図面(ドキュメント)のコマンドラインに任意のコマンド文字列を送信するためのメソッドです。
基本的にコマンドラインを操作するのはアクティブな図面内である場合が一般的であるため、下記のようにThisDocumentもしくはActiveDocumentのいずれかを対象にして使用します。
ThisDocument.SendCommand(sCmd)
AutoCAD.ActiveDocument.SendCommand(sCmd)
引数のsCmdにはコマンドラインに送信する文字列(String)を入力します。
上記のLISPファイル読み込みのコマンド文字列をVBAから送信するには下記のように記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Sub LoadLisp() Dim sCmd As String 'コマンド作成 sCmd = "(load ""C:\xxx\tmp.lsp"")" sCmd = Replace(sCmd, "\", "/") '"区切り文字置換 sCmd = sCmd & vbCr 'LISPファイル読込 Call ThisDrawing.SendCommand(sCmd) End Sub |
VBAで通常扱うファイルパスは円マークであることが多いため、Replace関数でスラッシュ(もしくは2つの円マーク)に置き換える必要があります。あわせてファイルパスの前後にはダブルクォーテーションを付与しなければならないのでVBA上ではダブルクォーテーションのエスケープが必要になります。
また、SendCommandメソッドで送信する文字列の最後には改行コード(vbCr)を付与しておく必要があります。この改行コードは手作業でいう[Enter]の押下と同じ意味であり、改行コードが存在しない場合は[Enter]が押されていない状態、つまりはコマンド実行がされていない状態となってしまうため注意が必要です。(※実行されないだけで文字列がコマンドラインに入力された状態となる)
LISPファイル読み込み時のセキュリティ警告
読み込ませるLISPファイルがAutoCADオプションの「信頼できる場所」に登録されていないディレクトリ内にある場合、上記のようなセキュリティの警告ウィンドウが表示されます。
VBAでAutoLISP実行
LISPファイル内の関数実行
AutoLISPではdefun関数を使うことで自作の関数(コマンド)を作成することができます。自作関数を定義したLISPファイルを前項の通りAutoCADに読み込ませることで、コマンドラインからその自作関数を実行させることができます。(※自作関数名は「C:関数名」となるような文字列を設定のこと)
たとえば下記のようなalert関数を使って「Hello Lisp World」というメッセージボックスを表示する「HelloWorld」関数を定義したLISPファイルを用意します。
1 2 3 |
(defun C:HelloWorld () (alert "Hello Lisp World") ) |
このLISPファイルを読み込ませることで、コマンドラインに「HELLOWORLD」(コマンド名は大文字になる)というコマンドを入力することが可能になります。このコマンドを実行することでLISPファイル内で定義した”メッセージボックスを表示する処理”を実行することができます。
VBAでコマンドライン操作
VBAでのコマンドライン操作はLISPファイルの読み込みと同じく、AcadDocumentオブジェクトのSendCommandメソッドで行います。VBAでLISPファイルの読み込みと関数実行の流れを一連の処理で行うには下記のようなコードとなります。処理内容としてはLISPファイルの読み込みとLISPファイル内関数の実行を行っていますが、実質コマンドラインに文字列を2回送信しているだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub RunLisp() Dim sCmd As String 'コマンド作成 sCmd = "(load ""C:\xxx\tmp.lsp"")" sCmd = Replace(sCmd, "\", "/") '"区切り文字置換 sCmd = sCmd & vbCr 'LISPファイル読込 Call ThisDrawing.SendCommand(sCmd) 'コマンド作成 sCmd = "HELLOWORLD" & vbCr 'LISPファイル内の関数実行 Call ThisDrawing.SendCommand(sCmd) End Sub |
LISPファイルは1度読み込み(load)をさせたら、その図面が閉じられるまで読み込まれた状態のままとなります。そのため、LISPファイル内の関数をVBAで利用する際はコードの初めに1度だけ読み込み処理をしておけば、それ以降に再度読み込ませる処理を実装する必要はありません。
まとめ
今回の内容をまとめると以下のとおりです。
LISPファイル内の関数を実行するにはLISPファイルを読み込む必要がある
LISPファイルの読み込みと関数の実行はコマンドラインから行うことができる
AutoCAD VBAはコマンドラインを操作するためのSendCommandメソッドが存在する
基本的にLISPファイルの読み込みも関数の実行もコマンドライン上だけで完結する処理です。VBAから実行する場合もSendCommandメソッドを使ってコマンドライン経由でLISPを実行します。
この内容だけ見るとわざわざVBAを利用する必要がないと感じるかもしれませんが、ここで重要なのはVBAの処理の一部としてLISPの関数を使用することができるという点です。VBAの処理には限界がありますがLISPと組み合わせることで実現できることの幅は広がるので、「VBAだけ」「LISPだけ」にとどまらず2つの言語を連携するという手法があるということは認識しておくだけでも損はないです。