#7 レコード単位の編集イベント

ここに出てくるイベント
  • Current/レコード移動時
  • BeforeInsert/挿入前処理
  • AfterInsert/挿入後処理
  • BeforeUpdate/更新前処理
  • AfterUpdate/更新後処理
  • Dirty/ダーティー時
  • Delete/レコード削除時
  • BeforeDelConfirm/削除前確認
  • AfterDelConfirm/削除後確認


Accessはデータベースソフトということもあって、そのデータ入出力の中核となるフォームには、レコード操作に関するさまざまなイベントが用意されています。
  • レコード移動時
  • 挿入前処理
  • 挿入後処理
  • 更新前処理
  • 更新後処理
  • ダーティー時
  • レコード削除時
  • 削除前確認
  • 削除後確認

このうち、"更新前処理"イベント"更新後処理"イベントについては、「#5 フォームとテキストボックスの更新系イベントの違い」で取り上げていますので、どのようなときに発生するイベントかはあらためて説明する必要はないでしょう。それ以外のイベントについても、特にオンラインヘルプを開くまでもなく、どんなときに発生するイベントか、その用語から容易に想像がつくのではないでしょうか?。

ここでは、それらのイベントを確認する意味で、次のようなフォーム上からいくつかのレコード編集操作を行って、イベント発生の概要を調査してみたいと思います。
サンプルフォーム

なお、調査にあたっては、イベントをトレースするために、これまでと同様に、各イベントプロパティを次のように設定しています。
フォームのイベントプロパティ



既存レコードを更新すると?

まずは、既存のレコードを更新した場合のイベントを調べてみます。「#5 フォームとテキストボックスの更新系イベントの違い」でも説明したように、レコード単位の更新のイベントは、レコードセレクタのクリックやレコード移動などによって、そのレコードが保存されたときに発生します。したがって、ここでは、「既存のレコードを編集し、レコードセレクタをクリックする」という操作に伴って、どのようなイベントが発生するかをウォッチしてみます。

発生順序 オブジェクト名 イベント名
1 frm顧客マスタ ダーティー時
2 frm顧客マスタ 更新前処理
3 frm顧客マスタ 更新後処理


2と3のイベントはもちろん、レコードを編集後、保存操作によって発生するイベントです。ここでは1番目の"ダーティー時"イベントについて説明しておきましょう。このイベントの発生時点をよく観察すると、レコードに含まれるいずれかのフィールドの内容を変更したとき(厳密には変更し始めたとき)に一度だけ発生していることが分かります。一度発生したあとは、いくらそのレコードを編集しても再度発生することはありません。そして、そのレコードを保存し、別のレコードに移動後また編集操作を行うと、やはり最初に一度だけ発生しています。カレントレコードに対して編集を加えていない場合にはこのイベントは発生しませんので、「そのレコードに対する編集が始まったかどうか」を検出したいような場面で使えるイベントといえるでしょう。

なお、
  • テキストボックスの"変更時"イベントとは違って、漢字入力においても、変換が確定する前の、何らかのキーインがあった時点で発生する
  • あとでレコード編集をESCキーなどでキャンセルしても、すでにこのイベントは発生しているため、レコードが最終的に更新されたかどうかは分からない
などの特性があるので、使用時には注意した方がよいでしょう。

ここでは省略しましたが、フォームを開いた直後の、一切編集やレコード移動を行っていない状態で、"レコード移動時"イベントがまず発生していることを付け加えておきます。これは、フォームが開くと同時に既存レコードの1レコード目(既存レコードがないときは新規レコード)が表示されることから分かるように、自動的に先頭レコードへの移動が行われているためです。



新規レコードを追加すると?

続いて、新規レコードをあらたに追加する場合のイベントの発生をトレースしてみます。

その結果は次の通りです。

発生順序 オブジェクト名 イベント名
1 frm顧客マスタ 挿入前処理
2 frm顧客マスタ ダーティー時
3 frm顧客マスタ 更新前処理
4 frm顧客マスタ 更新後処理
5 frm顧客マスタ 挿入後処理


全部で5つのイベントが発生していますが、実際の操作と照合してみると、まず、新規レコードに移動しただけではこれらのイベントは発生しません。新規レコードのいずれかのフィールドに何か1文字でも入力し始めると、"挿入前処理"イベントと"ダーティー時"イベントが立て続けに発生します。そのあとは、レコード内の編集をいくら行っても、フォームレベルでのレコード編集イベントは何も発生しません。そして、レコードが保存されると同時に、"更新前処理"・"更新後処理"・"挿入後処理"の3つのイベントが一挙に発生するという動作になっています。

既存レコードが更新されたときに"更新前処理"イベントや"更新後処理"イベントが発生するのはすでに説明していますが、この結果から、それらのイベントは「既存レコードだけに作用するものではない」ということが分かります。イメージ的にはすでにあるデータが"更新"されたときに発生するイベントのように感じますが、実際には新規にレコード追加したときにもこれらのイベントが発生しているのです。そのため、イベントプロシージャを使って、既存レコードが編集されたときと新規レコードが追加されたときとで別々の処理を行いたいような場合、その処理を更新後処理イベントプロシージャなどに記述してしまうと、レコード追加時にもその処理が起動し、予期せぬ動作をしてしまう可能性がありますので、この点は注意した方がよいでしょう。結果的に、フィールドの初期値をVBAから設定するような、"新規レコードが追加されたときだけ"何らかの処理を行いたいのなら、"挿入前処理"や"挿入後処理"イベントプロシージャを利用しなければなりません。

なお、既存レコードがある状態で新規レコードを追加するためには、新規レコード(最後のレコードの次のレコード)に移動する必要があります。したがって、そのような操作においては、当然のことながら"レコード移動時"イベントが事前に発生していることを付け加えておきます(上表では省略しています)。



既存レコードを削除すると?

続いて、既存レコードを削除してみます。

その結果は次の通りです。

発生順序 オブジェクト名 イベント名
1 frm顧客マスタ レコード削除時
2 frm顧客マスタ レコード移動時
3 frm顧客マスタ 削除前確認
4 frm顧客マスタ 削除後確認


ここでは、レコードセレクタをクリックしてレコード全体を選択、そしてDeleteキーを押すことによってレコードを削除しています。Deleteキーを押すとともに、1〜3の"レコード削除時"・"レコード移動時"・"削除前確認"の3つのイベントが立て続けに発生します。そして、そのあと、次のような削除の確認メッセージが表示されるという仕組みになっています。
削除確認メッセージ

ここで[はい]ボタンをクリックすると、実際にレコードが削除され、"削除後確認"イベントが発生します。


このイベント発生順序でおもしろいのは、"削除前確認"をしてからレコードが削除される(="レコード削除時"イベントの発生)のではなく、その逆になっている点です。レコードを削除してから削除確認を行うというおかしな動作ですが、画面の動きをよく観察してみるとうなずける話しです。Deleteキーを押すと、まずはそのレコードがいったん画面から消去される(A)のが分かります。そして、その次のレコードが前にシフトして画面に表示され(B)、そのあと、削除確認メッセージが表示されます。Aの動作に対応しているのが"レコード削除時"イベント、Bの動作に対応しているのが"レコード移動時"イベントです。つまり、とりあえずはレコードを削除してしまい、"削除前確認"で[はい]が押されたらそのまま削除処理を完了(コミット)し、[いいえ]が押されたらそのレコード削除を取り消す(ロールバック)という、一種のトランザクション処理的な動作をしているのです。

試しに、削除確認メッセージで[いいえ]を選択するとどうなるか確認してみましょう。このとき、次のようなイベントが発生します。

発生順序 オブジェクト名 イベント名
1 frm顧客マスタ レコード削除時
2 frm顧客マスタ レコード移動時
3 frm顧客マスタ 削除前確認
4 frm顧客マスタ レコード移動時
5 frm顧客マスタ 削除後確認

ポイントは、"削除前確認"イベントの次の"レコード移動時"イベントです。確認メッセージが出た時点ですでに次のレコードにカレントレコードが移っていますので、削除しようとしたレコードにカレントレコードを戻しているのです。これは実際の画面の動きからも分かります。


さて、意外と複雑な動きをしているレコード削除操作ですが、なぜ"レコード削除時"イベントだけでなく、"削除前確認"という「確認」イベントがあるのでしょうか?。実はこれをうまく使うことによって、削除動作をいろいろとコントロールすることができるのです。削除確認メッセージを表示せずに直ちにレコードを削除したり、逆に条件に応じて強制的に削除をキャンセルさせたり、独自の確認メッセージを表示させたりすることができるのです。イベントが発生したことを知らせるだけでなく、そのようなオリジナルな動作をさせるためのイベントといってもよいでしょう。

そのポイントはイベントプロシージャの引数にあります。

イベント名 宣言
フォームの削除前確認 Private Sub Form_BeforeDelConfirm(Cancel As Integer, Response As Integer)

「Cancel」と「Response」という2つの引数を利用することによって、多様な削除時のアクションを設定することができます。その詳細については、ここでは説明を省略しますが、Accessのヘルプ、あるいは当HPの「Access Tips」の「#011 レコード削除時のAccessのメッセージを表示させない方法」をぜひ参考にしてみてください。

| Index | Prev | Next |

 

Copyright © T'sWare All rights reserved