Sponsored links

【AutoLISP エラー処理】システム変数とエラー処理 2 – 関数 *error*

Sponsored links
AutoLISP
Sponsored links

関数 *error* は、AutoLISPエラー中断時の処理をカスタマイズできるエラー処理関数です。
システム変数を初期値に戻す、コマンドUNDO[元に戻す] を使ってコマンド実行前の状態に戻すなど、エラー中断時にしたいことをプログラムできます。

Sponsored links

予備知識

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