Accessを利用して住所録のデータベースを作成しています。
検索用フォームのレコードソースにクエリを指定して,フォーム上にテキストボックスを2つ配置し,コマンドボタンをクリックして抽出結果をフォームに表示させます。一つめのテキストボックスには氏名,二つ目のテキストボックスには,勤務先の入力をします。以下の条件での検索結果をフォーム上に表示させたいのですが,(3)の場合に,勤務先がない(未入力の)人のデータも同時に抽出されてしまいます。
(1)氏名のみの条件で該当する人
(2)氏名及び勤務先の条件で該当する人
(3)勤務先のみの条件で該当する人
(4)条件を入力しない場合
<住所録>
ID___氏名_________フリガナ___________勤務先
1____鈴木 健一__スズキ ケンイチ__新日本商事
2____中村 主水__ナカムラ モンド___新日本商事
3____山田 太郎__ヤマダ タロウ_____
クエリには
WHERE ((([tbl THE CARD].氏名) Like "*" & [Forms]![frm_検索用]![氏名] & "*") AND (([tbl THE CARD].勤務先) Like [Forms]![frm_検索用]![勤務先] & "*")) OR ((([tbl THE CARD].氏名) Like "*" & [Forms]![frm_検索用]![氏名] & "*") AND ((([tbl THE CARD].[勤務先]) Like [Forms]![frm_検索用]![勤務先] & "*") Is Null)) OR ((([tbl THE CARD].勤務先) Like [Forms]![frm_検索用]![勤務先] & "*"))
ORDER BY [tbl THE CARD].ID;
と記載しました。
例えば,氏名と勤務先の両方の検索結果を表示させる場合,
・氏名が該当し,勤務先が空白のデータ
が抽出されます。氏名と勤務先の両方に検索条件をいれたときには,勤務先が空白のデータを抽出しないようにしたいのですが,どうしたら良いでしょうか。氏名だけで検索するときには,勤務先が空白かどうかは考慮しない結果を表示させたいと思います。
過不足があると思いますが,ご指導宜しくお願いします。
No.2ベストアンサー
- 回答日時:
横レス失礼致します。
No.1の方の組み方では、検索条件とするフィールドを追加するほど、複雑になっていきます。
VBAで対応されるのでしたら、以下のようにした方が、簡単にフィールドの追加ができます:
Private Sub 表示_Click()
On Error Goto エラー処理
Dim StrWhr As String 'Where条件式
Dim StrMsg As String '表示メッセージ
Dim StrSrc As String 'レコードソース
Dim stDocName As String '表示用フォームの名前
'検索条件が指定されているもののみを、Andで順次連結してWhere条件式を作成
If Nz(Me!氏名, "") <> "" Then
StrWhr = "氏名 Like '*" & Me!氏名 & "*'"
End If
If Nz(Me!勤務先, "") <> "" Then
StrWhr = IIF(StrWhr = "", "", StrWhr & " And ") & "勤務先 Like '*" & Me!勤務先 & "*'"
End If
If Nz(Me!住所, "") <> "" Then
StrWhr = IIF(StrWhr = "", "", StrWhr & " And ") & "住所 Like '*" & Me!住所 & "*'"
End If
'以降、検索条件を入力するテキストボックスごとに、以下のセットで追加すればOKです。
'If Nz(Me!○○, "") <> "" Then
' '曖昧検索の場合
' StrWhr = IIF(StrWhr="", "", StrWhr & " And ") & "○○ Like '*" & Me!○○ & "*'"
' '完全一致検索(数値型)の場合
' 'StrWhr = IIF(StrWhr="", "", StrWhr & " And ") & "○○ = " & Me!○○
'End If
'↓~~~OpenFormのWhere条件で絞り込みをする場合、ここの一団は不要~~~↓
If StrWhr="" Then
StrSrc = "Select * From [tbl THE CARD] Order By ID;"
Else
StrSrc = "Select * From [tbl THE CARD] Where " & StrWhr & " Order By ID;"
End If
'↑~~~OpenFormのWhere条件で絞り込みをする場合、ここの一団は不要~~~↑
'確認メッセージで「OK」を選択したら、絞り込み(または解除)を実行
If MsgBox(StrMsg, vbOKCancel, "確認") = vbOK Then
'レコードソースの切替で対応する場合
'(フォーム側のレコードソースは空白にしておくと、コントロールに一瞬エラーが表示
' されるものの、表示は速くなります)
DoCmd.OpenForm stDocName
Forms(stDocName).RecordSource = StrSrc
'フィルタ条件で対応する場合(一旦レコードを読み込んでからの絞り込みになる分、
' 表示は遅くなります)
'DoCmd.OpenForm stDocName, , , StrWhr
End If
終了処理:
Exit Sub
エラー処理:
MsgBox Err & Error$, , Me.Name & " 表示"
Resume 終了処理
End Sub
・・・以上です。
この回答への補足
詳細な構文を書いていただき,ありがとうございます。とりあえず,単純化したDBを作成し,下記のとおり記載してコマンドボタンをクリックしてみましたが,目的のフォームは表示されるものの,データが全て「#Name?」と表示されてしまい,レコードを抽出することができません。ここでは,タイトルを検索することにしています。どこが間違っているのでしょうか?VBAを使うのは初めてなので,参考書を見てみましたが,理解できません。宜しくお願いします。
Private Sub コマンド28_Click()
Dim StrWhr As String 'Where条件式
Dim StrMsg As String '表示メッセージ
Dim StrSrc As String 'レコードソース
Dim stDocName As String '表示用フォームの名前
'検索条件が指定されているもののみを、Andで順次連結してWhere条件式を作成
If Nz(Me!タイトル, "") <> "" Then
StrWhr = "タイトル Like '*" & Me!タイトル & "*'"
End If
'以降、検索条件を入力するテキストボックスごとに、以下のセットで追加すればOKです。
'If Nz(Me!○○, "") <> "" Then
' '曖昧検索の場合
' StrWhr = IIF(StrWhr="", "", StrWhr & " And ") & "○○ Like '*" & Me!○○ & "*'"
' '完全一致検索(数値型)の場合
' 'StrWhr = IIF(StrWhr="", "", StrWhr & " And ") & "○○ = " & Me!○○
'End If
If MsgBox(StrMsg, vbOKCancel, "確認") = vbOK Then
'レコードソースの切替で対応する場合
'(フォーム側のレコードソースは空白にしておくと、コントロールに一瞬エラーが表示
' されるものの、表示は速くなります)
DoCmd.OpenForm "F入力フォーム のコピー", acNormal
Forms("F入力フォーム のコピー").RecordSource = StrSrc
'フィルタ条件で対応する場合(一旦レコードを読み込んでからの絞り込みになる分、
' 表示は遅くなります)
'DoCmd.OpenForm "F入力フォーム のコピー"stDocName, , , StrWhr
End If
End Sub
No.5
- 回答日時:
No.2~4です。
> コマンドボタンは何の反応も示しませんでした。
If文で「Else」の後に「ElseIf」をおくと、エラーになるはずです。
ですので、コマンドボタンが反応しなくなったのは、そのエラーのためではないかと思います。
(VBAでのエラー処理の記述によって、エラーメッセージを出さずに処理を終了させることも
可能なので、恐らくそういった処理がされているものと考えられます)
> 両方を使用したい場合
ご要望の動作が
1)フィルタ適用時は、そのフィルタを反映してレポートを展開
2)(フィルタは適用しておらず、)引数OpenArgsで式が渡されている場合は、その式を反映
してレポートを展開
3)フィルタを適用しておらず、OpenArgsによる式の指定もない場合は、絞り込みをせずに
レポートを展開
ということでしたら、以下のようになります:
Private Sub ラベル自宅_Click()
Dim stDocName As String
stDocName = "rpt_ラベル自宅"
If Me.FilterOn Then 'フィルタ適用時(=「1」相当)
DoCmd.OpenReport stDocName, acViewPreview, , Me.Filter
ElseIf Nz(Me.OpenArgs, "")="" Then 'フィルタ非適用・OpenArgs不使用(=「3」相当)
DoCmd.OpenReport stDocName, acViewPreview
Else 'フィルタ非適用・OpenArgs使用時(=「2」相当)
DoCmd.OpenReport stDocName, acViewPreview, , Me.OpenArgs
End If
End Sub
・・・以上です。
但し、もしも「4)引数OpenArgsで式を渡した上で、表示用フォームを右クリックするなどして
フィルタによる絞り込みも適用した場合」と状態があり得るとすると、上記では不充分という
ことになってしまいます。
(「Me.FilterOn」が合致することになるため、表示用フォームで行った追加絞り込みのみが
有効になり、条件指定用のフォームで指定された検索条件(=OpenArgs)が無視される)
その場合は、上記の代わりに以下のようなコードにして下さい:
Private Sub ラベル自宅_Click()
Dim stDocName As String
Dim StrCnd As String
stDocName = "rpt_ラベル自宅"
'フィルタやOpenArgsの適用状況を元に、レポートに適用する式を作成し直します。
'(No.2の回答で、テキストボックスの追加時に行ったのと同様の考え方です)
StrCnd = Nz(Me.OpenArgs, "")
If Me.FilterOn Then 'フィルタ適用(=FilterOnがTrue)時は「Me.Filter <> ""」
StrCnd = IIF(StrCnd = "", "", StrCnd & " And ") & Me.Filter
End If
If StrCnd = "" Then 'フィルタもOpenArgsも適用していなかった場合
DoCmd.OpenReport stDocName, acViewPreview
Else '何らかの形で絞り込みが掛けられていた場合
DoCmd.OpenReport stDocName, acViewPreview, , StrCnd
End If
End Sub
数回に渡る拙い質問に丁寧に回答していただき,ありがとうございました。お陰様で満足の行くデータベースが作成できました。これからも宜しくお願いいたします。また,これを機会にVBAを少し勉強してみることにしました。
No.4
- 回答日時:
No.2,3です。
> DoCmd.OpenReport stDocName, acViewPreview, , Me.Filter
表示用フォームに適用された絞り込み(フィルタ)をレポートに転用していた、ということですね。
だとすると、「レコードソース切替」ではなく「フィルタ条件使用」にするというのが一番無難では
あります。
ただ、そうすると、No.2で回答した通り、表示速度は低下します。
ですので、「レコードソース切替」という手段は保ちつつ、改修を最小限にするという観点から、
「フィルタに相当する式を表示フォームに渡しておき、レポート展開時にその式を使用する」、
というのがよいかと思います。
具体的には以下の通りです(それぞれ改修が必要になる部分のみの抜粋):
【表示用フォームを開くコマンドボタンでの改修内容】
<現状>
DoCmd.OpenForm stDocName
<改修後>
'OpenFormの引数OpenArgsとして、表示用フォームにStrWhrの値を渡します。
DoCmd.OpenForm stDocName, , , , , , StrWhr
【表示用フォームの、レポートを開くコマンドボタンでの改修内容】
<現状>
If Me.FilterOn Then
DoCmd.OpenReport stDocName, acViewPreview, , Me.Filter
Else
DoCmd.OpenReport stDocName, acViewPreview
End If
<改修後>
'従来のFilterの代わりに、OpenArgsで受け取った式をレポートに適用します。
'(「OpenArgs=""」(=空)は、フィルタを適用していない場合(→FilterOn=False)に相当)
If Nz(Me.OpenArgs, "") = "" Then
DoCmd.OpenReport stDocName, acViewPreview
Else
DoCmd.OpenReport stDocName, acViewPreview, , Me.OpenArgs
End If
・・・以上です。
この回答への補足
お返事が遅くなりました。上記の記述でできました。本当にありがとうございました。最後に,もう一つ,質問があります。表示用フォームの、レポートを開くコマンドボタンにおいて,
(1)フィルタを適用したデータをレポートに表示させる(以前に設定していた構文)
(2)フィルタに相当する式を表示フォームに渡しておき、レポート展開時にその式を使用する(今回教えていただいた構文)
の両方を使用したい場合,
Private Sub ラベル自宅_Click()
Dim stDocName As String
stDocName = "rpt_ラベル自宅"
If Nz(Me.OpenArgs, "") = "" Then
DoCmd.OpenReport stDocName, acViewPreview
Else
DoCmd.OpenReport stDocName, acViewPreview, , Me.OpenArgs
ElseIf Me.FilterOn Then
DoCmd.OpenReport stDocName, acViewPreview, , Me.Filter
Else
DoCmd.OpenReport stDocName, acViewPreview
End If
End Sub
と,単純にくっつけてみましたが,コマンドボタンは何の反応も示しませんでした。何度も,申し訳ありませんが,もし可能でしたらその方法を教えていただけると助かります。
No.3
- 回答日時:
No.2です。
> データが全て「#Name?」と表示されて
これは、レコードソースが空のフォームで、テキストボックスのコントロールソースにフィールド名を
入力している場合に起こるエラーです。
(前回の回答で、「コントロールに一瞬エラーが表示される」と言ったエラーそのものになります)
補足欄に書かれたコードを見ると、レコードソースの切替で対応する方法を選択されていますが、
「↓~~~・・・~~~↓」から「↑~~~・・・~~~↑」で囲んだ『Where条件で絞り込む場合
は不要な部分』=『レコードソースの切替で対応する場合は必要な部分』が、省略されて
しまっています。
そのため、「StrSrc」(=レコードソース)にSQL文が記録されず空(="")のままになってしまっているので、
「#Name?」(=「レコードソースに、そのNameのフィールドがありませんよ?」)というエラーが表示された
ままになって(=一瞬ではなくなって)しまっているわけです。
ですので、「↓~~~・・・~~~↓」から「↑~~~・・・~~~↑」で囲んだ部分を追加すれば、
上記のエラーは解消するものと思います。
※Where条件を使用する場合とレコードソース切替の場合で、コードを完全に分けてしまった方が
わかりやすかったかもしれません。反省(汗)
この回答への補足
ありがとうございました。が,表示用のフォームに設定したコマンドボタンが使用できなくなってしまいました・・・・。表示用のフォームには,
Private Sub 封筒角2勤務先_Click()
Dim stDocName As String
stDocName = "rpt_封筒角2勤務先"
If Me.FilterOn Then
DoCmd.OpenReport stDocName, acViewPreview, , Me.Filter
Else
DoCmd.OpenReport stDocName, acViewPreview
End If
End Sub
という構文を書いていたのですが,検索用フォームのコマンドボタンを使用して表示用フォームに表示させたデータはフィルタ処理されていないようです。封筒角2勤務先のコマンドボタンを押すと,全件がレポートに表示されてしまいます。
(1)検索用フォームから開く表示用フォームを別個に作成し,新しいコマンドボタンを作成して,検索用フォームからの検索結果をレポートに表示させる
(2)今の表示用フォームのコマンドを書き換える
のどちらかだと思うのですが,ご教示お願いいたします。
No.1
- 回答日時:
住所録:
ID__氏名_______フリガナ________勤務先
_1__鈴木 健一__スズキ ケンイチ__新日本商事
_2__中村 主水__ナカムラ モンド__新日本商事
_3__山田 太郎__ヤマダ タロウ______________
_4__鈴木 健二__スズキ ケンジ______________
このようなテーブルをもとに表タイプのフォームを作成します。
フッターに[参照する氏名]と[参照する勤務先]という参照したいデータの入力欄を配置。
参照する氏名__[鈴__________]
参照する勤務先[____________]
_1__鈴木 健一__スズキ ケンイチ__新日本商事
_4__鈴木 健二__スズキ ケンジ______________
参照する氏名__[鈴__________]
参照する勤務先[新__________]
_1__鈴木 健一__スズキ ケンイチ__新日本商事
で、このような検索結果を得るサンプルコードです。
Private Sub コマンド_参照_Click()
Dim A As Integer
Dim strWhere As String
A = Abs(Len(Me.参照する氏名 & "")) + Abs(Len(Me.参照する勤務先 & "") * 2)
Select Case A
Case 1
strWhere = "氏名 LIKE '" & Me.参照する氏名 & "*'"
Case 2
strWhere = "勤務先 LIKE '" & Me.参照する勤務先 & "*'"
Case 3
strWhere = "氏名 LIKE '" & Me.参照する氏名 & "*' AND 勤務先 LIKE '" & Me.参照する勤務先 & "*'"
Case Else
End Select
If Len(strWhere & "") Then
Me.RecordSource = "SELECT * FROM 住所録 WHERE " & strWhere & " ORDER BY ID"
Me.Requery
End If
End Sub
ここでは4つのケースに応じて単純に WHERE節を生成しています。
滅茶苦茶に複雑なクエリに頭を悩ますよりも、やりたいことをそのまんま書く。
レコードソースを書換えてリクエリすれば事足りる訳ですから・・・。
この回答への補足
回答ありがとうございます。氏名,勤務先の他に,IDや住所,電話番号等でも検索したい場合には,条件を加筆していけば,いくらでも増やせるのでしょうか?
コマンドボタンを押して検索結果を表示させるのは別のフォームを使いたいので,
Me.Requery
End If
の後に
End Select
DoCmd.OpenForm stDocName, , , "[frm THE CARD]='" & Me![氏名] & "'"
と記述しましたが,反応しません。どこが間違っているのでしょうか。
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
ハマっている「お菓子」を教えて!
この世には、おいしいお菓子がありすぎて……。 次何を食べたらいいか迷っています。 みなさんが今、ハマっている「お菓子」を教えてください!
-
【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
2024年は「名探偵コナン30周年」「涼宮ハルヒ20周年」などを迎えますが、 あなたが「もうそんなに!?」と驚いた○○周年を教えてください。
-
メモのコツを教えてください!
メモを取るのが苦手です。 急いでメモすると内容がごちゃごちゃになってしまったり、ひどいときには全く読めない時もあります。
-
【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
【お題】 ・買ったばかりの自転車を分解してひと言
-
14歳の自分に衝撃の事実を告げてください
タイムマシンで14歳の自分のところに現れた未来のあなた。 衝撃的な事実を告げて自分に驚かせるとしたら何を告げますか?
-
Access 複数条件のフィルタ
その他(Microsoft Office)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
レコードを保存するコード ア...
-
アクセスでフォームビューがみ...
-
レコード削除時に(サブ)フォー...
-
Accessで上の行を自動でコピー...
-
新規レコード行を非表示にしたい
-
アクセスの自動保存解除はでき...
-
フィルタ後のフォームの件数の...
-
Accessでレコードの保存をせず...
-
Accessで一件の新規レコードの...
-
Access:フォームプロパティ「...
-
ACCESSでフォームを使って、テ...
-
ACCESSのクエリで抽出したデー...
-
ACCESS起動時に所定フォームを...
-
Accessでチェックボックスで抽...
-
ACCESSフォームのリストボック...
-
ACCESS「ンボ ボックスで選択し...
-
アクセスのフォームで立ち上げ...
-
アクセス 前レコード内容を、...
-
Access2016 入力専用フォームと...
-
Access非連結フォームから複数...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
レコードを保存するコード ア...
-
アクセスでフォームビューがみ...
-
フィルタ後のフォームの件数の...
-
新規レコード行を非表示にしたい
-
アクセスの自動保存解除はでき...
-
ACCESSでフォームを使って、テ...
-
レコード削除時に(サブ)フォー...
-
Accessでレコードの保存をせず...
-
Access:フォームプロパティ「...
-
Accessでフォーム上に 直前の...
-
ACCESS起動時に所定フォームを...
-
AccessVBA RecordSourceのリセ...
-
アクセスでの警告について教え...
-
accessのクエリで、該当するデ...
-
アクセス データの競合を非表...
-
Access 「このレコードを保存す...
-
Accessで上の行を自動でコピー...
-
Access サブフォームにフィルタ...
-
Access2010、値を入力したら自...
-
Accessで新しいレコードに規定...
おすすめ情報