こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

複数条件で抽出後結果をフォームに表示する方法

フォーム上で「客先名」と「納入日」を指定して、その指定したものだけを表示したいと思い、下記のURL参考にさせていただき、自分で必要と思われる箇所を変更してみたのですが、「コンパイルエラー:プロシージャの外では無効です」とでて、うまくいきません。

私の知識不足でどこがどう悪いのかわからないので、どうかお助けください。

参考URL:http://hatenachips.blog34.fc2.com/blog-entry-129.html

※「納入日」はたとえば「2013/05/01~2013/05/20」というふうに範囲指定したいです。

※作ったテキストボックス名は txt客先名、min年月日、max年月日 で、
抽出したいフィールド名は「客先名」と「納入日」です。

↓URLを参考に自分なりに書き換えてみたコード

Private Sub cmdFilter_Click()
Dim strFilter As String, strExp As String, aryOpe As Variant

If Not IsDate(Me.min年月日) Then
MsgBox "日付ではありません。"
Me.min年月日.SetFocus
Exit Sub
End If
If Not IsDate(Me.max年月日) Then
MsgBox "日付ではありません。"
Me.max年月日.SetFocus
Exit Sub
End If

If Not IsNull(Me.txt客先名) Then
strFilter = strFilter & " AND 客先名 Like '*" & Me.txt客先名 & "*'"
End If

If Not IsNull(Me.min年月日) Then
strFilter = strFilter & " AND 納入日 >= #" & Nz(Me.min年月日) & "#"
End If

If Not IsNull(Me.max年月日) Then
strFilter = strFilter & " AND 納入日 <= #" & Nz(Me.max年月日) & "#"
End If

Me.Filter = Mid(strFilter, 3)
If strFilter = "" Then
Me.FilterOn = False
Else
Me.FilterOn = True
End If
End Sub

Private Sub cmdFilterOff_Click()
Me.Filter = ""
Me.FilterOn = False
Me.txt客先名 = Null
Me.min年月日 = Null
Me.max年月日 = Null
End Sub


以上、よろしくおねがいします。

投稿日時 - 2013-07-04 15:37:44

QNo.8162065

困ってます

質問者が選んだベストアンサー

#3さんが模範解答をくださっていますので、私からは蛇足的に解説。
まったくの蛇足ですから、回答としての役には立てないものと思われます。

フィルタ条件(strFilter)に文字列を代入していく行からです。
まず・・[txt客先名]が空白じゃなかったら、(この時点では変数は空白ですから)
変数strFilterには" AND 客先名 Like '*" & Me.txt客先名 & "*'"と代入されますね。
以下、二つの項目も同様ですね。
ここが理解できていないと先に進めないので、しっかりコードを読み解きましょう。

で、これ(strFilter)をフィルタに渡してやるのですが、
この時の変数の中身は" AND 客先名 Like '*" & Me.txt客先名 & "*' AND (以下省略)" です。
フィルタ条件の冒頭に「AND」があるとフィルタがうまく機能しないので、
これを省くために「MID関数」を使います。
  MID(文字列,開始位置[,文字数])
と言う形で「指定した「文字列」の「開始文字位置」から後ろ(何文字分)を返す」関数です。
(文字数を省略すると、開始位置以降全てを返してきますので、今回は省略可能です。)
コレを使うことによって、strFilterの中身を
"客先名 Like '*" & Me.txt客先名 & "*' AND (以下省略)"
と言う風に「フィルタが認識してくれる条件」に書き換えてやっているわけです。


おそらく、勘違いなさっているのだと思います。
ご提示のコード中の
  Me.Filter = Mid(strFilter, 3)
の「3」は、フィルタ条件が「3個ありますよ」の「3」ではなく、
「3文字目から後ろを引っ張りなさい」の「3」なのですね。
なので、フィルタ条件が"ND 客先名 Like '*" & Me.txt客先名 & "*' AND (以下省略)"
と言う、アクセスにとってわからない文字列を指定してしまっているので、
エラーが返ってきてしまった・・・ということですね。
(リンク先の元コードの条件項目は「6個」でしたもんね。
 書き換えたくなる気持ちは何となくわかります。)



MID関数は(エクセルでも使えますし)、かなり便利に使える関数の一つです。
覚えておいて損は無いですよ。



以上、参考までに。

投稿日時 - 2013-07-05 02:02:17

お礼

回答ありがとうございます。

m3_maki様の回答の補足説明、大変助かりました。
ご指摘のとおり、「3」はフィルタ条件の数だと勝手に思っていました。mid関数の意味がやっとわかりました。
VBAと関数をきちんと基礎から勉強したいと思います。

ちなみに、「客先名」も客先コードを設定したルックアップを使って入力し、客先の名前を表示していたことにいまさらながら気づき、というか理解し、コードを下記のように変えてみたらおかげさまでやりたいことができるようになりました。

本当に助かりました。
ありがとうございました。

↓書き換えたコード

Private Sub cmdFilter_Click()
Dim strFilter As String, strExp As String, aryOpe As Variant

If Not IsDate(Me.min年月日) Then
MsgBox "日付ではありません。"
Me.min年月日.SetFocus
Exit Sub
End If
If Not IsDate(Me.max年月日) Then
MsgBox "日付ではありません。"
Me.max年月日.SetFocus
Exit Sub
End If

If Not IsNull(Me.txt客先コード) Then
strFilter = " AND " & BuildCriteria("客先名", _
dbLong, Me.txt客先コード)
End If

If Not IsNull(Me.min年月日) Then
strFilter = strFilter & " AND 納入日 >= #" & Nz(Me.min年月日) & "#"
End If

If Not IsNull(Me.max年月日) Then
strFilter = strFilter & " AND 納入日 <= #" & Nz(Me.max年月日) & "#"
End If



Me.Filter = Mid(strFilter, 6)
If strFilter = "" Then
Me.FilterOn = False
Else
Me.FilterOn = True
End If
End Sub

Private Sub cmdFilterOff_Click()
Me.Filter = ""
Me.FilterOn = False
Me.txt客先コード = Null
Me.min年月日 = Null
Me.max年月日 = Null
End Sub

投稿日時 - 2013-07-05 11:21:52

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.3

> 今度は「実行時エラー'2448' このオブジェクトに値を代入することができません」とメッセージが出て、Me.Filter = Mid(strFilter, 3)の行が黄色くなってしまいました。

Me.Filter = Mid(strFilter, 6)

ですね。

投稿日時 - 2013-07-04 21:26:21

お礼

回答ありがとうございます。

Me.Filter = Mid(strFilter, 6)
に書き換え、なおかつ「客先名」はルックアップでコード選択して表示していたことにいまさらながら気づき、コード入力で検索することにしたら、条件を指定した結果を表示することができました。

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

投稿日時 - 2013-07-05 11:10:47

ANo.2

14行目あたりに、

  strFilter = strFilter & " AND 客先名 Like '*" & Me.txt客先名 & "*'"

という行がありますが、これを、

  strFilter = "AND 客先名 Like '*" & Me.txt客先名 & "*'"

としてみたらどうでしょうか?(全然自信はありませんが・・・)

投稿日時 - 2013-07-04 18:58:41

お礼

再びありがとうございます。
ご指摘のように変えてみましたが、残念ながら同じ結果でした…

ちなみに、このフォームは選択クエリから作成しているのですが、テーブルから作成したフォームではないということが影響したりしているのでしょうか?

聞いてばかりですみません。本当に自分の知識の無さが情けないです。
VBAがなんたるかを勉強するために現在参考書を注文している最中です。

投稿日時 - 2013-07-04 19:26:08

ANo.1

>プロシージャの外では無効です

ということは、ご質問のコード自体に問題があるのではなくて、プロシージャの外に何かゴミ?がありませんか?
(Sub ~ End Subに囲まれた部分以外に何か不必要な記述がありませんか?)

投稿日時 - 2013-07-04 16:15:13

補足

すみません。いろいろ見てみたらほかのモジュールに不要な記述がありました。
なので、コンパイルエラーはでなくなりました。
ありがとうございます!

ですが、次なる問題が出てきまして、今度は「実行時エラー'2448' このオブジェクトに値を代入することができません」とメッセージが出て、Me.Filter = Mid(strFilter, 3)の行が黄色くなってしまいました。

投稿日時 - 2013-07-04 20:05:25

お礼

回答ありがとうございます。
よく見てみたのですが、特に不必要な記述というものが見当たりません。

また、「抽出」のコマンドボタンをクリックしたときは「Private Sub cmdFilter_Click()」の部分が、「抽出解除」のコマンドボタンをクリックしたときは「Private Sub cmdFilterOff_Click()」の部分が黄色くなります。

これはなにか関係あるでしょうか?

投稿日時 - 2013-07-04 16:59:08

あなたにオススメの質問