Access (VBA)

Access VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : 指定なし)
複数条件にあう検索フォーム
投稿日時: 20/04/09 19:37:23
投稿者: さー

お世話になります。
 
データベースから複数条件にあうデータを抽出するフォームを作成したいのですが、うまく抽出できずに
困っています。
間違っている個所やこうしたら良いなどアドバイスいただけますでしょうか?
  
データベース(テーブル)
No   名前         好きな色    好きな果物   メッセージ          
1    山田 太郎     赤       りんご     サイクリングと料理が趣味です。
2    山田 花子     白       りんご     週末にサイクリングに行きました。
3    田中 一郎     青       バナナ     毎日サイクリング、週末に料理をします。 
 ・
 ・
 ・
  
抽出条件(フォーム)
 検索条件1:「txb名前」というテキストボックスにフリーワード(例;山田)を入力する
 検索条件2:「txb好きな色」というテキストボックスにフリーワード(例:赤)を入力する
 検索条件3:「cmb好きな果物」というコンボボックス▼から項目(例:りんご)を選択する
 検索条件4:「txbメッセージ1」というテキストボックスにフリーワード(例:サイクリング)を入力する
  and or:「flmオプション」というオプショングループでand orのいずれかを●で選択する
 検索条件5:「txbメッセージ2」というテキストボックスにフリーワード(例:料理)を入力する
<やりたいこと>
検索条件を1つ以上入力すると条件にあうデータが抽出できる(検索結果フォームを開き、条件にあう
結果のみが表示される)ようにしたいです。
検索条件1〜3はすべてandで、検索条件4・5はandとorをオプショングループで選べるようにしたいです。
  
<問題点>
  txbメッセージ1に「サイクリング」、txbメッセージ2に「料理」を入力しand検索にした場合
  No.1とNo.3が表示されます。→これはOKです。
  
  cmb好きな果物からりんごを選ぶとNo.1とNo.2が表示されます。→これもOKです。
  
  cmb好きな果物から「りんご」を選び、txbメッセージ1に「サイクリング」、txbメッセージ2に
  「料理」を入力しオプショングループでandを選択した場合、No1のみを表示させたいのに、No.1と
  No.3が表示されてしまいます。
  (cmb好きな果物をtxb好きな色に変更しても同様の結果となります。)
どこが間違っているのか、おわかりになり方がいましたら、教えていただけますでしょうか?
よろしくお願いいたします。
 
  
以下、イベントプロシージャです。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
Public Sub ClearObj()
    Dim myObj As Object
     
    For Each myObj In Me
        If myObj.Name Like "txb*" _
        Then
            myObj.Value = Null
        End If
  
        If myObj.Name Like "cmb*" _
        Then
            myObj.Value = Null
        End If
  
        If myObj.Name Like "flm*" _
        Then
            myObj.Value = 1
        End If
  
    Next
     
End Sub
ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
  
Private Sub 検索開始_Click()
  Dim myStr As String '条件
   
  myStr = ""
  If Not IsNull(txb名前) Then
     myStr = myStr & " And 名前 like '*" & txb名前.Value & "*'"
  End If
   
   If Not IsNull(txb好きな色) Then
     myStr = myStr & " And 好きな色 like '*" & txb好きな色.Value & "*'"
  End If
   
    If Not IsNull(cmb好きな果物) Then
     myStr = myStr & " And 好きな果物 like '*" & cmb好きな果物.Value & "*'"
  End If
 
Select Case flmオプション
  Case 1
  If Not IsNull(txbメッセージ1) Then
     myStr = myStr & " And メッセージ like '*" & txbメッセージ1.Value & "*'"
  End If
    If Not IsNull(txbメッセージ2) Then
     myStr = myStr & " And メッセージ like '*" & txbメッセージ2.Value & "*'"
  End If
   
  Case 2
  If Not IsNull(txbメッセージ1) Then
     myStr = myStr & " And メッセージ like '*" & txbメッセージ1.Value & "*'"
  End If
    If Not IsNull(txbメッセージ2) Then
     myStr = myStr & " Or メッセージ like '*" & txbメッセージ2.Value & "*'"
  End If
End Select
   
  If myStr = "" Then
     MsgBox "いずれか1項目以上を必ず入力してください", vbCritical, "エラー"
  Else
     DoCmd.OpenForm "検索結果", , , Mid(myStr, 6)
  End If
   
End Sub

回答
投稿日時: 20/04/10 09:58:44
投稿者: WinArrow
投稿者のウェブサイトに移動

And と Or を組み合わせる場合
「(」「)」で囲む必要があります。
 

男は10才以上
女は15才以上
というような場合
 
(姓='男' AND 年齢>=10) OR 姓='女' AND 年齢>=15)
 
のような形を参考にして
SQL文を組み立ててみましょう

回答
投稿日時: 20/04/10 23:51:40
投稿者: MMYS

文字列をパラメータとして
DoCmd.OpenForm に与える。
はご存知だと思います。
 
そういう時は、目的とする動作の文字列を直接与えて、動作確認です。
この時点で、生成すべき文字列を確実に確認するのです。
 

Private Sub 検索開始_Click()
  Dim myStr As String

  myStr="名前 like '*山田*' And 好きな色 like '*赤*' And 好きな果物 like '*りんご*'"
'myStr="(名前 like '*山田*' And 好きな色 like '*赤*' And 好きな果物 like '*りん*')"_
 & " Or (メッセージ like '*サイクリング*' Or メッセージ like '*料理*')"
    
  Debug.Print myStr
  DoCmd.OpenForm "検索結果", , , Mid(myStr, 6)
End Sub

このコードの文字列を直接書き換えて、生成すべき文字列を把握します。
コメントアウト機能を使って、テストを繰り返します。
これで生成すべき文字列の固定値と変更値が、わかったと思います。
 
あとはその文字列をいかに生成するコードの作成です。
 
  Dim myStr As String '条件
  Dim myA As String   '条件1〜3
  Dim myB As String   '条件4〜5
  Dim myAndOr As String

  '条件1〜3
  myStr = ""
  If Not IsNull(txb名前) Then
     myStr = myStr & " And 名前 like '*" & txb名前.Value & "*'"
  End If
  If Not IsNull(txb好きな色) Then
     myStr = myStr & " And 好きな色 like '*" & txb好きな色.Value & "*'"
  End If
  If Not IsNull(cmb好きな果物) Then
     myStr = myStr & " And 好きな果物 like '*" & cmb好きな果物.Value & "*'"
  End If
  myA = Mid(myStr, 6)
  
 '条件4〜5
  myStr = ""
  myAndOr = " AND  "    'デフォルトはAND
  If optオア.Value Then 'OR の時
    myAndOr = " OR  "
  End If
  If Not IsNull(txbメッセージ1) Then
     myStr = myStr & myAndOr & "メッセージ like '*" & txbメッセージ1.Value & "*'"
  End If
    If Not IsNull(txbメッセージ2) Then
     myStr = myStr & myAndOr & "メッセージ like '*" & txbメッセージ2.Value & "*'"
  End If
  myB = Mid(myStr, 6)

  myStr = "(" & myA & ")" & myAndOr & "(" & myB & ")"
  Debug.Print myStr

上記はアルゴリズムの例を示しただけです。未テスト。
実用では入力チェックが不十分。
 
さー さんの引用:

Select Case flmオプション
  Case 1

上記は、どのような意図ですか。
・フレーム
・オプションボタン
の動作をどのように理解してますか。
 
ほかにも、動作には問題ないけど、疑問に思う箇所はあります。
 
 

回答
投稿日時: 20/04/12 19:42:44
投稿者: Moko

「Or条件」の場合はうまくいかない、というのは置いといて、
最後に入力した「txbメッセージ2」からフォーカスが移動していないように見えます。
 
「検索開始」コントロールはコマンドボタンですか?
 
「txbメッセージ2」入力後、いったん「txbメッセージ1」に移動してから
「検索開始」をクリックしたらどうなりますか?

投稿日時: 20/04/14 19:37:30
投稿者: さー

WinArrow様
MMYS様
Moko様
 
お世話になります。回答いただきましてありがとうございました。
またご連絡が遅くなりまして申し訳ございません。
いろいろと試してみたのですが、うまくいかず、追加で質問をさせてください。
 

引用:

Select Case flmオプション Case 1
上記は、どのような意図ですか。

オプションボタンでand と or を選択できるようにしたいので、
andを選んだ場合をCase1、orを選んだ場合をCase2としました。
"flamオプション"はオプションボタン2個(andとor)を囲んである枠の名前です。
やりたいのは下記のイメージです。
 
オプションボタンでandを選択した場合(←Case1としたい)
 検索条件1:「txb名前」というテキストボックスにフリーワード(例;山田)を入力する
  and
 検索条件2:「txb好きな色」というテキストボックスにフリーワード(例:赤)を入力する
  and
 検索条件3:「cmb好きな果物」というコンボボックス▼から項目(例:りんご)を選択する
  and
 検索条件4:「txbメッセージ1」というテキストボックスにフリーワード(例:サイクリング)を入力する
  and (←ここだけオプションボタンでand or選択可能)
 検索条件5:「txbメッセージ2」というテキストボックスにフリーワード(例:料理)を入力する
 ※ただし、検索条件1〜5のうち、最低1つ入力すればよいとしたいです。
 
オプションボタンでandを選択した場合(←Case2としたい)
 検索条件1:「txb名前」というテキストボックスにフリーワード(例;山田)を入力する
  and
 検索条件2:「txb好きな色」というテキストボックスにフリーワード(例:赤)を入力する
  and
 検索条件3:「cmb好きな果物」というコンボボックス▼から項目(例:りんご)を選択する
  and
 検索条件4:「txbメッセージ1」というテキストボックスにフリーワード(例:サイクリング)を入力する
  or (←ここだけオプションボタンでand or選択可能)
 検索条件5:「txbメッセージ2」というテキストボックスにフリーワード(例:料理)を入力する
 ※ただし、検索条件1〜5のうち、最低1つ入力すればよいとしたいです。
 
 
引用:
And と Or を組み合わせる場合 「(」「)」で囲む必要があります。

このようにしてみたのですが、エラーになってしまいます。そもそも1文の中に2個の条件を
入力すること自体が間違いなのでしょうか?
  If Not IsNull(txbメッセージ2) Then
     myStr = myStr & " And( "メッセージ like '*" & txbメッセージ1.Value & "*'" )Or( " メッセージ like '*" & txbメッセージ2.Value & "*'" )
  End If
 
 
引用:
「検索開始」コントロールはコマンドボタンですか?

はい。「検索開始」コントロールはコマンドボタンです。
 
引用:
「txbメッセージ2」入力後、いったん「txbメッセージ1」に移動してから
「検索開始」をクリックしたらどうなりますか?

移動せずにクリックした場合と同様の検索結果でした。
and orを選択した場合に検索結果が異なってしまいます。cmb好きな果物にりんごを
入力しているのに、りんご以外も抽出されてしまいます。
 
長文の質問となり申し訳ございませんが、よろしくお願いいたします。
 
 

回答
投稿日時: 20/04/15 20:16:49
投稿者: MMYS

すでにレス済みですが
複雑なことをする前に
単純になコードで
テストして下さい。
そして、目的の結果になることを確認。
 

Private Sub 検索開始_Click()
  Dim myStr As String
  myStr = "(名前 like '*山田*' And 好きな色 like '*赤*' And 好きな果物 like '*りん*') Or (メッセージ like '*週末*')"
  Debug.Print myStr
  DoCmd.OpenForm "検索結果", , , Mid(myStr, 6)
End Sub

正常動作を確認したら、可変に変更していきます。
 
Private Sub 検索開始_Click()
  Dim myStr As String
  Dim t名前 As String  
  t名前 = txb名前.Value  
  myStr = "(名前 like '*" & t名前 & "*' And 好きな色 like '*赤*' And 好きな果物 like '*りん*') Or (メッセージ like '*週末*')"
  Debug.Print myStr
  DoCmd.OpenForm "検索結果", , , Mid(myStr, 6)
End Sub

 

投稿日時: 20/04/17 20:10:35
投稿者: さー

MMYS様
 
お世話になります。ご回答いただき、ありがとうございます。
無事にうまくいきました。完全解決です!
 

引用:
Private Sub 検索開始_Click()
  Dim myStr As String
  myStr = "(名前 like '*山田*' And 好きな色 like '*赤*' And 好きな果物 like '*りん*') Or (メッセージ like '*週末*')"
  Debug.Print myStr
  DoCmd.OpenForm "検索結果", , , Mid(myStr, 6)
End Sub

こちらはやったのですが、何も反応しない(検索しない)状態でした。こちらを参考に
Private Sub 検索開始_Click()
  Dim myStr As String '条件
  myStr = ""
  If Not IsNull(txb名前) Then
     myStr = myStr & " And (好きな色 like '*赤*' And 好きな果物 like '*りんご*') Or (メッセージ like '*週末*')"
  End If
  DoCmd.OpenForm "検索結果", , , Mid(myStr, 6)
End Sub
として動作確認しました。
 
 
結論としては                               ↓この"が不要でした。
 myStr = myStr & " And( "メッセージ like '*" & txbメッセージ1.Value & "*'" )Or( " メッセージ like '*" & txbメッセージ2.Value & "*'" )
 
ご丁寧に教えていただきましてありがとうございました。
また何かありましたら、よろしくお願いいたします。