
コラム
AutoLISPで業務を効率化する 第二回【開発を始める】

第一回では使用方法について以下の記事で解説しました。
AutoLISPで業務を効率化する 第一回【使用方法】
第二回では開発方法について、特にその初歩的な部分について解説していきます。
AutoLISP(以降基本LISPと呼称)の開発はシンプルです。前回述べた、「エクセルの数式のように開発できる」という文句の訳が今回のコラムでは垣間見ることができると思います。
AutoLISP開発の初歩
まずはエディタの起動や、LISPの基本的な構造について解説していきます。VisualLISPエディタの起動
筆者はテキストエディタをメインに使用していますが、AutoCADの基本機能である「Visual LISP エディタ」を使う事もできます。
リボンタブの[管理]→[アプリケーション]リボンから[Visual LISP エディタ]を起動できます。

コマンドラインから「VLISP」コマンドで起動することもできます。

初回起動時は以下の様なダイアログが出ますが、下の「AutoCAD Visual LISP」を選びましょう。
※上の選択肢はマイクロソフト製の別のアプリが必要になります。


VisualLISPエディタを立ち上げたら、フォントを設定しましょう。既定のままだと日本語が文字化けして扱いにくいです。
リボン[ツール]→[ウィンドウの属性]→「フォント」から変更できます。


左がテキストエディタ、右がVisualLISPエディタ。
見易さは圧倒的にVisualLISPエディタに軍配が上がります。それ以外にもVisualLISPエディタにはコーディングをサポートする様々な機能があるので、機能面だけ見ればテキストエディタを使う意味は全くありませんね。

ただ、個人的にテキストエディタの方が簡単にファイルを増やせたり読み込んだりと、VisualLISPエディタに比べて何かと手軽に作業できる印象があるので、なんだかんだテキストエディタがいまだにメインです。どうしてもエラーの原因が分からない時や、コードを整形したい時にだけVisualLISPエディタを使っています。
VisualLISPエディタの細かな使い方は一旦脇に置いておいて、プログラミング自体の話題に移ります。
括弧()で括る
エクセルでは関数(引数1,引数2)のような構造を取りますが、LISPでは(関数 引数1 引数2)というように、関数も含めて()で括る形になります。
()で括られていなければ関数と認識されません。つまり、必ず左括弧(と右括弧)の数が一致します。一致しなければエラーがコマンドラインに表示され、読み込みが拒否されます。
また、エクセルでは「,」カンマ(コンマ)が区切りとして機能しますが、LISPでは「 」半角スペースで区切ります(全角スペースではダメです)。
それでは、試しにLISP式を入力してみます。
以下の文をコピーし、AutoCADのコマンドラインに貼り付けてエンターで実行してみると…。
(princ “Let’s get the Beginning”)
![]()
↓ (エンターかスペースで実行)

上の画像の様に、LISP式がコマンドとして読み込まれ、princ関数が””で括られた文字列をコマンドラインに表示します。
括弧を外して入力した場合、このようになります。
princ “Let’s get the Beginning”

LISP式ではなく、「princ “Let’s get the Beginning”」というコマンドとして扱われてしまっているため、エラーが表示されます。
関数、引数、戻り値
(princ “Let’s get the Beginning”)
というLISP式を例とします。

このように分けられます。引数を関数に与えることで戻り値という結果が出力されます。
|
関数 |
princ |
|
引数 |
“Let’s get the Beginning”(文字列) |
|
戻り値 |
Let’s get the Beginning(コマンドラインに出力) |
関数、引数、戻り値という言葉が出てきました。関数と引数に関してはエクセルでも見慣れた概念かと思います。
関数とは、「特定の処理をまとめて名前を付けたもの」です。「princ」は、コマンドラインに式を表示する関数ですが、一見単純そうに見えて、裏ではいくつもの処理が動いています。
引数とは、プログラムや関数に渡す値です。今回は引数として、文字列“Let’s get the Beginning“を渡しました。
戻り値とは、関数が出力する結果のことです。「princ」関数は引数の値がそのまま戻り値になり、コマンドライン上に出力されます。Excelではあまり戻り値を意識することはありませんが、LISPではデータがどのような型で戻り値として出力されるかはとても大事です。この場では、詳細は省きます。
引数が増えたり種類が決まっていたりと関数によって異なりますが、(関数 引数)というのがLISP式の基本構図になります。
この関数の機能を組み合わせることで機能が実装できます。具体的な機能や引数の種類を暗記する必要はありません。エクセルの数式を考えると時と同じように、AutoCAD公式関数リファレンスを見ながら式を作成しましょう。
余談ですが、最初の方はGoogle検索した方が、リファレンスサイトを眺めるより楽かもしれません。関数リファレンスはアルファベット順に並んでいて、しかも全て英語を略して設定されています(例:princ = Prints an expression to the command line)。
ここから適した関数を探そうとすると、上からしらみつぶしに探すことになります。とてもしんどいので、まずはネット検索で「AutpLISP やりたい内容」で調べてみましょう。大抵の関数は既にネット上にまとめてありますし、運が良ければ最適なLISPがそのまま見つかるかもしれません。慣れてきて、関数の内容や詳しい引数の扱い方を知りたくなったら関数リファレンスを読むと良いです。
変数
変数とは、好きなデータを入れておける箱のようなものです。LISPでは、簡単に呼び出せて上書きできます。変数の良いところは何度でも使えて、修正や変更が容易で、コードが読みやすくなることです。長い処理の結果でも、一度変数に入れておけば何度でも再利用することができます。
変数は、「setq」関数で作成、値の代入ができます。
構文は(setq 変数名1 内容1 変数名2 内容2…)といったもので、一度の「setq」関数で複数定義することが可能です。
(princ “Let’s get the Beginning”)の文字列“Let’s get the Beginning”も、(setq a “Let’s get the Beginning”)として変数「a」に入れておけば、(princ a)と記述するだけで済みます。
注意すべき点は、変数の中身が文字列だからと(princ “a”)としてはいけません。これでは変数ではなく、単に「a」という文字列になってしまいます。
また、関数の引数として変数を与える場合は、変数の中身の種類を意識しましょう。
例えば、文字列を結合する「strcat」関数の引数は文字列です。数値を与えるとエラーがでるため、”7”の様に文字列にします。しかし変数に「7」を数値として入れていた場合、そのまま渡せませんし、””をつけることもできません。こういった場合は関数を使って変換しましょう。今回の場合は、「itoa」関数で整数から文字列に変換できます。
余談ですが、VBA等と違い型の宣言等は存在しません。文字列を代入した変数に、後で数値を代入した場合は、その数値で変数が上書きされます。
コメントアウト
コメントアウトとは、プログラム内の読み込まれない部分のことです。
ひたすらコードが続くと読みにくいので、適宜コメントを残して見やすくしましょう。
コメントアウトのやり方は二種類あります。「;」セミコロンを使うと改行するまでがコメントアウトになり、「;|」セミコロンとパイプを使うと、「;|」から「|;」までがコメントアウトになります。
|
記号 |
名前 |
内容 |
|
; |
セミコロン |
改行されるまで |
|
;| |; |
セミコロン&パイプ |
「;|」から「|;」まで |
LISP式のコマンド化
これまではLISP式の記述について話しました。次のステップとして、LISP式をコマンドとしてひとまとまりにする方法について話していきます。defun関数
defun関数はLISP式にコマンド名を与え、コマンドラインから呼び出せるようにします。
前回の記事の「AutoLISPの使い方」章「AutoLISPの呼び出し方」節で説明したように、defun C:~の~部分で書かれた文字列がコマンドとして認識されます。※コマンド名は日本語も使用可能ですが、呼び出し時の変換の手間や文字コードの関係で問題が起きる可能性があるので、普通にアルファベットを使用することをおすすめします。
では、サンプルのLISP式を見てみましょう。

このようになります。
(defun c:コマンド名 (引数/ローカル変数) LISP式~)
defun関数には「コマンド名」「引数/ローカル変数」「LISP式」が引数として必要です。
この構成は絶対で、「引数/ローカル変数」中身は省略可能ですが、()という記述は必ずしなくてはなりません。省くと以下のようにエラーがでます。

また、コマンド名の前に置くc:を省略すると、コマンドではなく関数を定義した扱いになります。つまり、以下のようなLisp式を呼び出す場合、「test」と入力するのではなく、(test)という風にLISP式として入力することになります。
(defun test ( / )
(princ “Let’s get the Begining”)
);defun
( / )の左側の引数に関しては、コマンド化する場合は気にしなくて良いです。しかし、「c:」を置かずに関数として定義する場合は引数の設定も必要になる場合があります。
また、関数化する場合は戻り値があるため、別のLISP式で呼び出して使う、ライブラリの様な扱い方が可能です。活用方法は様々ありますが、長くなるので今回は割愛させていただきます。
余談ですが、このコマンドとして定義するという説明は関数リファレンスの「defun」の項目にはなく、なぜか別の章「概要 – シンボルおよび関数の処理(AutoLISP)」の一部で解説されています。
ローカル変数
前項ではローカル変数という概念が登場しました。名前から察せられる通り、ローカル変数は特定の関数の中でのみ機能します。対になる概念にグローバル変数があり、これはAutoCADファイル内のすべて関数で共有されます。オフセットコマンド等は前回の値をシステム変数として記録していますが、これと同じように、関数の終了後もデータが破棄されません。
defun関数の②の引数「( / )」がありましたが、この「/」の右側に記述した値はローカル変数として定義されます。
例えば、以下のように、変数aに文字列“Let’s get the Beginning”を代入して、変数aを「princ」関数でコマンドプロンプトに書き出してみましょう。
(defun c:test ( / a )
(setq a “Let’s get the Beginning”)
(princ a)
(princ)
);defun
「!変数名」で変数の中身を見ることができます。
「test」コマンドを起動した後に、「!a」と入力した結果は「nil」、空です。

次に、変数「a」をグローバル変数として、同じ動作を行います。

“Let’s get the Beginning”が表示されました。このようにグローバル変数は、関数の終了後も残り続けます。
そのため、別のコマンドを作成した場合でも、同じ変数「a」を使用することができます。
↓名前の異なるコマンドを設定
(defun c:test2 ( / )
(princ a)
(princ)
);defun

しかし、ローカル変数を設定すると、同じ変数名のグローバル変数は使うことができません。
(defun c:test2 ( / a )
(princ a)
);defun

グローバル変数の影響を受けたくない場合はローカル変数として設定しましょう。
まとめ
今回はVisualLISPの起動から、LISP式をコマンド化するところまで解説しました。特に、基本的な要素の中でも、関数や引数などのプログラミングに共通している概念と、それらのAutoLISPでの扱い方という初歩的な部分を解説になりました。全二回を予定していましたが、このほかにもまだまだ説明できていないAutoLISP固有の要素は数多くあるため、「AutoLISP開発の基本」を網羅するためにもう少し回は続きます。
最後に、今回解説した用語をまとめて締めとさせていただきます。
用語まとめ
|
名前 |
内容 |
|
関数 |
特定の処理をまとめて名前を付けたもの |
|
引数 |
プログラムや関数に渡す値、パラメータ |
|
戻り値 |
関数が出力する結果 |
|
変数 |
数値や文字などの値を入れられる領域「値が入る箱」 |
|
グローバル変数 |
ファイル内で共有される変数 |
|
ローカル変数 |
特定の関数の中でのみ共有される変数 |