2012/09/05

【Access】パラメータクエリにフォームのコントロール割り当てた時の問題点【VBA】

 今日も今日とて悩める後輩君。例によって頭を抱えていたので聞いてみた。
 以下、内容。
とある同一のクエリを使用し、フォーム(単票)とサブフォーム(データシート)を作成した。フォームとサブフォームの関係は親子ではなく対等であり、サブフォームをフォームのナビゲーションとして利用する。要はサブフォーム側のレコードを移動するとフォーム側のレコードも同じレコードに移動するというものである。
若干状況が分かりにくいのでここで一端サンプルとイメージを提示しときます。

テーブル
Books
Id
BookName
Price
Sales
Id
BookId
SaleDate
Num


クエリ
SaleList
Id
SaleDate
BookName
Num
Sale
(Num*Price)

フォーム
2012090501
ソース
'サブフォームのレコード移動時イベント
Private Sub Form_Current()
 
    '親フォームのレコードを自身のレコードのインデックスに移動する
    DoCmd.GoToRecord acDataForm, "SalesForm", acGoTo, Me.CurrentRecord
 
End Sub

 こんな感じです。こんな風にしたらって言ったのは自分ですが、面倒なことをさせてしまったもんです。…さて、後輩君もここまでは何も問題なく作成しておりました。

 問題はここからです。以下、再び内容。
フォームに使用したクエリに外部のフォームで確定した条件で抽出する必要が発生した。クエリをパラメータクエリに変更し、対象となるフォームのコントロールを参照するよう変更する。
これだけだと何が問題なのって感じですよね?とりあえずその通りにサンプルを追加・変更してレコード移動してみます。

フォーム(パラメータ設定用)
2012090502

クエリ
SaleList
Id
SaleDate
(Where: SaleDate = Forms![ParamForm]![SaleDateText])
BookName
Num
Sale
(Num*Price)

実行時
2012090503
 あれ?サブフォームのレコード移動するとこけるようになっちゃいましたってなわけです。う~ん、細かく見てみましたがぶっちゃけはっきりとした原因は分かりませんでした。流れ的にはサブフォーム側の移動が実行され、フォーム側の移動が実行されるんですが、ここで終了せず何でかサブフォームの先頭レコードにフォーカスが移っちゃって再度同じイベントが発生して…って感じです。自分の推測としては移動後にパラメータクエリのフォーム参照が再評価に走ってフォームのフォーカスが飛んじゃってるんじゃないかなって感じです。すごく不確かですが。こりゃ後輩君も悩むよねって話です。
 とりあえず後輩君にはこのやり方自体諦めて違う手段を考えようって言いました。後輩君には教えなかったんですが自分的な代替え案としてはパラメータクエリを諦めて、外部フォームを参照するのをクエリではなくフォームにしてフィルタで対応したらってとこですね。一応サンプル載せときます。当然、後輩君はこのブログを知りません。

ソース(メインフォーム側)
'メインフォームのオープン時イベント
'Loadで書くとフィルタの挙動がおかしくなったのでこちらにしました
Private Sub Form_Open(Cancel As Integer)
 
    '外部フォーム(ParamForm)の設定値を取得
    Dim param As String
    param = Forms!ParamForm!SaleDateText
    
    '自身のフィルタ設定
    Me.Filter = "SaleDate = #" & param & "#"
    Me.FilterOn = True
    
    'サブフォームのフィルタ設定
    Me.SubForm.Form.Filter = "SaleDate = #" & param & "#"
    Me.FilterOn = True
    
End Sub


HP Directplus オンラインストア
pagetop