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

入力ダイアログフォームの設計

メインフォーム上に複数のサブフォームコントロールが配置してあります。ソースオブジェクトには同じフォームが設定してあります。サブフォーム上のコマンドボタンをクリックすると別フォームを開き、値を入力します。その値を同じサブフォーム上のテキストボックスに代入したい。

というような質問がありました。複数のサブフォームがありますので、どのサブフォームのコマンドボタンをクリックしたかを判別する必要があります。しかし、元は同じフォームですので、コマンドボタンの名前や自分自身のフォーム名で判断することはできません。

では、どうしたらいいでしょうか。

難易度:

仕様

まずは、仕様を下記のようだと仮定します。

サブフォーム
コマンドボタン cmdOpenInputForm
値が代入されるテキストボックス txt1

呼び出される別フォーム InputForm
コマンドボタン cmdInput
テキストボックス txtInput

サブフォーム上のコマンドボタン cmdOpenInputForm をクリックすると別フォーム「InputForm」を ダイアログモードで呼び出す。

別フォーム上の txtInput に値を入力して、cmdInput をクリックするとサブフォーム上の txt1 に txtInputの値を代入して 自分自身を閉じる。

サンプルコード1

さて、質問者さんは、サブフォーム上のコマンドボタンをクリックしたときに、フォーカスのあるサブフォームコントロール名が取得できれば、解決できると考えたようです。

これは、Screen.ActiveForm.ActiveControl.Name で取得できます。これを OpenForm の OpenArgs引数で渡せばいいですね。
具体的には下記のコードになります。

サブフォームのモジュール

入力フォーム上のモジュール

別フォームをダイアログモードで開いてますが、ダイアログモードは、開いたフォームを 閉じるまでは、そのフォーム以外は操作できなくなります。今回のような入力フォームの 場合、誤操作を防ぐためには必須の設定です。

サンプルコード2

サンプルコード1だと、Forms!メインフォーム と特定のフォーム名で参照してますので、入力フォーム(InputForm)を他のメインフォームでも共有して使うというようなことができません。また、途中で設計変更で、代入先がメインフォームへ移動になった、あるいはサブフォームのサブフォーム(孫フォーム)へ移動になったというときにコードを変更する必要がでてきます。

この入力ダイアログフォームを、メインフォームでもサブフォームでも、また、孫フォームでも、複数のフォームからでも共有して利用できるといいですね。

呼び出し側のフォームのモジュール

入力フォームのモジュール

事前に代入したいテキストボックスへフォーカス移動させておきます。その後入力フォーム(InputForm)をダイアログモードで開きます。入力後、cmdInput をクリック時で、自分自身(InputForm)を非表示にすると、直前にフォーカスのあったコントロールがアクティブになります。ですので、Screen.ActiveControl に値を代入すればいいことになります。

共有部品化をさらに推し進めて関数にするともっと簡単に共有利用できるようになります。

入力フォームのモジュールは上記のままで、標準モジュールに下記の関数を作成します。

このようにしておけば、呼び出し側のフォームのコマンドボタンのクリック時のイベントプロパティの「クリック時」欄に
=CallInputForm([txt1])
と入力するだけで入力フォームを呼び出せます。
また、テキストボックスのダブルクリックで入力フォームを呼び出したい場合は、テキストボックスのイベントプロパティの「ダブルクリック時」欄に
=CallInputForm()
というように引数を省略して設定します。

なお、カレンダーコントロールを利用した日付入力汎用関数 でも同様の手法で汎用関数化してます。

サンプルファイルが下記からダウンロードできます。
FrmInputDlg_07.zip (Access 2007-2010 形式 - 26kb)
FrmInputDlg.zip (Access 2002-2003 形式 - 19kb)
FrmInputDlg_2k.zip (Access 2000 形式 - 18kb)

拍手する

6 Comments

きりか says...""

Access Club でこの質問をした きりか です。

わかりやすい解説、ありがとうございます^^

標準モジュールのコードがいまいち理解できませんが、サンプルを活用し、自分でいじって覚えてみようと思います。

2009.04.06 11:38 | URL | #SFo5/nok [edit]
hatena says..."がんばってください"

コードで分からない部分がありましたら、なんなりとご質問ください。

2009.04.07 00:22 | URL | #5uE6dEgY [edit]
なおと says..."大変参考になりました、、、1点教えてもらえますか?"

このサンプルコード2大変助かりました。
テキストボックスに対して製品・取引先・受注コードの検索フォームを、それぞれのフォームごとに作成していましたが、ひとつのフォームで対応できるようになり大変助かっています。
しかしながら一点、、、サンプルコード2の場合、値を代入後の更新後イベントが発生しないという問題が、、、
もし心当たりがありましたら、ちょっとだけヒントをいただければ、、、お願いします。

2009.04.13 22:02 | URL | #ZxXOt7Ek [edit]
hatena says..."Accessの仕様です。"

なおとさん、こんばんは。

> しかしながら一点、、、サンプルコード2の場合、値を代入後の更新後イベントが発生しないという問題が、、、

ユーザーの入力でなく、VBAやマクロでの値の代入では、更新関係のイベント(更新前処理、更新後処理等)は発生しないというのは、Accessの仕様です。

対処法としては、2つあります。

ちょっと長くなりそうなので、別に新規記事として投稿しますので、しばらくお待ちください。

2009.04.13 22:29 | URL | #5uE6dEgY [edit]
hatena says..."新規記事として投稿しました"

「値の代入で更新イベントを発生させる」
http://hatenachips.blog34.fc2.com/blog-entry-57.html

2009.04.14 00:48 | URL | #5uE6dEgY [edit]
says..."承認待ちコメント"

このコメントは管理者の承認待ちです

2016.02.13 19:00 | | # [edit]

Leave a reply






Trackbacks

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