- ●メイン/サブフォームのリンク方法の変更
- 本題材のデータベースには「業務履歴検索」という画面があり、メイン/サブフォーム形式になっています。メインフォーム側のリストボックスで「人材ID」を選択すると、サブフォーム側にはそのデータだけが抽出表示されます。その際、内部的にはサブフォームにはレコードソースとなっているテーブルやビューの全レコードがサーバー側からあらかじめ読み込まれ、メイン側の切り替えに応じてその都度クライアント側でフィルタリングされることになります。

この画面ではサブフォーム側でデータを編集することはなく、スナップショット(ある時点での静的なデータ)としてデータを取得するだけですので、メイン/サブフォームのリンク形式を、ストアドプロシージャを使った方法に変更してみます。
- なお本題材の場合、「ニーズ検索」画面も同じような構成になっています。
- まず、サブフォームのレコードソースとなっているクエリ(ビュー)をストアドプロシージャに変更します。それにはまず、クエリのデザインビューを開き、SQLペインからSQL文をクリップボードにコピーします。

- 次に、リボンの[作成]タブから[その他]-[ストアドプロシージャ]を選択します。
- 「テーブルの追加」ダイアログではそのまま[閉じる]ボタンをクリックし、ストアドプロシージャのデザインビューを表示します。
- そして、先ほどコピーしたSQL文をSQLペインに貼り付けます。

- ここでは、「tbl業務履歴」テーブルの「人材ID」フィールドが抽出条件(サブフォームコントロールのリンク子フィールド)となりますので、「抽出条件」の欄に「@抽出人材ID」と書き込みます。「@」がパラメータであることを表わし、「抽出人材ID」は任意のパラメータ名です。

- 別名でこのストアドプロシージャを保存してもかまいませんが、ここでは既存のビュー「qsel業務履歴検索」を削除して、その名前で保存することとします。
- 次に、ここからフォーム側の変更に移ります。
まず、サブフォームの「入力パラメータ」プロパティに、プロパティシートから次のような式を書き込みます。
@抽出人材ID nvarchar(15) = Forms!frm業務履歴検索!lst登録者一覧

ここに指定するのは、レコードソースとなっているストアドプロシージャに対するパラメータです。書き方としては、まずストアドプロシージャ上のパラメータ名を「@」付きで表記します。そのあとに半角スペースを入れてそのパラメータのデータ型をSQL Serverの形式で記述します。そして、「=」に続けてそこの代入する式を指定します。ここでは、『nvarchar(15)というデータ型の@抽出人材IDに対して、「frm業務履歴検索」フォーム上のリストボックスコントロール「lst登録者一覧」の値を代入する』という指定になっています(ここでは「Parent!lst登録者一覧」という表記は使えません)。
- メインフォームについて、サブフォームコントロールの「リンク親フィールド」と「リンク子フィールド」の2つのプロパティ値を空欄にします。
- また、このフォームからは次のような命令でレポートを開いています。
DoCmd.OpenReport "rpt業務履歴", acViewPreview, , "人材ID='"
& Me!lst登録者一覧 & "'"
リストボックスで現在選択されている「人材ID」の値をWhere条件としてレポートを開いていますが、このレポートも同じパラメータ付きのストアドプロシージャをレコードソースとしているため、フォームと同様に「入力パラメータ」プロパティを設定します。
- OpenFormメソッドでWhere条件を指定してフォームを開いている場合にも、このようにレコードソースをストアドプロシージャとして「入力パラメータ」プロパティを指定する方法が使えます。
なお、このような仕組みにした場合、メインフォーム側で従来リンク親フィールドとなっていたコントロールの値が変更されるたびに、サブフォームを再クエリする必要があります。VBAの場合には、そのコントロールの「更新後処理イベント」を使ってサブフォームを再クエリします。メイン/サブフォーム形式とは異なり、この処理を行わないとリストボックスを変更してもサブフォームの内容が自動的に切り替わりません。
またこのフォームでは、[全登録者を表示]というチェックボックスがあり、チェックの有無によってサブフォームコントロールのリンクフィールドを切り替えています。

従来は、チェックが付いていない場合は「リンク親フィールド」と「リンク子フィールド」プロパティに値を設定することでメインフォームのリストボックスとサブフォームが連動するようにし、チェックが付けられた場合はそれらのプロパティを空にすることでリンク解除すなわちサブフォームに全レコードが表示されるようにしていました。
しかし今回、サブフォームはパラメータ付きのストアドプロシージャに変更しましたので、そのままではうまく動作しません。
そこで、VBAのモジュールで、『もしチェックが付けられたらレコードソースをパラメータなしのストアドプロシージャ(これも新規に作成)に切り替えるとともに、入力パラメータ(InputParameters)を空欄にする』といった対処が必要となります。
【プログラム例】
Private Sub chkAll_AfterUpdate()
'[全登録者を表示]チェックボックスの更新後処理
If Me!chkAll Then
'チェックマークが付けられたとき
With Me!frm業務履歴検索_sub.Form
.RecordSource = "qsel業務履歴検索全件"
.InputParameters = ""
End With
〜〜〜〜〜〜〜後略〜〜〜〜〜〜〜〜
|