サンプルコード

【サンプルコード】選択した図形の色をAutoLISPで自由に変更する|ByLayerへの変更も可能

samplecode2_eyecatch
  • AutoLISPを覚えてAutoCADを効率化したい
  • サンプルコードを参考にしたいけど検索しても見つからない
  • プログラミングは苦手なので解説付きだとうれしい

AutoLISPでAutoCADの作業を楽にしたいけど、プログラミングが苦手でコード(プログラム)を作れずにお困りではないでしょうか。マイナーなプログラム言語なのでサンプルコードを検索しても見つからずにお困りの方も多いはず。

私はAutoLISPを独学し、業務の自動化・効率化に役立つプログラムを5年以上作成しています。数行で書けるような簡単なプログラムから、1000行以上の少し複雑なプログラムまで様々なツールを作成してきました。

そもそもAutoLISPってなに?という方はこちらの記事をご覧ください。
>>AutoCADユーザー必見!【AutoLISPを覚えるべきメリット5選】デメリットも解説

当記事ではAutoLISPのサンプルコードとして、選択した図形の色を自由に変更できるコードをご紹介します。初心者向けの解説付きなので、どんな方でも参考にしやすい内容になっています。

AutoLISPを覚えて今よりもAutoCADを効率化したい方はぜひ最後までお読みください。

サンプルコードの動作解説

samplecode2_1

今回ご紹介するAutoLISPのサンプルコードは以下のとおりです。

申し訳ありませんがコードの使用は自己責任でお願いします。不具合が起きないようにするため、コピーしたdwgファイルで実行することをおすすめします。

(defun c:test2
   (
    /
    mode colorindex ss n ent
   )

  ;;;色を変更する図形で選択セットを作成
  (initget 1 "1 2 3 4")
  (setq mode (getkword "対象図形の番号を入力してください。1:円のみ、2:赤い図形のみ、3:赤い円のみ、4:任意選択⇒"))

  ;;;モード毎に指定の図形を選択
  (cond
    
    ;;;図面上に存在する、すべての円を選択
    ((= mode "1")
     (setq ss (ssget "X" (list (cons 0 "circle"))))
    )

    ;;;図面上に存在する、色が赤の図形をすべて選択
    ((= mode "2")
     (setq ss (ssget "X" (list (cons 62 1))))
    )

    ;;;図面上に存在する、色が赤の円をすべて選択
    ((= mode "3")
     (setq ss (ssget "X" (list (cons 0 "circle") (cons 62 1))))
    )

    ;;;ユーザーが任意の図形を選択
    ((= mode "4")
     (setq ss (ssget))
    )
  )

  ;;;変更後の色番号を入力。整数以外が入力されたら再入力を求める。
  (initget 1)
  (setq colorindex (getint "変更後の色番号(0~256)を入力してください。※ByLayerは256 ⇒"))

  ;;;対象図形の図形情報を書き換える
  (if ss
    (progn
      (setq n 0)
      (repeat (sslength ss)

	    ;;;図形情報を取得
	    (setq ent (entget (ssname ss n)))

	    ;;;色の情報を変更または追加
	    (if (assoc 62 ent)
	      (setq ent (subst (cons 62 colorindex) (assoc 62 ent) ent))
	      (setq ent (append ent (list (cons 62 colorindex))))
        )

	    ;;;図形情報の書き換え
        (entmod ent)
        (setq n (1+ n))
      )
    )
  )

  ;;;終了
  (print "終了しました。")
  (princ)
)

上記のコードが書かれたlspファイルをロードして、コマンドラインに「test2」と入力すると動作が始まります。

samplecode2_1-1

lspファイルの使い方についてはこちらの記事を参考にしてください。
>>【入門】AutoLISP開発をはじめよう!Visual LISP エディタの使い方

動作の流れは以下のようになっています。

  1. 図形選択のモードをユーザーに指定させる
  2. 指定されたモードに従って図形を選択
  3. 変更後の色番号をユーザーに入力させる
  4. 選択した図形の色番号をユーザーが入力した色番号に変更する
はこさん。
はこさん。

1つずつ解説していきます。

①図形選択のモードをユーザーに指定させる

まず最初に、図形選択の各モードに対応した1~4の番号をユーザーに指定させます。コードで示すと以下の2行(8行目~9行目)でユーザーにモードを指定させています。

;;;色を変更する図形で選択セットを作成
(initget 1 "1 2 3 4")
(setq mode (getkword "対象図形の番号を入力してください。1:円のみ、2:赤い図形のみ、3:赤い円のみ、4:任意選択⇒"))

「getkword」とはユーザーにキーワードの入力を求めて、入力されたキーワードを返すAutoLISP関数のこと。入力させるキーワードは「initget」で設定できます。

「getkword」と「initget」についてもっと知りたい方はこちらの記事をご覧ください。
>>AutoCADに情報を取り込もう!AutoLISPのユーザー入力関数8種を解説

各モードの内容は次のとおり。モード毎の図形選択方法については後述します。

モードの番号動作内容
1図面上に存在する、すべての円を選択する
2図面上に存在する、色が赤の図形をすべて選択する
3図面上に存在する、色が赤の円をすべて選択する
4ユーザーが任意の図形を選択する

ちなみに「initget」の先頭に数値の1を記述すると、Enterの入力を禁止にできます。Enterが入力された場合は再度キーワードの入力を求めてくるので、「getkword」の返り値は必ず「initget」で設定したキーワードのいずれかになります。

はこさん。
はこさん。

入力するキーワードは数値ですが、返り値は文字列になるので注意してください。

「getkword」の返り値がローカル変数のmodeに格納され、次の動作へ移ります。

ローカル変数って何?という方はこちらの記事をご覧ください。
>>オリジナルの関数を作ろう!ユーザー関数を定義するAutoLISP関数「defun」

②指定されたモードに従って図形を選択

ローカル変数のmodeに格納された文字列から、図形選択のモードを判別して対象の図形を選択します。コードで示すと以下の部分(12行目~33行目)でモードの判別と図形の選択を行います。

;;;モード毎に指定の図形を選択
(cond
    
  ;;;図面上に存在する、すべての円を選択
  ((= mode "1")
   (setq ss (ssget "X" (list (cons 0 "circle"))))
  )

  ;;;図面上に存在する、色が赤の図形をすべて選択
  ((= mode "2")
   (setq ss (ssget "X" (list (cons 62 1))))
  )

  ;;;図面上に存在する、色が赤の円をすべて選択
  ((= mode "3")
   (setq ss (ssget "X" (list (cons 0 "circle") (cons 62 1))))
  )

  ;;;ユーザーが任意の図形を選択
  ((= mode "4")
   (setq ss (ssget))
  )
)

「cond」は複数の条件で処理の分岐ができるAutoLISP関数です。ローカル変数modeの中身を条件として、処理を分岐させています。

「cond」など条件分岐の関数についてもっと知りたい方はこちらの記事をご覧ください。
>>【初心者向け】処理を自由に切り替えよう!条件分岐のAutoLISP関数2選

分岐後は「ssget」で図形を選択し、取得した選択セットをローカル変数ssに格納します。「ssget」とは選択した図形から選択セットを作成する関数のこと。選択範囲や図形の種類などさまざまな条件をつけて図形を選択できます。

たとえば、図面上に以下の図形が配置されている場合、モード番号が2の時は矢印で示した図形のみ選択されます。(赤い図形のみ選択)

samplecode2_1-2

ちなみに選択セットとは選択した図形を1つのグループにまとめたものです。専用の関数を使うことで選択セットから図形単体を指定できます。

「ssget」や選択セットから図形を指定する関数についてはこちらの記事で解説していますのでぜひご覧ください。
>>図形選択の効率アップ!選択セットを操作するAutoLISP関数6選|ssgetが重要

「ssget」で取得した選択セットがローカル変数のssに格納されて次の動作へ移ります。

はこさん。
はこさん。

「ssget」は非常に便利でよく使う関数なので、使い方をしっかり覚えておきましょう。

③変更後の色番号をユーザーに入力させる

選択した図形の色を変えるため、変更後の色番号をユーザーに入力させます。コードで示すと以下の部分(36行目~37行目)で色番号の入力を行います。

;;;変更後の色番号を入力。整数以外が入力されたら再入力を求める。
(initget 1)
(setq colorindex (getint "変更後の色番号(0~256)を入力してください。※ByLayerは256 ⇒"))

「getint」はユーザーに整数の入力を求めるAutoLISPの関数です。モード番号を入力するときと同様に「initget」で1を与えているため、Enterが入力されたら再入力を求めます。

「getint」と「initget」についてはこちらの記事で解説してるのでぜひご覧ください。
>>AutoCADに情報を取り込もう!AutoLISPのユーザー入力関数8種を解説

色番号と色の対応は「COLOR」コマンドで表示される下記の画面で確認できます。色にカーソルを合わせると色番号(インデックスカラー)が赤枠内に表示されます。

samplecode2_1-3

ユーザーが入力した整数はローカル変数のcolorindexに格納され、次の動作へ移ります。

はこさん。
はこさん。

257以上の整数を入力してもエラーで動作は止まりませんですが、色は変化しません。

④選択した図形の色番号をユーザーが入力した色番号に変更する

②で選択した全図形の色番号を、③でユーザーが入力した色番号に変更します。コードで示すと以下の部分(40行目~59行目)で色番号の変更を行います。

;;;対象図形の図形情報を書き換える
(if ss
  (progn
    (setq n 0)
    (repeat (sslength ss)

	  ;;;図形情報を取得
	  (setq ent (entget (ssname ss n)))

	  ;;;色の情報を変更または追加
	  (if (assoc 62 ent)
	    (setq ent (subst (cons 62 colorindex) (assoc 62 ent) ent))
	    (setq ent (append ent (list (cons 62 colorindex))))
      )

	  ;;;図形情報の書き換え
      (entmod ent)
      (setq n (1+ n))
    )
  )
)

「sslength」は選択セット内の図形数を返すAutoLISPの関数なので、選択された図形の数だけ「repeat」で動作を繰り返します。

「sslength」など選択セットの関数についてはこちらの記事で解説しています。
>>図形選択の効率アップ!選択セットを操作するAutoLISP関数6選|ssgetが重要

「repeat」など繰り返しの関数について知りたい方はこちらの記事をご覧ください。
>>AutoCADで楽をしたい人必見【繰り返しを自動化するAutoLISP関数3選】

図形が選択されていない(選択セット内の図形数が0)場合、ローカル変数ssの中身はnilのままです。「sslength」は引数がnilだとエラーで動作が止まるため、「repeat」の動作が始まる前に「if」でssの中身を判定しています。

はこさん。
はこさん。

図形が選択されていないときは何もせず終了します。

repeat内の動作解説

「repeat」内の動作では、最初に図形情報を取得してローカル変数のentに格納します。色の情報を表すグループコードは62なので、62から始まる連想リストを「assoc」で検索しています。

グループコードや図形情報についてはこちらの記事をご覧ください。
>>図形編集を自動化しよう!AutoLISPの図形名関数を解説

「assoc」などリストからデータを取得する関数はこちらの記事で解説しています。
>>【AutoLISP】リストの要素を取得する関数「nth」「last」「assoc」

「assoc」で連想リストが見つかった場合は色番号を変更し、新しい図形情報をローカル変数のentに格納します。

;;;色の情報を変更または追加
(if (assoc 62 ent)
  (setq ent (subst (cons 62 colorindex) (assoc 62 ent) ent))
  (setq ent (append ent (list (cons 62 colorindex))))
)

色がByLayerのときは62から始まる連想リストが省略されているため、「assoc」の返り値はnilになります。この場合は図形情報に62から始まる連想リストを「append」で追加して、新しい図形情報を作成します。

「append」はリストの一番最後に要素を追加するAutoLISPの関数です。詳細はこちらの記事をご覧ください。
>>【初心者必読】リストを作成するAutoLISP関数3選|使用例も解説

「entmod」で新しい図形情報(ローカル変数のent)に書き換えることで、図形の色はユーザーが指定した色に変更されます。

「entmod」の使い方についてはこちらの記事を参考にしてください。
>>図形編集を自動化しよう!AutoLISPの図形名関数を解説

たとえば、モード番号が2でユーザーが入力した色番号が110の場合は、赤い四角形だけ色が変わって緑になります。

samplecode2_1-4
はこさん。
はこさん。

図形情報の書き換えはさまざまな場面で応用できるので覚えておくと便利です。

サンプルコードを活かしてAutoCADをもっと効率化しよう

samplecode2_last

今回ご紹介したサンプルコードの動作内容を以下にまとめます。

  1. 「getkword」で図形選択のモード番号をユーザーに入力させる
  2. 「cond」でモード番号別に動作を分岐させて、指定の図形だけで選択セットを作成する
  3. 「getint」で変更後の色番号をユーザーに入力させる
  4. 作成した選択セットから図形情報を取得して、色番号の情報をユーザーが入力した色番号に書き換える
  5. ④の動作を選択した図形の数だけ繰り返す

選択図形の条件を変えたり、変更する図形情報を追加したりすることで、やりたい作業に特化したツールを作成できます。今回のサンプルコードを活かして、AutoCADの作業が楽になるツール作成に役立ててください。

あなたに代わってAutoLISPプログラムを作成します

AutoLISPで作業を自動化したいけど、プログラミングに詳しくないのでツールが作れずにお悩みの方へ。5年以上のAutoLISP経験を活かしてAutoCADを自動化するツールを作成します。既にお持ちのAutoLISPプログラム修正も対応可能です。

AutoCADの面倒くさい作業から解放されたい方は、下記リンク先の「ココナラ」からお気軽にご相談ください。
>>AutoCADが楽になるプログラムを作成します|ココナラ

AutoCADが楽になるプログラムを作成します AutoCADを効率化して面倒な作業から解放されましょう!

-サンプルコード