・ エラー処理

*error* 関数を適切に使用すると、エラーが発生した後に AutoCAD を確実に特定の状態に戻すことができます。
AutoCAD が評価中にエラーを検出すると、次の形式でメッセージを出力します。

エラー: text

このメッセージで、text はエラーの内容を表します。 しかし、*error* 関数が定義されている場合は(つまり、nil でない場合は) 、AutoLISP はメッセージを出力しないで、*error* を実行します *error* 関数は、1 つの引数として 文字列 を受け取ります。 
プログラムの中で、独自のエラー処理を行うには、以下のようにします。

1.エラー処理のルーチン my-error を記述する

2.*error* の内容を err_def として控える

3.*error* の内容を my_error におきかえる

4.処理の実行

5.一連の処理が終わったら *error* に err_def を書きもどす

一般的には、エラー処理内で使う変数や、書き戻すシステム変数はグローバルな変数を用いるのが慣しですが、ローカル変数でもOKみたいです

例)

;/////////////////////////////////////////////////////////////////////////////////////////////////;
;*** Jo_bobj_offset.lsp  INSERT図形にネストされたオブジェクトをオフセット By Kamijo  2003/08/25***; 
;                                                                                                 ; 
;                Visual Lisp 用                                                                   ; 
;/////////////////////////////////////////////////////////////////////////////////////////////////;
 
(defun Jov_bobj_offset ( / cmd_def err_def dist str_dist ent en ed et mat ;err_def をローカル変数としています
			Jof_mat_3to4 Jof_pled Jof_make_obj Jos_err );エラー処理をローカル関数としています
 
  ;***********************************************************************************************;
 
  ;サブルーチン 4x3のマトリックスを4x4に変換 ;
  (defun Jof_mat_3to4 ( mat / a b i mat_col x mat4) 
    (setq mat (mapcar '(lambda (a b) (append a (list b))) mat '(0.0 0.0 0.0 1.0))) 
    (setq i 0) 
    (repeat (length mat) 
      (setq mat_col (list (mapcar '(lambda (x) (nth i x)) mat))) 
      (setq mat4 (append mat4 mat_col)) 
      (setq i (1+ i)) 
      ) 
    mat4 
    )
 
  ;***********************************************************************************************; 
  ; サブルーチン VERTEX の 主図形 POLYLINE のエンティティーデータを取得する; 
  (defun Jof_pled ( en / ed ) 
    (while en 
      (setq ed (entget (setq en (entnext en)))) 
      (if (= "SEQEND" (cdr (assoc 0 ed))) 
	  (progn 
	    (setq ed (entget (cdr (assoc -2 ed)))) 
	    (setq en nil) 
	    ) 
	  ) 
      ) 
    ed 
    )
 
  ;***********************************************************************************************; 
  ; サブルーチン 元図の複製を作成;
  (defun Jof_make_obj( ed / plen pled en ) 
    (if (entmake ed) 
      (progn 
	(if (= (cdr (assoc 0 ed)) "POLYLINE") 
	  (progn 
	    (setq plen (cdr (assoc -1 ed))) 
	    (while plen 
	      (setq pled (entget (setq plen (entnext plen)))) 
	      (entmake pled) 
	      (if (= (cdr (assoc 0 pled )) "SEQEND") 
		(setq plen nil) 
		) 
	      ) 
	    ) 
	  ) 
	(setq en (entlast)) 
	) 
      (setq en nil) 
      ) 
    en 
    )
 
  ;***********************************************************************************************; 
  ;エラー処理  ; 
  (defun Jos_err ( msg ) ;msg を使う使わないに関係なく 引数に msg は必須です
    (setq *error* err_def) ;エラーでこけた場合も エラー処理を書き戻します
    (command) ;command の途中でこけた場合は command をキャンセル
    (if (and en (entget en)) 
      (command "._ERASE" en "") ;一時的にできる余分なオブジェクトは削除
      ) 
    (setvar "CMDECHO" cmd_def) ;システム変数の書き戻し ローカル変数でもOK
    (if (= msg "オートメーション エラー.均等でない尺度で尺度変更できません") ;msgの内容をユーザーに知らせます・・知らせなくてもOK
      (princ "\n選択したオブジェクトはは均等でない尺度で挿入されているため処理できませんでした") 
      (princ "\n処理はキャンセルされました") 
      ) 
    (princ) ;princしないとごみが表示されます
    )
 
  ;***********************************************************************************************; 
  ; メインルーチン (Jov_bobj_offset) ; 
  (setq cmd_def (getvar "CMDECHO")) ;処理終了後、エラー処理で書き戻すために システム変数を控えます
  (setvar "CMDECHO" 0) 
  (command "UNDO" "M") 
  (vl-load-com) 
  (setq err_def *error*) ;エラー処理を控えます
  (setq *error* Jos_err) ;エラー処理を独自のものに変更
 
  (princ "\n(Jov_bobj_offset):ネストしたオブジェクトをオフセットします") 
  (setq str_dist (if (= -1.0 (getvar "OFFSETDIST")) "" (strcat "<" (rtos (getvar "OFFSETDIST")) "> "))) 
  (while (or (= -1.0 dist) (not dist)) 
    (initget 6) 
    (setq dist (getdist (strcat "\nオフセット間隔を指定 または [通過点(T)] " str_dist ":")))  ;ユーザーがキャンセルしたらエラーにる
    (setq dist (if dist dist (getvar "OFFSETDIST"))) 
    ) 
  (while (not en) 
    (setq ent (nentsel "\nオフセットするオブジェクトを選択 または <終了>:"))  ;ユーザーがキャンセルしたらエラーにる
    (if (not ent) 
      (exit) 
      ) 
    (if (= 4 (length ent)) 
      (setq mat (Jof_mat_3to4 (caddr ent)));4x4のマトリックスに変換 ; 
      ) 
    (setq et (cdr (assoc 0 (setq ed (entget (car ent)))))) 
    (cond
      ((= et "LINE")) 
      ((= et "CIRCLE")) 
      ((= et "ARC")) 
      ((= et "LWPOLYLINE")) 
      ((= et "VERTEX")(setq ed (Jof_pled (car ent)))) 
      ((= et "SPLINE")) 
      ((= et "ELLIPSE")) 
      (T (progn 
	   (princ "\n選択したオブジェクトはオフセットできません") 
	   (setq ed nil) 
	   )) 
      ) 
    (setq en (Jof_make_obj ed)) 
    (if (and mat en) 
      (progn 
	(setq v_obj (vlax-ename->vla-object en));図形名を vla-object に; 
	(vla-TransformBy v_obj (vlax-tmatrix mat));>>>>> X Y Z の尺度が違うとエラーになる; 
	(vla-Update v_obj) 
	(setq en (vlax-vla-object->ename v_obj));vla-object を図形名に; 
	) 
      ) 
    ) 
   (redraw en 3) 
   (initget 1) 
   (setq pt (getpoint "\nオフセットする側の点を指定:"))  ;ユーザーがキャンセルしたらエラーにる
   (command "OFFSET" dist en pt "") ;ユーザーがキャンセルしたらエラーにる
   (entdel en)
 
   (setq *error* err_def) ;処理が終了したのでエラー処理を元に戻す
   (setvar "CMDECHO" cmd_def) 
   (princ) 
   )
 

 
;*************************************************************************************************; 
; ロード時に表示;
(princ "\nJov_bobj_offset.lsp ロード完了 : ネストされたオブジェクトをオフセット") 
(princ "\nコマンドは (Jov_bobj_offset) です") 
(princ)