« 第8回 手順6 | トップページ | おばけつぶやき帳 »

2008年5月26日 (月曜日)

第9回 完成

連載ももう何回目なのか判らなくなってきましたが、いよいよ問1の完成です。


最終系……スクリプトを完成させよう!!

さて手順6までで値入率を表示させるスクリプトを完成させる準備ができました。今回はもう一つの発生しうるエラーについて説明し、スクリプトを完成させることにします。

手順6までのエラー・チェックは売価と原価に入力されるデータが数字(半角数字)であることを前提としてきました。が、実際には入力者が全角文字や半角英字など数値データ以外を入力してしまうことも考えられます。そこで、入力されたデータが数値(半角数字)かどうかをチェックする関数を使ってみます。
その関数とは、isNumber関数というもので、is Number ?と覚えるといいかも知れません。

この関数は、“Returns true if a value is a number, false if it is not.”ということで、「与えられた値が数字ならば“真(true)”を数字でなければ“偽(false)”を返します」。この関数は「真偽関数」と呼ばれるもので、round関数のように直ぐに使える値を返してくれるわけではありません。帰ってくるのは、真偽のどちらかだけです。従って、主に手順4で説明した『if文(条件文)』と併せて使うことになります。

さて今回はスクリプトをフィールドに書いてみます。この連載の最初のころに少し振れたと思いますが、スクリプトはオブジェクトのどこにでも書き込むことができるのです。今回はいままでと違いボタンではなくフィールドに書くのですが、その理由は後述することにします。

スクリプトを書くためのフィールドは「fld “BaiKa1”」にします。これは、画面でタブキーを押した時に最初に選択されるフィールドだからです(最初に作成さたフィールドが最初に選択されたフィールドになります)。下のスクリプトは例によって動作確認用のスクリプトです。


on enterInField
if isnumber(me) then
put “OK”
else
put me
end if
end enterInField


このスクリプトを「fld “BaiKa1”」に書き込み、ブラウズ・モードにうつって、タブキーを押し「fld “BaiKa1”」に何か入力してみましょう。数字が入力された場合には「OK」が、数字以外が入力された場合にはその入力された文字が、メッセージ・ボックスに表示されます。

ここでは新たに「me」というキーワードが登場しています。「me」とは、ある意味で「文字通りの意味」です。「Equivalent to the object that contains the currently running handler.」つまり「現在実行中のハンドラを含むオブジェクトを同義」であり、「Use the me keyword within a handler to determine which object’s script is executing.」つまり「どのオブジェクトのスクリプトが実行されているか決定するハンドラ内でキーワード“me”を使います」、「The me keyword is a reference to the object whose script contains the current handler.」つまり「現在実行中のハンドラを含むスクリプトを持つオブジェクトを参照するのにキーワード“me”を使います」。ということですが、なにがなんだか判らないですよネ

上のスクリプトでは、スクリプトが書かれている「fld “BaiKa1”」それ自身を参照しており、「isnumber(me)」は「isnumber(fld “BaiKa1”)」と全く同じ意味です。同様に「put me」は「put fld “BaiKa1”」と書くのと全く同義です。キーワード“me”を使うとスクリプトが簡潔になり、処理の流れが追いやすくなるメリットがあります。
今回のハンドラは「enterInField」ですが、「enterInField」は「フィールド内でエンター・キーが押された時」にRunRevが発するメッセージです。手順1で説明した「エンター・キー」と「リターン・キー」の区別が重要になります。例えば「fld “BaiKa1”」に「999」を入力した後にリターン・キーを押してみると、「fld “BaiKa1”」から今入力したばかりの「999」が消えてしまったように見えるはずです。さらに上の「enterInField」ハンドラの「OK」も表示されません。これはつまり「enterInField」ハンドラが実行されていないということで、その理由は、フィールド内で押されたのはリターン・キーであってエンター・キーではないからです。そこで、「fld “BaiKa1”」のスクリプトにリターン・キーにも対応するハンドラも追加してみます。ついでにタブキーにも対応するハンドラも書き込んでみます。すると、スクリプトは次の様になります。


on enterInField
if isNumber(me) then
put “OK”
else
put me
end if
end enterInField

on returnInField
enterInField
end returnInField

on tabkey
enterInField
end tabkey


「returnInField」ハンドラにも「tabkey」ハンドラにも全く同じ「enterInField」という一行のみが書かれています。こうしておくことで、「enterInField」ハンドラの内容を書き換えた時にも「returnInField」ハンドラや「tabkey」ハンドラを書き直す必要がなくなります。このテクニックも覚えておくと便利ですが、どうしてこう言ったことができるのかの詳細はご自身で勉強してみて下さい。
さあここまでやってきていよいよこのテスト用のスクリプトを本番用のスクリプトに書き換えていきましょう。

まず「fld “BaiKa1”」のスクリプトですが、isNumber関数を使った『if文(条件文)』を次の様な考え方で書き換えることにします。つまり『もし自分自身に入力された値が数字の場合には;fld “NeIre”を空にし;fld “BaiKa2”に自分自身と同じ値を入力し;fld “GenKa”を選択する』、『自分自身に入力された値が数字でない場合には;自分自身をもう一度選択する』という流れを作ります。
次に、上の条件で「fld “GenKa”が選択選択された場合」には、原価を入力することになります。その入力をうけて値入率が計算されるほうが、原価を入力してから計算用のボタンをクリックするよりも、ずっとエレガントに思えます。
以上を踏まえて実際のスクリプトを下に示しておきます。何故その様なスクリプトになるかは自身で考えてみて下さい。尚、下に示すスクリプトはエラーのでないように検証済みですが、もし何らかのエラーが発生しスクリプトの実行が止まった場合には、その情況をお知らせいただければ幸いです。では……;

「fld “BaiKa1”」のスクリプト;


on enterInField
if isNumber(me) then
put empty into fld “NeIre”
put me into fld “BaiKa2”
select text of fld “GenKa”
else
select text of me
end if
end enterInField

on returnInField
enterInField
end returnInField

on tabkey
enterInField
end tabkey


「fld “GenKa”」のスクリプト;


on enterInField
if isNumber(me) then
put round(((fld “BaiKa2” - fld “GenKa”) / fld “Baika1”) * 100,2) into fld “NeIre”
select empty
else
select text of me
end if
end enterInField

on returnInField
enterInField
end returnInField

on tabkey
enterInField
end tabkey


【蛇足】
スクリプトを確実に速く書くコツの一つに、キチンと動くことが確認されたスクリプトを良く似た働きをさせるオブジェクトのスクリプトとして、コピー&ペーストを使って再利用するというものがある。上で示した「fld “BaiKa1”」のスクリプトは「fld “GenKa”」のスクリプトとほぼ同じものと考えられます。そこで、「fld “GenKa”」には「fld “BaiKa1”」のスクリプトを一旦そのままコピー&ペーストで持ってきます。その後、「fld “GenKa”」と「fld “BaiKa1”」の機能の異なる部分、実際には「put round(((fld “BaiKa2” - fld “GenKa”) / fld “Baika1”) * 100,2) into fld “NeIre”」の部分、のみを書き換えることにします。
また、この書き換える「put round(((fld “BaiKa2” - fld “GenKa”) / fld “Baika1”) * 100,2) into fld “NeIre”」は、手順6で「%へ変換」ボタンに書き込んだスクリプトが使えますから、そちらからコピー&ペーストで持ってきます。
こうした作業を行うことで、決定稿となるスクリプトを迅速に且つ確実に作ることが可能となるわけです。逆に言えば、決定稿を確実なものにする為には、一度にスクリプトを書き上げようとせず、何段階にも渡ってオブジェクトのスクリプトを作っていくということが肝心だということになります。

さて、最後の最後になりますが……;今まで作ってきた、オブジェクトで使わないものを表示させないようにします。さらに、データを入力すべきフィールドは二つしかないので、必要のないフィールドにカーソルが移らないように、カーソルの制御をしておきます。

不必要なオブジェクトを表示させないようにするには、次の図のように非表示にするオブジェクトを選んで、メニューからインスペクタを選択し、インスペクタにある「visible」のチェックを外します。するとその次の図にあるように、ウィンドウから選択したオブジェクトが消えてしまったように見えるはずです。ここで実際に「削除」してしまわないのは、また後で機能を追加したり、変更したりするような場合に、以前書いたスクリプトが参考になったり、先程のようにコピー&ペーストで再利用できたりするからです。


【オブジェクトの選択】


Itoh014

【オブジェクトの非表示を設定】


Itoh015


必要のないフィールドにカーソルが移らないように、カーソルの制御を行なうには、「fld “BaiKa2”」と「fld “NeIre”」を、上と同じような方法で選択し、インスペクタを表示させて図のような属性の設定を行います。尚、どの属性をどのように変更したかは宿題としておきますので、ご自身で考えてみて下さい。

【フィールドの属性変更】


Itoh016

|

« 第8回 手順6 | トップページ | おばけつぶやき帳 »