フォーム上で「客先名」と「納入日」を指定して、その指定したものだけを表示したいと思い、下記の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
以上、よろしくおねがいします。
#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関数は(エクセルでも使えますし)、かなり便利に使える関数の一つです。
覚えておいて損は無いですよ。
以上、参考までに。
質問者
お礼
回答ありがとうございます。
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
>プロシージャの外では無効です
ということは、ご質問のコード自体に問題があるのではなくて、プロシージャの外に何かゴミ?がありませんか?
(Sub ~ End Subに囲まれた部分以外に何か不必要な記述がありませんか?)
質問者
お礼
回答ありがとうございます。
よく見てみたのですが、特に不必要な記述というものが見当たりません。
また、「抽出」のコマンドボタンをクリックしたときは「Private Sub cmdFilter_Click()」の部分が、「抽出解除」のコマンドボタンをクリックしたときは「Private Sub cmdFilterOff_Click()」の部分が黄色くなります。
これはなにか関係あるでしょうか?
お礼
回答ありがとうございます。 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