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

サブフォームのフィールドを対象にメインフォームにフィルタをかける

メイン/サブフォームで、キーフィールドでリンクフィールドの設定をしてあります。キーフィールド以外のフィールドでサブフォームにフィルタをかけました。それによりサブフォームにはレコードが 0件になるメインのレコードが存在します。このメインのレコードを表示しないようにフィルタをかけたいのですが、抽出対象フィールドはサブフォームにしか存在しません。どうしたらいいでしょう。

というような質問がMougでありました。

他にも、メイン/サブフォーム形式でサブフォームにしかないフィールドでメインフォームにフィルタをかけたい場面はいろいろあると思います。

例えば、メインは社員マスタ、サブが その社員の資格一覧 になっていて、ある資格を持っている社員のみにフィルタをかけたいとか、いろいろありそうです。

難易度:

仕様

下記のようなテーブルがあるとします。

テーブル名 T_社員
フィールド名 社員CD, 氏名 ・・・

テーブル名 T_実績
フィールド名 実績ID, 社員CD, 得意先CD, ・・・

メインフォーム が T_社員 と、サブフォームが T_実績 と連結、リンク親/子フィールドは、社員CD。

メインフォームにコンボボックスが cb得意先CD があり、得意先CD を選択できるようになっていて、そこで選択した得意先が実績にある社員のみメインフォームに表示させるようにフィルタをかけたい。

コーディング

メインフォームには、得意先CD はないので直接フィルタはかけれません。しかし、Filterプロパティのヘルプをみると「Filter プロパティの設定値は、WHERE 句から WHERE を省いた文字列式です」と記述してあります。ということは、WHERE句に記述できるSQLなら、設定可能ということになります。

さらに、サブクエリを含む条件式も設定可能ではないかと期待がふくらみます。実際、実験してみると可能なのです。

得意先CD は数値型の前提です。テキスト型の場合は、’(シングルクォーテーション) で囲んでください。

Filterプロパティの条件式にサブクエリも使えるというテクニックを覚えておくと、他にもいろいろ応用がききそうです。

拍手する

15 Comments

迷子 says..."教えてください。"

いつもお世話になっております。
貴サイトを参考に四苦八苦しながらも、少しずつ前進したり、後退したりの毎日です。
教えていただきたいことがあります。
上記の
Me.Filter = "社員CD In (SELECT 社員CD FROM T_実績 WHERE 得意先CD = " & Me.cb得意先CD & ")"
というコードの社員CD社員CDは何を入れたらよいでしょうか?
リレーションシップの項目になるのでしょうか?

2013.07.22 17:55 | URL | #Ib5UFj1M [edit]
hatena says..."リンクフィールド"

「リレーションシップの項目」というのが、2つのテーブルがリレーションシップで結合されているフィールドという意味でしたら、そうです。

サブフォームコントロールの、リンク子フィールド、リンク親フィールドに設定してあるフィールド名と同じものです。

2013.07.22 18:02 | URL | #5uE6dEgY [edit]
迷子 says..."お返事ありがとうございます。"

早速のお返事、ありがとうございます。
確認したところ、リンク子フィールド、リンク親フィールドに設定してあるフィールド名になっていました。他のところに原因があるようです。

厚かましいお願いではありますが、当方の情報を一度見ていただけないでしょうか。
※色が同じもので関連付けしています。
【メインフォーム】
レコード№(リンク親フィールド)
製品名

【サブフォーム】(2つのテーブルからなります)
■テーブル①
レコード№(リンク子フィールド)
原料ID
■テーブル②
原料ID
原料名(フィルター条件のフィールド)

上記から、次のようなコードにしましたが、うまくいきませんでした。
Me.Filter = "レコード№ In (SELECT レコード№ FROM テーブル② WHERE 原料名 = " & Me.cb原料名CD & ")"

お忙しいところ、まことに申し訳ございませんが、
ご教示の程よろしくお願い申し上げます。

2013.07.23 10:37 | URL | #Ib5UFj1M [edit]
hatena says..."サブフォームのレコードソース?"

サブフォームのレコードソースには、クエリが設定してありますか、それともSQLが設定してありますか。

クエリなら、

Me.Filter = "レコード№ In (SELECT レコード№ FROM クエリ名 WHERE 原料名 = " & Me.cb原料名CD & ")"

SQLなら、

Me.Filter = "レコード№ In (SELECT レコード№ FROM (*SQL*) WHERE 原料名 = " & Me.cb原料名CD & ")"

*SQL* の部分にレコードソースのSQL文を挿入。
ただし、最後の ; は削除する。

2013.07.23 10:51 | URL | #5uE6dEgY [edit]
迷子 says..."本当にありがとうございます。"

早急にご回答いただき、誠にありがとうございます。
調べても調べてもできなかったことが、できました。
(もしかしたら、初歩的過ぎて参考先がなかったのでしょうか…。)
本当にありがとうございました。
貴サイトを参考に使いやすいDBに改善していきたいと思います。
今後ともよろしくお願いいたします。

2013.07.23 15:23 | URL | #Ib5UFj1M [edit]
名無し says...""

ホームページを見て,なんとかがんばって サブフォームのデータから検索しようと しているのですが,うまくいかないので, 何が悪いのか教えてもらえないでしょう か。 個人の住所や名前やtelの値を持つメイ ンのT世帯台帳テーブルがあり,証書番号 というフィールドでリレーションシップで [T交付返付]がつながっていて,サブフ ォームで更新申請等の申請内容や,届出日 の日付が表示されます。(児童手当の申 請に近いのでそれをイメージしてみてくだ さい。) 8月に一斉に更新申請の提出があるので ,更新の届出日や届出の内容を入力しま す。その後,チェック等のために特定の日 付で申請のあった人を抽出できるように できればと思っています。以下のように作 ってみましたが,どうもうまくいきませ ん。コンボボックスでなくて,テキストボ ックス(証書の交付返付検索)にフリー ワードで検索するようにしているのがいけ ないのでしょうか。

Private Sub 証書の交付返付_Click()

If IsNull(Me.証書の交付返付検索) Then Me.Filter = "" Me.FilterOn = False Me![T 交付返付のサブフォーム].Form.Fi lter = "" Me![T 交付返付のサブフォーム].Form.Fi lterOn = False Else

Me.Filter = "証書番号 In (SELECT 証書番 号 FROM (SELECT [T交付返付].証 書番号, [T交付返付].内容, [T交付返付].届 出日 FROM T交付返付) WHERE 届出 日=" & Me.証書の交付返付検索 & ")"

Me.FilterOn = True Me![T 交付返付のサブフォーム].Form.Fi lter = "届出日=" & Me.証書の交付 返付検索 Me![T 交付返付のサブフォーム].Form.Fi lterOn = True End If End Sub

2014.08.22 14:54 | URL | #- [edit]
hatena says..."re: サブフォームのデータから検索"

現状のテーブル名、フィールド名、フィールドのデータ型、主キー設定を提示してください。

2014.08.22 16:13 | URL | #5uE6dEgY [edit]
名無し says...""

失礼しました。 ①テーブル名「T世帯台帳」の中に 母カナ(主キー)(テキスト型) ,証書番号 (数値型),母生年月日(日付/時刻型),ID(主キー)(オートナン バー型)等の フィールドがあります。 ②テーブル名「T交付返付」の中に
ID(主キー)(オートナンバー型) ,証書番号 (数値型),届出日(日付/時刻型),内容(テキスト型)のフィール ドがありま す。

2014.08.25 10:25 | URL | #- [edit]
hatena says...""

T世帯台帳
 母カナ(テキスト型)
 証書番号 (数値型)
 母生年月日(日付/時刻型)
 ID(主キー)(オートナン バー型)

交付返付
 ID(主キー)(オートナンバー型)
 証書番号 (数値型)
 届出日(日付/時刻型)
 内容(テキスト型)

ということですね。
日付/時刻型の値は、# で囲む必要があります。
下記のコードでどうでしょうか。

Private Sub 証書の交付返付_Click()
  If IsNull(Me.証書の交付返付検索) Then
    Me.Filter = ""
    Me.FilterOn = False
    Me![T 交付返付のサブフォーム].Form.Filter = ""
    Me![T 交付返付のサブフォーム].Form.FilterOn = False
  Else
    Me.Filter = "証書番号 In (SELECT 証書番号 FROM T交付返付 WHERE 届出日=#" & Me.証書の交付返付検索 & "#)"
    Me.FilterOn = True
    Me![T 交付返付のサブフォーム].Form.Filter = "届出日=#" & Me.証書の交付返付検索 & "#"
    Me![T 交付返付のサブフォーム].Form.FilterOn = True
  End If
End Sub

2014.08.25 17:43 | URL | #5uE6dEgY [edit]
名無し says...""

ありがとうございました。サブフォームのレコードソースにSQLが設定してあるのでそれを入力すればできました。ただ、サブフォームに表示されるのが、抽出条件に指定したものだけになってしまうので、抽出条件の値を持つ人を抽出し、なおかつその人が持つ抽出条件以外のデータも表示できるようにしたいのですが、可能でしょうか?

2014.08.26 15:16 | URL | #- [edit]
hatena says..."re:"

> ただ、サブフォームに表示されるのが、抽出条件に指定したものだけになってしまうので、抽出条件の値を持つ人を抽出し、なおかつその人が持つ抽出条件以外のデータも表示できるようにしたいのですが、可能でしょうか?

サブフォームにフィルタをかけなければいいでしょう。

2014.08.26 16:28 | URL | #5uE6dEgY [edit]
名無し says...""

早速の回答ありがとうございました。サブフォームのフィルターのところを削除したらうまくいきました。意外と単純だったんですね。VBAの基礎が分かってないので、これから勉強します。

2014.08.26 16:41 | URL | #- [edit]
名無し says..."教えてください"

ACCESSを始めて間もない未熟者です。
ご教授願います。

以下の2つのテーブルの説明

Tインシデント
  事例ID(主キー)(オートナンバー型)
  受付日 (日付/時刻型)
  受付者 (テキスト型)
  内容 (メモ型)
  完了チェック (Yes/No型)

T既読チェック
  事例ID(主キー)
  担当者A (日付/時刻型)
  担当者B (日付/時刻型)
  担当者C (日付/時刻型)
  担当者D (日付/時刻型)

事例IDをリレーションシップで繋げています。
Tインシデントフォームから既読フォームを開き、レコード(事例ID)ごとに
既読日を担当者別に入力するようになっています。

Tインシデントフォームにコンボボックスで「担当者」を選択する枠を設置し
「担当者別未読検索ボタン」を実行すると、
担当者の既読日が入力されていない(空白)の事例IDのTインシデントの内容(レコード)を表示したい。
併せて、①完了チェックがYesのものは表示しない。②完了チェックがYesのものも表示する。


この場合どのようにコーディングすれば良いでしょうか。
どうぞ宜しくお願い致します。

2014.11.21 22:40 | URL | #- [edit]
hatena says..."Re: 教えてください"

> T既読チェック
>   事例ID(主キー)
>   担当者A (日付/時刻型)
>   担当者B (日付/時刻型)
>   担当者C (日付/時刻型)
>   担当者D (日付/時刻型)

回答の前に、
このテーブル設計は、データペースとして間違っていますね。

これだと、もし、担当者が増えたりした場合、どうしますか。
テーブルをデザインビューで開いて、フィールドを増やすしかないですね。
そうなると、関連するそれ以外の部分、クエリやフォーム、レポート、コードなどすべて変更する必要があります。

これは面倒ですし、バグや不具合のもとになります。

このテーブルは、下記のように設計すべきです。

T担当者マスター
 担当者ID (主キー)
 氏名
 性別
 入社日
 ・・・
 ・・・

T既読チェック
 事例ID  (主キー)
 担当者ID (主キー)
 既読日 日付/時刻型

2014.11.22 17:44 | URL | #- [edit]
名無し says..."re:Re: 教えてください"

ご指摘ありがとうございます。
おっしゃる通りで都度テーブルをデザインビューで開いて、
フィールドを増やしていました。

Tインシデントフォームで事例IDごとのレコードに
  ・受付日
  ・受付者
  ・内容
  ・完了チェック
の項目が表示され、既読フォームを別に開いた状態で自分の名前の枠に既読日を入力(コマンドボタン)するようになっており、また、メンバー全員の既読状況も確認できるようにしていました。単純に既読テーブルを別フォームで開くのでこのテーブル設計にしてしまいました。最初はTインシデントフォームに既読欄を設け、同じテーブルで設計していて、フィルターが掛けやすかったのですが、担当者人数が増えた時に、既読欄のスペースが足りなくなることを想定し、別に開くようにし、Tインシデントフォームのレコードを選択するごとに既読フォームも事例IDをキーに表示させることだけに囚われていました。その結果がテーブルを別にしフィルターがうまく機能させることができずご相談した次第です。データベースのあるべき基本的な考え方や構成のセンスが足りないのだと痛感しました。

2014.11.22 23:08 | URL | #- [edit]

Leave a reply






Trackbacks

trackback URL
http://hatenachips.blog34.fc2.com/tb.php/235-3b9e8b9d
該当の記事は見つかりませんでした。