キーワード非対応の入力関数
AutoLISP関数 |
---|
(getstring [cr] [msg]) |
cr:nil、またはnil以外 msg:文字列 |
ユーザーが文字列を入力するまで待機し、入力された文字列を返します。 |
戻り値:文字列 |
getstring 関数は、ユーザーから文字列を受け取ります。
msg 引数には、ユーザーに表示するプロンプトを指定します。省略された場合は、何も表示されません。
一般的な使い方は以下のとおりです。
コマンド: (getstring "文字列を入力:")⏎
文字列を入力:fire⏎
"fire"
initget 関数によるキーワードの制約は受けませんので、戻り値の文字列が空("")の場合があります。
コマンド: (getstring "文字列を入力:")⏎
文字列を入力:⏎
""
空白を含む文字列の場合は、通常はスペースキーを押すと ENTER キーと同じになりますので、ユーザーは”(ダブルクォーテーション)で囲んで入力しなければなりません。
コマンド: (getstring "文字列を入力:")⏎
文字列を入力:fire⏎ "fire"
コマンド:(getstring "文字列を入力:")⏎
文字列を入力:"fire wall"⏎
"fire wall"
cr 引数を nil 以外にすると、スペースキーは空白と解釈され、ENTER キーで確定します。下は、空白を含む文字列を”(ダブルクォーテーション)で囲まなくても良い例です。
コマンド: (getstring T "文字列を入力:")⏎
文字列を入力:fire wall⏎
"fire wall"
ESC キーが押されると、「*キャンセル*」と表示されエラーが発生します。
ユーザー入力関数の注意点
ユーザー入力は、プログラムに副作用をもたらすもので、適切な入力がないとプログラムが誤作動を起こしかねません。その点、AutoLISP では目的に合わせたユーザー入力関数が用意されているので、適切に用いることでプログラムを堅牢にすることができます。
しかしながら、プログラム側で対処する必要があるユーザーの予定外の行動が、三つほど残っています。まず二つについて説明します。
一つ目は、ユーザーの空入力です。initget 関数でキーボードから何も入力せずに ENTER を押してユーザー入力関数が nil を返すことを防ぐことはできますが、entsel 関数でユーザーが図形を選択しそこなって nil が返るようなことまでは防ぎきれません。
二つ目は、ユーザーが ESC キーを押した場合は、例外が発生し実行中のプログラムはすべからく「*キャンセル*」と表示されエラーによって終了します。ユーザーは、単に前に戻りたかったのかもしれませんし、プログラムが想定内以外で終了することは好ましくありません。
これらを考慮して、ユーザー入力関数を安全に使うことができるラッパー関数を次のように用意します。
(defun getException (func args onEmpty onException / $error) (if func (if (vl-catch-all-error-p (setq $error (vl-catch-all-apply func args))) (eval onException) (if (= $error (if (= func 'getstring) "" nil)) (eval onEmpty) $error ) ) (exit) ) )
getException 関数の func 引数には使用するユーザー入力関数名を、args 引数にはその関数で使用する引数をリストにまとめて指定します。ここまでは apply 関数と同様です。そして、ユーザー入力関数が空入力を返した場合は、onEmpty 引数が評価されて返ります。ユーザーが ESC キーを押した場合は、onException 引数が評価されて返ります。
具体的な使い方は以下の通りです。多くの場合は、onEmpty 引数はデフォルト値、onException 引数はnil を指定することになるでしょう。別の言い方をしますと、ユーザーは空入力でデフォルト値を選べるように利便性を高めることができます。
_$ (getException 'getint (list "Input index : ") 0 nil) ⏎ ; ユーザーの入力10
10
_$ (getException 'getint (list "Input index : ") 0 nil) ⏎ ; 空入力
0
_$ (getException 'getint (list "Input index : ") 0 nil) ⏎ ; ESCキー
nil
onEmpty 引数と onException 引数は値を返すだけでなく、それぞれのケースが発生した場合に評価されるので、実行コードを表すリストを渡して、何らかの動作を行うこともできます。下の例では、ESC キーが押された場合、「EXCEPTION!」と表示し、-1 を戻り値として返すようにしています。例外のとき評価されるコードでは、シンボル $error に例外オブジェクトが代入されており利用できます。
_$ (getException 'getint (list "Input index : ") 0 '(progn (princ "EXCEPTION!\n") -1)) ⏎
EXCEPTION!
-1
ユーザーの予定外の入力で三つめの問題点は図形を選択する場面で起こります。それは、entsel 関数はロックされた図形も選択できるので、それを確認せずにプログラムで図形を変更しようとするとエラーが発生します。
次のラッパー関数は、entsel 関数と nentselp 関数用で、allowLocked 引数が nil 以外の場合にユーザーがロックされた図形を選択した場合は onEmpty 引数が評価されて返ります。
(defun entselException (func args onEmpty onException allowLocked / $error) (if func (if (vl-catch-all-error-p (setq $error (vl-catch-all-apply func args))) (eval onException) (if (or (null $error) (and (/= (type $error) 'STR) (not allowLocked) (not (vlax-write-enabled-p (car $error))) ) ) (eval onEmpty) $error ) ) (exit) ) )
具体的な使い方は以下の通りです。
_$ (entselException 'entsel (list "オブジェクトを選択:") 0 nil nil) ⏎ ;図形選択
(<図形名: 7ffff706cb0> (173.862 103.09 0.0))
_$ (entselException 'entsel (list "オブジェクトを選択:") 0 nil nil) ⏎ ;空クリック
0
_$ (entselException 'entsel (list "オブジェクトを選択:") 0 nil nil) ⏎ ;ESCキー
nil
_$ (entselException 'entsel (list "オブジェクトを選択:") 0 nil nil) ⏎ ;ロック図形を選択
nil