Microsoft Access 掲示板

サブフォームでのDlookup

17 コメント
views
4 フォロー

こんばんわ。
すいませんが以下の点についてご教授願えませんか。

フィールドが

個人ID 氏名

だけの
クエリ1
を作っています。

ここで、メインフォーム(基礎情報編集2)上で、コンボボックス「M_CMB」に「個人ID」フィールドの値を1~10まで選択できるようにしています。
そしてメインフォーム上にあるテキストボックスのコントロールソースに
=DLookUp("氏名","クエリ1","個人ID=" & [M_CMB])
と入れると、思うように氏名を抽出してくれます。

そこで、サブフォームを作成し、そこにテキストボックスを設置して
=DLookUp("氏名","クエリ1","個人ID=" & [Forms]![基礎情報編集2]![M_CMB])

と入力すると同じように抽出してくれるのかなと思ったのですが、エラーを返されてしまいました・・・

なぜか、すいませんがご教授願えませんでしょうか。

ろでます
作成: 2020/07/07 (火) 03:34:45
通報 ...
1
hiroton 2020/07/07 (火) 09:31:57 3dd82@f966d

フォーム名が間違っているくらいしかなさそうですが、「基礎情報編集2」はフォーム名で合ってますか?(フォームのプロパティの「標題」ではないですよね?)

2
ろでます 2020/07/07 (火) 15:51:29 61da2@be317

こんにちわ、ろでますです。
フォーム名が間違っているということはないと思います。
一度フォームを組み立てなおしても、同じエラーが出て、かなり困っています。
・メインフォーム名=基礎情報編集
・コンボボックスの名前=M_CMB
・クエリ名=クエリ1

メインフォーム上で
=DLookUp("氏名","クエリ1","個人ID=" & [M_CMB])
では、テキストボックスに「Aさん」が入ってくれますが
サブフォームに
=DLookUp("氏名","クエリ1","個人ID=" & [Forms]![基礎情報編集]![M_CMB])
と入れると
「#エラー」
となります。

何処がおかしいのか、以下の様にしたら、Aさんが取れました。
=DLookUp("氏名","クエリ1","個人ID=" & 1)

同様に以下の様にしたら、Bさんがとれました。
=DLookUp("氏名","クエリ1","個人ID=" & 2)

つまり、Dlookup関数の構文は間違っていないけども、M_CMBの値がちゃんと取れていないようです。
フォーム名等も、式ビルダーを使って、タブキーを押しながら選んでいったので、間違いはないと思います。

すいません、よろしければ、サブフォームに引き渡されているM_CMBの値を見る方法はありませんか。

よろしくお願い申し上げます。

3

サブフォームに
=DLookUp("氏名","クエリ1","個人ID=" & [Forms]![基礎情報編集]![M_CMB])
と入れると
「#エラー」
となります。

何処がおかしいのか、以下の様にしたら、Aさんが取れました。
=DLookUp("氏名","クエリ1","個人ID=" & 1)

=[Forms]![基礎情報編集]![M_CMB]
としたときは、正しい個人IDが表示されますか。

メインフォーム上で
=DLookUp("氏名","クエリ1","個人ID=" & [M_CMB])
では、テキストボックスに「Aさん」が入ってくれますが

ということなら、このテキストボックスは非表示で配置しておいて、サブフォームのテキストボックスのコントロールソースを下記のように設定してみたらどうなりますか。

=[Parent]![テキストボックス名]

4
ろでます 2020/07/07 (火) 19:03:35 61da2@be317

>=[Forms]![基礎情報編集]![M_CMB]
>としたときは、正しい個人IDが表示されますか。

テキストボックスの値は真っ白でした・・・
全く値が取れていないようですね・・・。

>=[Parent]![テキストボックス名]

同じく、
「#エラー」
となりました・・・><

VBAとかで細かく値の受け渡し状況を確認する方法とかあれば・・・

5

>=[Forms]![基礎情報編集]![M_CMB]
>としたときは、正しい個人IDが表示されますか。

テキストボックスの値は真っ白でした・・・
全く値が取れていないようですね・・・。

これで、
フォーム名、コンボボックス名に間違いがないとすると、
外から原因を特定するのは難しそうです。

症状の再現できるなるべくシンプルなファイルを、右カラムのファイル送信フォームから送ってもらえませんか。
そうすれば、現物をみて原因を特定できるかもしれません。

6
ろでます 2020/07/07 (火) 20:05:03 61da2@be317 >> 5

こんばんわ、ろでますです。
お手数おかけしますm(_ _)m

ファイルの方送付させていただきました・・・
が、この掲示板ではどこでアップしたファイルがダウンロードできるようになっているのでしょう。
手順を間違えたでしょうか(汗

7

送信ありがとうございました。
ファイルは私のところにメールで届いています。
自動でダウンロードできるようにはなってません。

ファイルを見てみました。
原因はメインフォームで個人IDを変更したときに、サブフォームで再クエリか再読み込みか再計算をしないと変更が反映されないようです。

コンボボックス「M_CMB」の更新後処理のイベントプロシージャで再読み込みをしたらエラーなく表示されて、更新するとサブフォームの値も更新されました。

Private Sub M_CMB_AfterUpdate()
    Me.個人別.Form.Refresh
End Sub

下記が修正済みのファイルです。

ZIPファイル

ただ、サブフォームが非連結(レコードソースが空欄)で、リンクフィールドが設定されていないために、自動で再読み込みが発生しないのが原因だと思われます。

通常、サブフォームはテーブルかクエリに連結させて、リンクフィールドを設定すると思います。そうすれば、リンクフィールドを更新すればサブフォームも再読み込みされます。

現状の非連結のサブフォームは、サブフォームにする必然性があるようには思えません。
最終的にどのようなものを考えているのでしょうか。

8
ろでます 2020/07/07 (火) 21:05:58 61da2@be317 >> 5

早々なご対応、誠にありがとうございます。
一番の問題は私自身の知識不足です。

エクセルからのAccessへの移行なので、その辺の知識が完全に欠落しております。

「関数に間違いない変数を渡してるんだから、計算して当然」
という思い込みがありました。

私もレコードセットは疑って、色々試したんですが、とりあえず、クエリ1でいいのかなと思って当てたものの、うまくいかず(エラーのまま)、であれば、SQL分でSelect・・・で書いたものはどうか、と色々試しては見たんですが結果が同じでしたので、そのまま非連結の状態でお渡ししてしまったという経緯です。

やはり、一番望ましいのは、

>リンクフィールドが設定されていないために、自動で再読み込みが発生しないのが原因だと思われます。

これを回避するために、リンクフィールドをきちんと設定してあげて、自動で再読み込みさせるのが理想です。

もしよろしければ教えていただきたいのですが、このような場合、どのようなレコードソースを設定してあげるのがよろしいのでしょうか。

ご教授いただけると助かります。

9
ろでます 2020/07/07 (火) 21:13:23 61da2@be317 >> 5

ちなみに、とりあえずの最終形態として考えているは、
個人別サブフォームを帳票フォームにして、
M_CMBを1に切り替えると、
Aさん ○○障害
Aさん ××障害
Aさん △△障害

そして、2に切り替えると、帳票フィールドの行数も動的に変化し
Bさん ××障害
Bさん △△障害

といった形に持って行きたいと思っています。
今は。帳票フォームの行が全部AさんやBさんになっているので、そこからまた頭を使って考えなければなりません(^^;

10
ろでます 2020/07/07 (火) 22:37:00 61da2@be317 >> 5

たびたびすいません、もう一点。
レコードソースについてなのですが、少し他の人に以前教えていただいたところ、VBAの中で

Private Sub M_CMB_AfterUpdate()
   [Forms]![基礎情報編集]![M-CMB].Requery
   sqlstr="SELECT * " &・・・
   Me.F_個人別.Form.RecordSource = sqlStr
   Me.F_個人別.Form.Requery
end sub

で、サブフォームのレコードセットは適当でも、これで書き換わるからいいと教えられました。
確かにこれでサブフォームのレコードセットは書き換わってうまく動作はするのですが・・・

だったら、最初からマクロに書かないで、レコードセットの所に直接書けば動くのでは?、と思い書くと動きませんでした。

こういう場合、このようなやり方は一般的なのでしょうか?

後からこのDBのフォームを見た人は、レコードセットがないと勘違いしてしまいそうで怖いです。

11
hiroton 2020/07/08 (水) 09:02:11 600c4@f966d >> 5

で、サブフォームのレコードセットは適当でも、これで書き換わるからいいと教えられました。

ACCESSを扱うなら非常に行儀が悪いですね。危惧している通りいろいろ問題が起きます。

まずはしっかりACCESSの作法を覚えるべきで、応用はその上に成り立つものでしょう


今は。帳票フォームの行が全部AさんやBさんになっているので、そこからまた頭を使って考えなければなりません(^^;

フォーム(サブフォーム)に必要とするすべてのデータを表示することができたら、フィルタープロパティを使ってデータの絞り込みができます。
サブフォームにはレコードソースを設定しておいて、親フォームのM_CMBの更新後イベントを次のようにします

Private Sub M_CMB_AfterUpdate()
    Dim strFilter
    If Not IsNull(Me!M_CMB) Then
        strFilter = "個人ID=" & Me!M_CMB
    End If
    Me!F_個人別.Form.Filter = strFilter
    Me!F_個人別.Form.FilterOn = True
End Sub
12
ろでます 2020/07/09 (木) 09:42:26 61da2@be317

おはようございます、ろでますです。
サブフォームの調整を考えて、きっちりすれば行けました!

というより、サブフォームのレコードソースをきっちりして、連結にすると、わざわざDlookup関数を用いないでも、きっちり連動してくれました。

その後、ご教授いただきましたフィルターをかけると思うように動作してくれました。

ありがとうございました。

13
hiroton 2020/07/10 (金) 09:19:55 b401e@f966d

うまく行ったようで何よりです。

そういえばですが、現状の内容だとメイン・サブにフォームを分ける必要がないですね。
「F_個人別」フォームのフォームヘッダーに「M_CMB」を設置して、フォームのフィルターをいじる部分は自分自身(のフォーム)でいいので

    Me.Filter = strFilter
    Me.FilterOn = True

で出来ます。


または、データ(テーブル)は正規化の観点から「T_個人」「T_障害」のように分かれていると思うので、
メインフォーム
既定のビュー:単票フォーム
レコードソース:T_個人

サブフォーム
既定のビュー:帳票フォーム
レコードソース:T_障害

サブフォームコントロール
リンク親フィールド:ID
リンク子フィールド:個人ID

のように、リンク関係を持ったメイン・サブフォームを作成すれば、メインフォーム側のレコード移動に伴って自動でサブフォーム側のレコードを変更することができます。

フォームの表示はたとえば


氏名:Aさん
住所:
電話番号:
<障害一覧>
○○障害
××障害
△△障害


のように作ることができ、共通するAさん(とその個人情報)は単票フォーム部分に1つだけ、Aさんに関連する障害情報は障害の情報だけを帳票フォーム部分に表示するといったようなことができ、Excelとは差別化されたACCESSらしい画面を作ることができます。

サブフォームの基本的な使い方でもあるので、一度調べてみることをオススメします。

なお、この場合の「M_CMB」はメインフォーム側に設置し、メインフォームのレコードを操作することになります。

14
ろでます 2020/07/10 (金) 15:30:13 61da2@be317

こんにちわ、ろでますです。
そんな方法があったんですか。
強にでも早速試そうとおもいます。

正直、サブフォームの作成って結構手間がかかってしまって、若干困っていたところです。😄

15
ろでます 2020/07/11 (土) 00:34:07 61da2@be317

こんばんわ、ろでますです。

先般はありがとうございました。
以降、色々触っているのですが、不可解な事象に遭遇しました。
色々設定を触りはしているのですが、あと一歩(?)のところでうまく動きません。

事象ですがテーブルが以下の様になっています
基礎情報_T - 個人別障害状況_T - 障害種別_T
           │
           - 等級_T
となっています。

この状態で以前と違い、フォームにレコードソースをセットして、コントロールソースも設定しています。
フォームには、基礎情報_より「個人ID」「名前」、障害種別_Tより「障害種別」、等級_Tより「等級」を表示させて、シンクさせています。(個人IDを変えれば、他も連動して変わります)

個人別障害状況_Tには、個人ID、障害種別ID、障等級IDが格納されて、これが各個人の実データテーブルになっています。

この状態で、フォームを起動して、例えば、個人ID1を参照します。
連動して、個人ID1の人の障害種別・等級が表示されます・・・といった具合にすべて正常に見えます。

ところが、参照後フォームを閉じた瞬間に、個人別障害状況_T内の「個人ID」の値が1レコード、必ず書き換わってしまいます。
何も命令を出していないのに書き換わってしまい、かなり困っています。

すいません、原因など分かればご教授いただけないでしょうか。
よろしくお願い申し上げます。

16
ろでます 2020/07/11 (土) 19:03:23 61da2@be317

すいません、自己解決しました。
フォーム・サブフォームとも参照元入力ソースのコンボボックスを非連結にして、教えていただいたフィルターをかけたところ、うまく動作してくれました。

なんで、コントロールソースを入れると値が書き換わってしまうのかは不明なままですが・・・

17

連結フォーム(レコードソースが設定してあるフォーム)、連結コントロール(コントロールソースか設定してあるコントロール)の場合は、テーブルのデータと直結してますので、フォームでの入力がそのままテーブルに反映されます。

ところが、参照後フォームを閉じた瞬間に、個人別障害状況_T内の「個人ID」の値が1レコード、必ず書き換わってしまいます。
何も命令を出していないのに書き換わってしまい、かなり困っています。

連結フォーム、連結コントロールでは当然の動作です。

今回のメインフォームの目的は何かを明確にしましょう。
サブフォームのデータを抽出する(フィルターをかける)だけが目的なら、非連結フォーム、非連結コントロールにすればいいでしょう。

逆にサブフォームの目的はなんでしょうか。「参照元入力ソースのコンボボックスを非連結にして」で本当に目的がかなってますか。