こんにちは。じじグラマーのカン太です。
衰えいく能力に怯えながらも、現役で週末プログラマーをしています。
今回の記事は、Accessのフォームで大量のテキストボックスを配置する方法を紹介します。また、その際に、フォーカスどのテキストボックスにるのかを知る方法も紹介します。
では、早速はじめましょう。
大量のテキストボックスを配置するには
お客様より「一覧表形式で表示された在庫場所に在庫品のあるなしを表示し、ないところには入庫、あるところからは出庫の処理がしたい」という要望をいただきました。
在庫場所は、ざっと600ヵ所くらいなのでタブを用いて1ページに100ヵ所ずつ、6ページで構成されるフォームを作ろうと考えました。
気の遠くなるような作業を繰り返し、ひとつ目のタブに、在庫場所名のラベルとそこに入庫される部品を表示するテキストボックスを配置しました。
あとはコピーして・・とコピーを続けると3ページ目くらいで
「このフォームまたはレポートにさらにコントロールを作成することはできません」
という無情なエラーメッセージが表示されました。
どうやら、Accessの仕様でひとつのフォーム内には、754以上のコントロールを設置することはできない仕様になっているようです。
仕様であれば仕方がありません。Google先生に頼りましたところ、Accessには「サブフォーム」なるものがあり、それをフォーム内に埋め込むことができることがわかりました。
サブフォームを埋め込む
まず、メインフォームに6つのページがあるタブを用意します。次に、100ヵ所ずつに分割した在庫場所の一覧表フォームを6つ作ります。メインフォームひとつ、サブフォーム6つという構成です。
メインフォーム内で、「デザイン」メニューから「サブフォーム」を選択して、表示したいエリアにドラッグして広げます。サブフォームのエリアができますので、そのプロパティの「ソースオブジェクト」欄に、作成したサブフォームを指定します(選択できるようにしてくれています)。
この作業を6回繰り返すと、6ページ分に渡る在庫場所一覧表ができあがります。この方法ですと、コントロールの上限は各サブフォーム内でのみカウントされ、親フォームのカウント数には影響しないようです。
ひとつのフォーム内に大量のテキストボックスを配置するには、「いくつかのフォームに分割して作成し、その作成したフォームを親フォームにサブフォームとして埋め込む」という方法が有効なようです。
フォーカスのあるコントロール名の取得方法
大量のテキストボックスを配置した場合、それぞれのクリックイベントに書くのは不可能に近いくらいの作業になります。そこで、クリックしたタイミングでフォーカスのあるテキストボックスの名前を取得する方法がないものか・・・やっぱりありました。
Dim strActiveCntrl as string
strActiveCntrl = Me.ActiveControl.Name
「ActiveControl」という便利が命令がありました。さらに、現在のフォーカスの前にあったコントロール名を調べる命令までありました。「Screen.PreviousControl.Name」という命令です。
テキストボックス全てにイベントを記述するのは不可能に近い場合、「テキストボックスにフォーカスを当て、ボタンをクリックさせる」というオペレーションで代用できます。ボタンをクリックした瞬間にフォーカスはボタンに移るので、「ActiveControl」ではボタンの名称が取得されてしまいます。そこで、「Screen.PreviousControl.Name」を使えば、ボタンにフォーカスが移る前のコントロール名が取得できます。
Dim strActiveCntrl as string
strActiveCntrl = Screen.PreviousControl.Name
サブフォーム内のフォーカスのあるコントロール名の取得方法
この「Screen.PreviousControl.Name」ですが、サブフォーム内のコントロールにフォーカスがある場合、サブフォーム名を返してくれるみたいです。そこで、サブフォーム内のフォーカスのあるコントロール名の取得するには、サブフォーム名を取得した上で、そのサブフォーム内でフォーカスのあるコントロール名を取得してあげる必要があります。
Dim strActiveCntrl As String
If Screen.PreviousControl.Name = "サブフォーム1" Then
strActiveCntrl = Me!サブフォーム1.Form.ActiveControl.Name
ElseIf Screen.PreviousControl.Name = "サブフォーム2" Then
strActiveCntrl = Me!サブフォーム2.Form.ActiveControl.Name
・
・
・
End If
まとめ
いかがでしたでしょうか。Accessのフォームで大量のテキストボックスを配置する方法を紹介してみました。本来であれば、設計段階でこんなことにならないようにするべきなのでしょうが、お客様の強い要望の前にいい対案が思い浮かばず、このような仕様になってしまいました。
サブフォーム内のテキストボックスの名称を取得するとなると、ネストが深くなってこんがらがってしまいますね。
もっとスマートな方法があれば、教えていただけるとありがたいです。
コメント