#5 | フォームとテキストボックスの更新系イベントの違い | |||||||||||||||||||||||||||||||||||||
フォームやコントロールでは、別のオブジェクトであっても、似たような名前あるいはまったく同じ名前のイベントがいくつも見受けられます。例えば、"更新前処理"イベント・"更新後処理"イベントはフォームにもありますし、テキストボックスコントロールにも存在しています。 また、コンボボックスやリストボックスコントロールにも存在しています。テキストボックスやコンボボックスなど、コントロールから発生されるイベントは、そのコントロールに何らかの更新操作が与えられたときに発生するのであろうと想像できますが、フォームの更新系イベントの発生との兼ね合いはどのようになっているのでしょうか?。 ここでは、上図のように、フォームの"更新前処理"イベント・"更新後処理"イベント、およびテキストボックスである「氏名」と「役職」の2つにイベントトレース用のプロシージャ呼び出しを記述し、その流れを追ってみたいと思います。
まず、テキストボックス単体でのイベント発生状況を確認してみましょう。テキストボックス「氏名」・「役職」に対して、次のような操作を実行してみます。
その結果は次のようになりました。
これを上記の操作手順と照らし合わせてみましょう。 まず、『1.テキストボックス「氏名」の内容を書き換える』という操作だけでは、何のイベントも発生しません(実際には"変更時"イベントが発生していますが、これについては別途取り上げます)。データ内容は変更されているものの、データベース上においては、まだ仮の入力状態にあるといえるでしょう。 続いて、『2.TABキーによってフォーカスを「役職」まで移動する』という操作ですが、この時点で、上表の"更新前処理"イベント・"更新後処理"イベントが同時に発生します。厳密には、「役職」にフォーカスが移動したときではなく、「氏名」のテキストボックスからフォーカスが喪失したときに発生します。つまり、フォーカスが喪失したときにはじめて、イベントとしてはそのテキストボックスが更新されたと判断されていることになります。 続いての『3.テキストボックス「役職」の内容を書き換える』と『4.Enterキーを押して、「役職」の内容を確定する』についても、同様の結果となります。内容を書き換えただけで、またフォーカスが「役職」欄にあるうちは、何らイベントは発生しません。先ほどはTABキーによってフォーカスを移動しましたが、Enterキーによってもフォーカスが次のコントロールに移動しますので、その時点で"更新前処理"イベント・"更新後処理"イベントが同時に発生します。
上記のテストを行う際には、フォームの"更新前処理"・"更新後処理"イベントのプロパティを空欄にしてあったわけではありません。それぞれ「=TrackEvents([Name],"更新前処理")」や「=TrackEvents([Name],"更新後処理")」というトレース用のプロシージャを呼び出すようにしてありました。しかし、VBEのイミディエイトウィンドウを確認しても、それらのイベントは確かに発生していません。それでは、それらフォームの更新系イベントはいつ発生するのでしょうか?。 結論からいうと、そのレコードが保存されたときに発生します。試しに、上記4つの操作を行ったあとで、単票フォームのレコードセレクタをクリックしてみましょう。 その結果をイミディエイトウィンドウで確認してみます。ご覧のように、最後(レコードセレクタクリック時)に「フォーム」の"更新前処理"イベントと"更新後処理"イベントが発生していることが分かります。 このフォームのイベントが発生するタイミングを「レコードが保存されたとき」と言いましたが、レコードが保存されるタイミングはレコードセレクタをクリックする以外にもあります。例えば、
テキストボックス単体での更新系イベントの発生状況、およびフォームも含めた更新系イベントの発生状況について調べてきましたが、イベントプロシージャを活用する際に、これらはどのような考え方で使い分けを行えばよいのでしょうか?。 それを考える上での、要点を整理しておきましょう。
つまり、
といった考え方で両者のイベントを使い分ければよいことになります。 それでは、その使い分け例を次に示します。 次のフォームのモジュールの例では、まず、「氏名」が更新されたら、姓と名がスペースで区切られているかをチェックします。そんなに厳密なチェックではなく、単に氏名のデータの中にスペースが1つ以上存在しているかチェックするだけです。そして、レコードが保存(移動)されたときに"レコードが編集されたかどうかチェック"し、もし編集が行われていたら、フォームモジュール内でグローバルな、レコード編集が行われたかどうかのフラグ変数をTrueに設定します。そして、フォームが閉じる際に、レコード編集が行われていたらその旨のメッセージを表示します。このとき、"レコードが編集されたかどうかチェック"とありますが、特にそのチェック用のコードを記述するわけではなく、レコードが編集されていない場合にはフォームの更新系イベントは発生しませんので、「イベントが発生した=レコードが編集された」と判断することにします。
上記のコードでは、フォームの2つの更新系イベントとテキストボックスの2つの更新系イベント、合計4つのすべてのイベントを使っているわけではありません。「氏名」のチェックでは"更新前処理"イベントを、一方、レコード編集のチェックでは"更新後処理"イベントだけを使っています。これは、"更新前処理"イベントと"更新後処理"イベントの使い分けのポイントともなることですので、ここで簡単に説明しておきましょう。 その違いを知るには、各イベントプロシージャの引数を確認するのが一番よいでしょう。
ご覧のように、大きな違いは「Cancel」という名前の引数の有無にあります。"更新前処理"イベントでは、イベントプロシージャの中でこの値を「True」に設定することによって、そのイベントの発生元となった操作を取り消すことができるのです。 上記のコードでは、「氏名」のチェックに"更新前処理"イベントプロシージャを使い、もし氏名データの中にスペースがなければCancel変数をTrueにしています。つまり、スペースを含まない氏名を入力したときには、その入力操作をキャンセルするようになっているのです。イベントプロシージャによって入力がキャンセルされると、もう一度その欄にデータを入力させるため、「氏名」欄からフォーカスが移動しません。入力した氏名データ全体が反転表示の状態になって、他のコントロールに移動できないようになります。 一方、レコード編集のチェックでは、レコードが編集されていようがいまいが、その編集操作を取り消すという処理は必要ありません。あくまでも編集されたかどうかをチェックするだけです。したがって、「Cancel」引数を利用する必要はありませんので、"更新後処理"イベントの方を使っているわけです。ただし、このようなチェックなら、たとえ"更新前処理"イベントでやってしまっても特に違いはでないでしょう。 |
||||||||||||||||||||||||||||||||||||||
|
Copyright © T'sWare All rights reserved |