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

ユーザーフォームで入力ダイアログを作成する

タイトル画像

InputBox関数というのがありますが、ユーザーフォームで同じようなものを作成しようということです。
InputBoxだとボックスにテキストを入力するだけですが、ユーザーフォームですのでUIを自由に設計できます。

例えば、リストボックスから選択したり、ラベルをカレンダーのように配置して日付を選択したり、とかいろいろ応用できます。

これをどこからでも呼び出しできて、結果を返り値として受け取ることができるという仕様です。

ユーザーフォームの設計

動作原理を理解しやすいように、シンプルな仕様のものにします。原理が理解できたら応用して目的にあったものに改修できます。

ユーザーフォーム上には、InputBox関数と同様に、標題用のラベル、入力用のテキストボックス、[OK]ボタン、[キャンセル]ボタンを配置します。オブジェクト名は下記のように変更してください。

オブジェクト名前
ユーザーフォーム名InputFrm
ラベルlblPrompt
テキストボックスtxtImput
コマンドボタンcmdOK
コマンドボタンcmdCancel

cmdOK の Defaultプロパティを True にしておくと Enterキーでクリックしたことになります。
cmdCancel の Cancelプロパティを True にしておくと ESCキーでクリックしたことになります。

ユーザーフォームの設計例

ユーザーフォームモジュールのコード

ユーザーフォームのモジュールに下記のコードをコピーして貼り付けます。

InputFrmフォームの使用例

ユーザーフォーム上のコマンドボタンクリックで呼び出して入力結果をラベルに表示する。

ユーザーフォーム上のコマンドボタンクリックで呼び出して入力結果をテキストボックスに入れる。
テキストボックスに入力済みのテキストは規定値として InputFrm のテキストボックスに入力される。

ワークシート上にフォームコントロールのボタンを配置して、そのクリックでInputFrm を呼び出して、
結果はA1セルに代入する。既定値は A1セルの値。

コード中でユーザーの入力結果を変数に格納してあとで利用。

このように返り値のある関数のように直感的に記述できて、汎用性の高い使い方ができます。

動作原理

Property Get ステートメントで入力結果を返り値として取得することで関数のように使えるようにしています。

Property Get ステートメント (VBA) | Microsoft Docs

上の説明ではピンと来ないかもしれませんが、ユーザーフォームやコントロールにはプロパティがあり、それを設定することで表示や動作を設定できますよね。そのプロパティと同じようなものを独自に作成できるのが Property プロシージャ です。

VBAウィンドウで[挿入]-[プロシージャ]をクリックすると開くダイアログで種類に「Property プロシージャ」というのがあります。これを選択して、名前に「Result」としてOKをクリックすると下記のようにコードが入力されます。

プロパティは通常は、設定を変更できて、また、その設定を参照できます。
設定を変更するのが Property Let ステートメント、設定値を参照するのが Property Get ステートメントです。
今回は、結果を受け取るだけですので、Property Get だけあればOKです。
ということで、Property Let は削除して、Property Get を上方で提示したコードに書き換えます。

次にどのようにこのコードが動作しているか順に説明します。

まず、InputFrm の呼び出しの下記のコードですが、

これは、内部的には下記のような動作をしています。

フォームが Load されていないときに、プロパティを参照したり、メソッドを呼び出すと、自動的に Load が実行されてフォームがメモリ上に読み込まれます。

よく使うShowメソッドの場合も実は裏でLoad が実行されているのです。

Show メソッド (Visual Basic for Applications) | Microsoft Docs

InputFrm.Result が呼び出されると、InputFrm が Load されて Resultプロシージャのコードが実行されます。

Showメソッドの Modal引数はユーザーフォームをモーダル(vbModal)で表示するか、モードレス(vbModeless)で表示するかを設定します。 モーダルは開いたフォーム以外をユーザーは操作することができません。モードレスだとフォーム以外でも操作できます。ことえばフォームを開いているときでもユーザーはシートに入力できたりします。
もうひとつ大きな違いがあります。モードレスだとすぐにShow後のコードが実行れます。モーダルだとShowの後のコードは、フォームをUnLoadするか非表示にするまで実行されません。

このため、Me.Show vbModal でコードの進行はいったん停止して、ユーザーはInputFrmフォームを操作できます。

ユーザーがフォームのテキストボックスに入力して、OKボタンをクリックすると下記のコードが実行されます。

ここで、フォームが非表示になるので、Property Get Result の Me.Show の後のコードが実行されます。

そして、下記のコードに戻って、入力値が戻り値として返ってきて、TextBox1に代入されます。

以上が動作原理になります。
これが理解できると、後はユーザーフォーム上のコントロールをいろいろ変更して、いろいろな用途に応用できるようになります。

応用例

この仕様のままなら、InputBoxの代わりにそのまま使えます。
InputBox だとフォントサイズが小さいので、大きくして見やすくしたりとかデザインを自由に変更できます。
InputBoxは引数で表示位置を設定できますが、今回はこれは省略しましたが、必要なら、追加することも可能です。

テキストボックスの代わりに、コンボボックスやリストボックスにして、そこから選択できるようにすることも簡単です。

元ネタは下記ですが、

VBA - VBA:作成したカレンダーフォームを複数のフォームで使用したい|teratail

このようにラベルをカレンダーのように配置して、そのクリックで日付を入力するということも可能です。

Leave a reply






Trackbacks

trackback URL
https://hatenachips.blog.fc2.com/tb.php/522-12c18a79
該当の記事は見つかりませんでした。