フォームの構成/操作等イメージできていないので、的外れかもしれません。
(親フォームのレコードソースがどうなっているかわからないので)
サブフォームの表示部分だけで良いですか。
(サブフォームから入力する場合は、入力チェック等々組み込む必要があります)
※ 下記は今回の動き(ご質問内容)についてのものではありません。
前のご質問をベースに記述したものになります。
今回の動きの原因はわかりません。(後述の余談部分が影響?)
仮定条件)
コンボボックス「cbx1」で、テーブル「T01」を参照し顧客を選択、
日付の検索用テキストボックスが「txt1」になっていたとします。
(親側の表示状態がわからないので、検索に必要と思われるものに限定)
帳票フォームとして表示しているサブフォームのレコードソースは、
テーブル「T03」そのままのものとします。(抽出条件なし)
サブフォームコントロール名を「FSUB」と仮定します。
また、リンク親/子フィールドは設定しません。
指定された検索条件で、サブフォームに Filter を設定します。
実行ボタン「btn1」で設定し、クリアボタン「btn2」で解除します。
親フォームへ記述:一例)
Private Sub SetFilter(sS As String)
With Me.FSUB.Form
If (Len(sS) = 0) Then
.FilterOn = False
.Filter = ""
Else
.Filter = sS
.FilterOn = True
End If
End With
End Sub
Private Sub btn1_Click()
Dim sS As String
Const sAndOr As String = " AND "
sS = ""
If (Not IsNull(Me.cbx1)) Then
sS = sS & sAndOr & "顧客ID = " & Me.cbx1
End If
If (Not IsNull(Me.txt1)) Then
sS = sS & sAndOr & "日付 = #" & Me.txt1 & "#"
End If
If (Len(sS) > 0) Then
sS = "売上ID IN (SELECT 売上ID FROM T02 WHERE " _
& Mid(sS, Len(sAndOr) + 1) & ")"
End If
Call SetFilter(sS)
End Sub
Private Sub btn2_Click()
Me.cbx1 = Null
Me.txt1 = Null
Call SetFilter("")
End Sub
※ 条件はテーブル「T02」に対して作成します。
その条件に合う「売上ID」で Filter を設定します。
( IN句 を使うのがミソ?)
※ 条件により1つだけを指定するのであれば、
sS = "売上ID = " & Me.売上ID
のように "=" にしてみたり・・・いろいろと変形できると思います。
※ 会社名の部分一致用にテキストボックス「txt2」を新設したとすると、
(コンボボックスの設定を優先してみると)
SetFilter 部分はそのまま流用し、「btn1」「btn2」部分を変更します。
Private Sub btn1_Click()
Dim sS As String
Const sAndOr As String = " AND "
sS = ""
If (Not IsNull(Me.cbx1)) Then
Me.txt2 = Null
sS = sS & sAndOr & "T02.顧客ID = " & Me.cbx1
ElseIf (Not IsNull(Me.txt2)) Then
sS = sS & sAndOr & "T01.会社名 Like '*" & Me.txt2 & "*'"
End If
If (Not IsNull(Me.txt1)) Then
sS = sS & sAndOr & "T02.日付 = #" & Me.txt1 & "#"
End If
If (Len(sS) > 0) Then
sS = "売上ID IN (SELECT 売上ID FROM T02 INNER JOIN T01 ON T02.顧客ID = T01.顧客ID WHERE " _
& Mid(sS, Len(sAndOr) + 1) & ")"
End If
Call SetFilter(sS)
End Sub
Private Sub btn2_Click()
Me.cbx1 = Null
Me.txt1 = Null
Me.txt2 = Null
Call SetFilter("")
End Sub
※ Filter を使いたくない場合には、
事前にサブフォームのレコードソースに指定するクエリに記述しておけば
それなりに動くと思います。
その場合は、必要に応じてサブフォームを Requery します。
余談)
LinkChildFields および LinkMasterFields プロパティについて、裏付けを取られたらと思います。
途中で設定を変えてもそこそこ動くようですが、ヘルプの中に気になる記述があります。
Access 2007 開発者用リファレンス > Access VBA リファレンス > SubForm オブジェクト > プロパティ
Access 開発者用リファレンス
SubForm."LinkChildFields/リンク子フィールド" プロパティ
の真ん中あたりに
-------------------
これらのプロパティは、デザイン ビュー (デザイン ビュー : データベース オブジェクト (テーブル、クエリ、フォーム、レポート、マクロ、およびデータ アクセス ページ) のデザインを表示するウィンドウ。デザイン ビューでは、新しいデータベース オブジェクトの作成と既存のデータベース オブジェクトの変更ができます。)、またはフォームやレポートの Open イベントの中で設定します。
-------------------
これに似た記述は、Access2000 のヘルプにもあります。
確認してみてください。
Open イベント以外での設定はできるし、エラーにもならない。
でも、このプロパティをいじったり、Filter も組み合わせたり・・・してみたり、
このような操作を繰り返していると動きがおかしくなってきたことがありました。
動的に変更するのではなく、固定して使われた方が良いような気がします。
#2です
> やはり、最後のところでおっしゃってる通り、
ということは、今回のご質問でも
クエリだけではなくリンク親/子フィールドも動的に変更していたという事でしょうか
(前回のご質問を参考にされた記述があったので、もしかしてと・・・・)
> 結局アクセス2000の仕様なのだと思い、・・・・
Access2007 のヘルプにも記述があるので、2000 限定ではないように思います。
この記述を仕様とみるのか・・・・でも、仕様なんですかね
ただ、そこそこ動くんですよね・・・
でも、変な動きをする時があるので、固定しておいた方が良さそう・・・と思います。
> 私のやり方が悪かったのだと思うのですが、検索ボタン(実行ボタン?)が反応しません。
という事ですが、#2で記述していなかった前提があります。
(VBA読むとわかるかな・・・で忘れてました)
テーブル「T01」「T02」にある「顧客ID」は数値型、
テーブル「T02」にある「日付」は日付/時刻型、
テーブル「T02」「T03」にある「売上ID」も数値型
(でも、これが違えばエラーは出たような)
#2は、
・リンク親/子フィールドは何も設定しない(で、固定して使う)
・それにより、サブフォームからの入力は処理が増える
・サブフォーム(T03の帳票表示フォーム)の Filter 指定で IN 句を使う
(時には "=" でも)
会社名の部分一致であれば、(例では「商事」)
SELECT 売上ID FROM T02 INNER JOIN T01 ON T02.顧客ID=T01.顧客ID WHERE T01.会社名 Like '*商事*'
とすると、会社名に "商事" が含まれる「T02」での 売上ID が求まるので
それを IN 句で指定した以下
"売上ID IN (・・・・前述の内容・・・・・・)"
の様に Filter 設定します。(#2の2つ目のパターン)
(IN の前にある「売上ID」は、サブフォームの「T03」でのものになります)
親フォームのレコードソースがテーブル「T02」をベースにしたものであったのなら、
サブフォームへの指定だけではなく、親の Filter へも共通に利用できると思います。
WEBを探すと、同じ様なテーブル/フォーム構成でのサンプルがあったように思います。
以下も参考程度で)
#2での動きを確認してみます(最低限の確認用です)
・新規 mdb を作成し、テーブル「T01」「T02」「T03」をインポートしておきます
・テーブル「T01」「T02」にある「顧客ID」は数値型、
テーブル「T02」にある「日付」は日付/時刻型、
テーブル「T02」「T03」にある「売上ID」も数値型を確認します
・テーブル「T03」を元にフォームウィザードで、表形式としてフォームを作成します
フォーム名を「FSUB」とし、閉じておきます
・新規フォームをデザインで作成していきます
・コンボボックス「cbx1」を配置します
値集合ソース:テーブル「T01」
列数:2
連結列:1
・テキストボックス「txt1」を配置し、書式を「日付(S)」
・テキストボックス「txt2」を配置します
・コマンドボタン、実行用「btn1」クリア用「btn2」を配置します
・作ってあったフォーム「FSUB」を上記配置した下側にドラッグ&ドロップします
・コマンドボタン「btn1」のプロパティで「クリック時」を「イベントプロシージャ」にし、
右横の「・・・」をクリックします
Private Sub btn1_Click()
End Sub
の表示になるので、以下と置き換えます。
Private Sub SetFilter(sS As String)
With Me.FSUB.Form
If (Len(sS) = 0) Then
.FilterOn = False
.Filter = ""
Else
.Filter = sS
.FilterOn = True
End If
End With
End Sub
Private Sub btn1_Click()
Dim sS As String
Const sAndOr As String = " AND "
sS = ""
If (Not IsNull(Me.cbx1)) Then
Me.txt2 = Null
sS = sS & sAndOr & "T02.顧客ID = " & Me.cbx1 ' ★
ElseIf (Not IsNull(Me.txt2)) Then
sS = sS & sAndOr & "T01.会社名 Like '*" & Me.txt2 & "*'"
End If
If (Not IsNull(Me.txt1)) Then
sS = sS & sAndOr & "T02.日付 = #" & Me.txt1 & "#"
End If
If (Len(sS) > 0) Then
sS = "売上ID IN (SELECT 売上ID FROM T02 INNER JOIN T01 ON T02.顧客ID = T01.顧客ID WHERE " _
& Mid(sS, Len(sAndOr) + 1) & ")"
End If
Call SetFilter(sS)
End Sub
Private Sub btn2_Click()
Me.cbx1 = Null
Me.txt1 = Null
Me.txt2 = Null
Call SetFilter("")
End Sub
※ 「顧客ID」がテキスト型であったのなら、★部分は
sS = sS & sAndOr & "T02.顧客ID = '" & Me.cbx1 & "'"
のように ' ' で値を囲みます
一通り完成したので、フォームビューで動きを確かめてみます。
コンボボックスで選んで、実行「btn1」を押してみる、とか
テキストボックス「txt2」に 「商事」と入れて、実行を押してみる・・・とか
この確認では、親フォームのレコードソースは設定していませんでしたが、
テーブル「T02」をベースにしたものが指定され、
「売上ID」名のテキストボックスがあったとした場合(連結状態とした場合)、
サブフォームから入力するには、サブフォーム内の「挿入前処理」で
Private Sub Form_BeforeInsert(Cancel As Integer)
If (IsNull(Me.Parent.売上ID)) Then
Cancel = True
Else
Me.売上ID = Me.Parent.売上ID
End If
End Sub
のように、
・親の「売上ID」が設定されていなかったら編集状態にしない
・テーブル「T03」登録に必要な「売上ID」を親から持ってくる
処理が最低限必要になると思います。
また、同一売上IDを登録できないようにするとか・・・・
(重複を許可する?とか・・・・)
※ リンク親/子フィールドに「売上ID」が設定されていた場合、
上記での親から「売上ID」を持ってくる処理は Access さんがやってくれてました。
リンク親/子フィールドを設定していないので、自分で処理する必要があります。
また、リンク親/子フィールドに「売上ID」が設定されていたら、
サブフォームへ複数の「売上ID」を表示することはできません。
(これに対して複数表示したい・・・が、前回ご質問の趣旨だったのかと思います)
なお、テーブル「T03」に日付がないもので確認していました。
(Filter を作成する時点でテーブル「T03」は使っていないので)
今回のご質問への回答になっていたでしょうか・・・・
前回のものについてばかりで・・・
失礼しました。
お礼
お返事が大変遅くなってしまってすみません。 詳しい説明ありがとうございます。 30246kikuさんの説明に、従いやってみたのですがやはりできません…。 私のやり方が悪かったのだと思うのですが、検索ボタン(実行ボタン?)が反応しません。 やはり、最後のところでおっしゃってる通り、 結局アクセス2000の仕様なのだと思い、あっさり諦め、固定して使おうかと思います…。 わかりにくい状況の中、丁寧に説明してくださりありがとうございました。