関数 *error* は、AutoLISPエラー中断時の処理をカスタマイズできるエラー処理関数です。
システム変数を初期値に戻す、コマンドUNDO[元に戻す] を使ってコマンド実行前の状態に戻すなど、エラー中断時にしたいことをプログラムできます。
予備知識
AutoLISP 関数 *error*
AutoLISP 関数 *error*は、AutoLISPエラー中断時の処理をする関数です。
エラー中断時にする処理をカスタマイズできます。
標準のエラー処理
標準のエラー処理 *error*は、こうなっています。
(defun *error* (msg)
(princ "エラー: ")
(princ msg)
(princ)
)
エラー処理って難しそう!と思うかもしれませんが、エラーメッセージを表示するだけの、とてもシンプルなものです。
(defun *error* (msg)
自作関数を作るとき、(defun 関数名 の横にくる ( )に入る情報 は、(引数/ローカル関数)でしたね。ここには / が無いので、msg は引数を受け取る変数です。
変数msgは、実行時に引数として情報が入る前提でプログラムしていきます。
msgの内容ですが、AutoLISPエラー中断時、AutoCADから、エラーメッセージが引数として渡されます。
(princ “エラー: “) (princ msg)
princ は、引数がある場合は、引数をコマンドラインに表示する機能があります。
まず、エラー: と表示し、その次に引数としてAutoCADから渡されて変数msgに入ったエラーメッセージを表示します。
関数 *error* のカスタマイズ
エラー処理関数に、標準の”エラーメッセージを出す”だけでなく、コマンド実行前の状態に戻すコードをいれれば、エラー中断時にコマンド実行前の状態に戻してくれるエラー処理関数になります。
システム変数を戻すエラー処理
コチラの記事に出てきた、現在画層設定を変更して、実行後は元に戻すAutoLISPプログラムです。(途中でエラーが起きるようになっています。)
(defun c:Test1-Err ( / OldLy)
(setq OldLy (getvar "CLAYER")) ;現在画層名をOldLyに入れる
(if (not (tblsearch "LAYER" "Jagaimo" )) ;もしJagaimo画層がなければ
(command-s "._LAYER" "N" "Jagaimo" "" );作る
);if
(setvar "CLAYER" "Jagaimo");現在画層をJagaimoにする
(command-s "._DIMLINEAR" Pt);!!!エラーを起こす!!!
(setvar "CLAYER" OldLy);最初の現在画層に戻す
(princ))
このコマンドの問題点は、
エラー中断時に、現在画層がもとの設定に戻らないこと。
です。
試しに現在画層がJagaimoではないことを確認して、このコマンド、Test1-Errを試してみてください。エラー中断後、現在画層がJagaimoになってしまいます。
このコマンドに、エラー中断時に現在画層のシステム変数を元に戻すエラー処理を付け加えていきます。
エラー処理の一例
(defun c:Test2 (/ Olderr OldLy)
(setq OldErr *error*);標準エラー処理を保存
(setq *error* JagaERR);エラー処理をJagaERRにする
(setq OldLy (getvar "CLAYER"));現在画層の設定を保存
;-------------------------------------------------------------------
(if (not (tblsearch "LAYER" "Jagaimo" ))
(command-s "._LAYER" "N" "Jagaimo" "" )
);if
(setvar "CLAYER" "Jagaimo")
(command-s "._DIMLINEAR")
;-------------------------------------------------------------------
(setvar "CLAYER" OldLy);現在画層の設定を戻す
(setq *error* OldErr);エラー処理を戻す
(princ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun JagaERR (msg)
(setvar "CLAYER" OldLy) ;現在画層の設定を戻す
(setq *error* Olderr) ;エラー処理を標準に戻す
(princ "JagaErr: ") ;JagaErrが実行されたか確認するためJagaErr: を表示
(princ msg) ;AutoCADからのエラーメッセージを表示する
(princ));defun
エラー処理部分の説明
コマンドの最初にする処理
(setq OldErr *error*)
最初のエラー処理設定を変数OldErrにいれておきます。
(setq *error* JagaErr)
エラー処理を、自作エラー処理関数JagaErrに変更します。JagaErrの説明は下にあります。通常、関数を使う時は( )で囲みますが、これは例外で()で囲いません。
(setq OldLy (getvar “CLAYER”))
AutoLISPプログラム内でいじるシステム変数の値を保存しておきます。
getvar はシステム変数の値を得る関数。CLAYERは現在画層のシステム変数です。
getvar で得たCLAYERの値を、setq を使って変数OldLYに入れています。
コマンドの最後でする処理
(setvar “CLAYER” OldLy)
現在画層のシステム変数を最初の設定に戻します。
(setq *error* OldErr)
*error* に、最初に変数OldErrに入れておいた情報を入れて、最初の状態に戻します。
(setq *error* nil) で、空にすれば、AutoLISP標準の設定に戻ります。
しかし、人によってはカスタマイズしたエラー処理を使っている場合もあるので、変数に入れて保存しておいて最後/エラー時に戻すほうが無難です。
自作エラー処理関数
これが、今回使う自作エラー処理JagaErrです。
エラー中断時にこのエラー処理が実行されます。
(defun JagaERR (msg)
(setvar "CLAYER" OldLy) ;現在画層の設定を戻す
(setq *error* Olderr) ;エラー処理を標準に戻す
(princ "JagaErr: ") ;JagaErrが実行されたか確認するためJagaErr: を表示
(princ msg) ;AutoCADからのエラーメッセージを表示する
(princ));defun
(setvar “CLAYER” OldLy)
(setq error Olderr)
コマンドの最後に行う、”システム変数とエラー処理設定を最初の設定に戻す” をエラー中断時に実行します。
(princ “JagaErr: “)
(princ msg)
キチンとJagaErrが実行されたことを知りたいので、princ を使って、JagaErr: と表示し、その後に、引数としてAutoCADから渡されて変数msgに入っているエラーメッセージを表示させています。
エラー中断させてエラー処理を試そう
(defun c:Test2-err (/ Olderr OldLy) ;
(setq Olderr *error*) ;現在のエラー処理を保存
(setq *error* JagaERR) ;エラー処理を自作関数JagaERRに変更
(setq OldLy (getvar "CLAYER"));現在画層の設定を保存
;-------------------------------------------------------------------
(if (not (tblsearch "LAYER" "Jagaimo" )) ;もしJagaimo画層がなければ
(command-s "._LAYER" "N" "Jagaimo" "" );作る
);if
(setvar "CLAYER" "Jagaimo");現在画層をJagaimoにする
(command-s "._DIMLINEAR" pt);!!!エラーが起きる!!!
;-------------------------------------------------------------------
(setvar "CLAYER" OldLy) ;現在画層の設定を戻す
; (setq *error* Olderr) ;エラー処理の設定を戻す
(princ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun JagaERR (msg)
(setvar "CLAYER" OldLy) ;現在画層の設定を戻す
(setq *error* Olderr) ;エラー処理を戻す
(princ "JagaErr: ") ;JagaErrが実行されたか確認するためJagaErr: を表示
(princ msg) ;AutoCADからのエラーメッセージを表示する
(princ));defun
先ほどのコマンドTest2にエラー処理を加えました。コマンド名はTest-errです。
現在画層がJagaimoではないことを確認して、このコマンド、Test2-Errを試してみてください。今回は、エラー中断後、自作エラー処理関数JagaERRが働いて、現在画層が元の設定に戻ります。
コマンドラインのログも確認してください。
JagaErr: Unknown (command-s) failure.
ここで、JagaErrが実行されたことと、AutoCADのエラーメッセージで、(command-s)の所でエラーがあったことがわかります。
改善点
今回のエラー処理は、エラー中断時にシステム変数を戻すだけでした。
しかし、”画層Jagaimoが無ければ作成”の部分を過ぎてからエラーが起きるので、画層Jagaimoが無かった場合、新しい画層ができていて、完全には元の設定には戻っていません。
コマンド”Undo”をエラー処理に組み入れることで、AutoCADコマンド操作で変更した部分も元に戻すことができます。
UNDOを使うエラー処理はコチラの記事にあります。
頻繁に使うシステム変数などはまとめて、自作関数にしてしまうと、エラー処理を加えるのが楽になります。
まとめ
- 関数 *error* は、AutoLISPエラー中断時の処理をカスタマイズできるエラー処理関数
- 標準の働きは、AutoCADからのエラーメッセージをコマンドラインに表示する。
- エラー中断時にして欲しい処理を加えることができる。
Comments