MS Access Tips/Sample and VBA and Blog customize etc...

閉じるときに更新前処理をキャンセルすると出るメッセージを変更

以前の記事 保存前に確認するマウスホイールでレコード移動しないようにする などのように更新前処理でイベントをキャンセルするコードを記述しているときに、フォームを閉じるアクションで連鎖して更新前処理が発生しそれをキャンセルしたときに、下記のようなシステムメッセージがでます。

このような無粋なメッセージではユーザーに困惑と不安を与えるだけのなで、ユーザーに優しいオリジナルなメッセージを表示したいですね。今回は、これを考えてみます。

FrmSaveCancelErr.gif

難易度:

保存前に確認する の方のサンプルを元に解説します。フォームの更新前処理に下記のコードが設定されてます。

フォームのタイトルバーのクローズ(×)ボタンをクリックすると、"保存しますか?" と聞いてきますので、[キャンセル]をクリックすると、上記のシステムメッセージがでます。

さて、このシステムメッセージは On Error ステートメントによるエラートラップではとらえることが出来ません。では、どうするかというと、フォームの「エラー時」イベントでトラップできます。

フォームのエラー時のイベントプロシージャを下記のように記述します。

これで、フォームのタイトルバーのクローズ(×)ボタンをクリックして、[キャンセル]をクリックすると、下記のようにオリジナルのメッセージが表示されます。

FrmSaveCancelErr1.gif

さて、ここで、先のシステムメッセージとオリジナルメッセージを比べてみると、前者は[はい][いいえ]のボタンがあり、更新破棄して閉じるのか、閉じるのをキャンセルするのか選べますが、後者は、破棄して閉じることしかできません。これではユーザーに親切とは言えませんね。ただ、エラー時では、Cancel引数がありませんので、閉じるアクションを止めることはできません。

そこで、"保存しますか?" と聞いて、[キャンセル]をクリックされたらフォームを閉じれないように、フラグ変数を利用して読み込み解除時イベントでキャンセルします。

フォームモジュール

しかし、これでは、閉じるのは阻止できましたが、更新内容は破棄されてしまいます。更新内容はそのままで、編集状態を維持しなければ意味がありません。これがなかなか難しい。読み込み解除時では更新内容が破棄された後なので。

そこで、力業ですが、エラー時で、更新データを変数に格納しておいて、読み込み解除時に変数からフィールドに戻すという方針でやることにします。とりあえずテストとして、「自宅住所2」だけを対象として下記のようにしてみました。

「自宅住所2」を更新→「閉じる」クリック→「更新しますか?」→「キャンセル」クリック→閉じずに、編集状態維持
成功です。希望の動作になりました。

すべてのフィールドに対して、更新値格納、更新値を代入するコードを記述すればいいのですが、汎用化するために、下記のようなコードにしました。

ロジックとしては、開くときに動的配列にレコードソースのフィールド名を格納しておいて、それと同じ要素数のデータ格納用の動的配列も宣言(ReDim)します。エラー時に更新データを格納して、読み込み解除時にフィールドに戻します。2つの動的配列を使いましたが、2次元動的配列やCollectionやDictionalyオブジェクトを使ってもいいでしょう。これで、フィールド構成の異なるフォームに対しても同じコードで対応できます。

サンプルファイルが下記からダウンロードできます。
FrmUpdateCancelErr_07.zip (Access 2007-2010 形式 - 26kb)
FrmUpdateCancelErr.zip (Access 2002-2003 形式 - 25kb)
FrmUpdateCancelErr_2k.zip (Access 2000 形式 - 21kb)

拍手する

3 Comments

まゆ says..."サブフォームも更新するか認識させたいです"

はじめまして
今回の記事で「閉じる」のボタンを作らずに更新の有無が確認できるようになったので非常に助かっています。

しかし、フォームの中に複数サブフォームを埋め込んでおり
サブフォームで変更を加えた際は確認無しで閉じてしまい
また、メインフォームで入力したあとにサブフォームへカーソルを移動させると変更の有無が確認されてしまいます。

・サブフォームを編集してもレコード移動や閉じる際に確認されるように
・同じレコード内のカーソル移動では確認をされないように
この2点を反映できるようなVBAは可能でしょうか。。。

2016.10.06 11:44 | URL | #7lwdvH2o [edit]
hatena says..."re:サブフォームも更新するか認識させたいです"

> ・サブフォームを編集してもレコード移動や閉じる際に確認されるように
> ・同じレコード内のカーソル移動では確認をされないように
> この2点を反映できるようなVBAは可能でしょうか。。。

連結フォームのメイン/サブフォーム形式では、仕様上不可能です。

連結フォームの場合、レコード移動するとレコード保存される
→サブフォームはおそらく複数レコードの登録になると思いますが、上記の使用上、1レコードごとに確認が発生します。

連結のメイン/サブフォームは、メイン→サブ、サブ→メイン というフォーカス移動があった時点でレコード保存される。

ということで、ご希望のことを実現するには、
メインフォームは非連結にして、サブフォームは一時テーブルに一旦入力してから、
本テーブルに戻すという処理をVBAで構築する必用があります。

これは、かなりのスキルとコード量を必用とします。

2016.10.06 12:29 | URL | #5uE6dEgY [edit]
まゆ says...""

わかりました。
ありがとうございます。

サブフォームが必要なフォームは閉じるボタンを作成して対応させていただきますm(_ _)m



申し訳ございません。お礼を誤って
http://hatenachips.blog34.fc2.com/?no=397
にコメントしてしまいました;
削除等必要であればお願い致します。。。

2016.10.07 10:42 | URL | #- [edit]

Leave a reply






Trackbacks

trackback URL
http://hatenachips.blog34.fc2.com/tb.php/180-baf2ff1f
該当の記事は見つかりませんでした。