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

レコード保存ボタンのクラス化

前回の記事 マウスホイールでレコード移動しないようにする で「保存」ボタンをクリックしたときのみレコード保存できるようにする仕様のフォームを作成しましたが、ボタンのクリックイベント以外に、フォームの更新後処理、更新前処理、ダーティ時、取り消し時 のイベントプロシージャも記述する必用がありました。入力フォームが一つだけならいいのですが多数ある場合、ユーザーインタフェイスを統一するためにすべての入力フォームに同じようコードを記述することになります。これはちょっと面倒ですし、メンテナンス性の面からも問題があります。

そこで、この 保存ボタン、取消ボタン のクラス化に挑戦してみましょう。

難易度:

フォーム上にコマンドボタン「cmd保存」「cmd取消」を配置するのは前回と同じです。

メニューから[挿入]-[クラスモジュール]をクリックして開いたVBA画面で下記のように記述します。

追記: AC2000以前では、取り消し時イベントが実装されていませんので、上記のAC2000以前に関するコメントをご確認ください。また、キーボード(ESC, Ctrl+Z)やメニューから取り消し操作を行ったとき、保存ボタン、取り消しボタンの使用可能が切り替わりません。

前回のフォームモジュールとの違いは、Bindメソッドと、オブジェクト名を変数にしたところぐらいです。ポイントは複数のコントロール「保存」と「取り消し」ボタン、その親フォームと関連づける部分ですね。

コードを記述したら、clsSaveButton と名前をつけて保存してください。

あとはフォームモジュールを下記のように記述するだけです。

加筆修正(2010/3/18): 新規レコードのとき、更新しても 保存ボタン、取り消しボタンが使用可能にならないという不具合がありました。対策として、挿入前処理のコードを追加しました。

いかがでしょうか。フォームモジュールが非常にスッキリしましたね。

もう一つクラス化のメリットとして、カプセル化ということがあげられます。今回は「保存ボタンをクリックしたときだけレコード保存できる」という仕様を実現するために必用なコードを一ヶ所(クラスモジュール)にまとめて記述してフォームモジュールから見えないようなりました。このことでフォームモジュールがスッキリしたし、またこの仕様に関係するコードを一元管理できることになります。仕様変更があった場合もクラスモジュールの変更だけで済むことになります。大きなシステムを開発しているときはこれは大きなメリットになります。

追記: これに、「閉じるボタン」も追加して、更新中に閉じるときに、保存して閉じるか、閉じるのをキャンセルするか選べるように改良したクラスを下記で紹介しています。
「レコード保存ボタン」クラスの改良
上記が「レコード保存ボタン」クラスの現状での最終バージョンです。

サンプルファイルが下記からダウンロードできます。
FrmSaveButtonClass_07.zip (Access 2007-2010 形式 - 34kb)
FrmSaveButtonClass.zip (Access 2002-2003 形式 - 28kb)
FrmSaveButtonClass_2k.zip (Access 2000 形式 - 28kb)


拍手する

4 Comments

ほいっと says..."クラス化にした時の不具合"

今晩は。今クラス化を自分のほうで試していますが、一つ何か変な不具合があります。
フォームのコントロールで、クラス化に宣言しているコントロールは、そこに値を入れると、保存ボタン、取消ボタンのEnabledプロパティが有効になるのですが、自分のフォーム特有のコントロールのイベント処理をそのフォーム自身のモジュールに記述してるもの(クラスの中では含めていないもの)に文字列を入力したりすると、ボタンが有効化されません。これは、何故でしょうか?

2014.11.16 22:47 | URL | #mQop/nM. [edit]
ななし says...""

いつも役立つ情報をありがとうございます。

上の共通化した処理を、テーブル構造が同じマスター画面の登録・修正画面に使ったら、とてもうまく出来ました。これで、1つの画面を使いまわすやり方がわかりました。

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

2014.11.22 16:48 | URL | #mQop/nM. [edit]
hatena says..."re:クラス化にした時の不具合"

文章だけでは、具体的に何をしているのか把握できません。

実際のコードを提示して、何をどうしているか説明してもらえますか。

2014.11.22 17:22 | URL | #5uE6dEgY [edit]
ななし says..."re:クラス化にした時の不具合"

お忙しいところご対応して頂き、ありがとうございます。
私の説明の不手際で、お時間を取らせてしまい、大変もうしわけありません。

例えば、以下のように書いたとします。確か、こんな感じでした。
Option Compare Database
Option Explicit
Private ClsSaveBtn As New clsSaveButton

Private Sub Form_Load()
  ClsSaveBtn.Bind Me.cmd保存, Me.cmd取消, Me.cmd終了, Me.日時, Me.作業記録ID, Me.RecordSource
  
End Sub

Private Sub 日時_DblClick(Cancel As Integer)
  Me.日時.Value = Format(Now(), "yyyy/mm/dd hh:MM:ss")
  
End Sub

このフォームには、日時というフィールドがあります。
そのフィールドをダブルクリックして日時を入れて新規入力すると、保存ボタンがアクティブにならず、登録が出来ませんでした。

多分、このようにクラスにBindする処理をいれたら、このフォームのイベントは使わないようにするのが決まりなのでしょうか。

あと、フォームのForm_Load時にクラスのBind処理すると、クラス化した方のForm_Load, Form_Openイベントは動作しませんでした。すると、クラスの中でLoad時にしたい処理が一向に出来ず困りました。

何故でしょうか?タイミング的に合わないのでしょうか。

説明ベタですが、読んで頂き、回答もして頂き大変ありがとうございます。

宜しくお願いします。

2014.11.22 23:03 | URL | #mQop/nM. [edit]

Leave a reply






Trackbacks

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