Microsoft Access 掲示板

検索のテキストが消えてほしい

14 コメント
views
4 フォロー

現在、検索条件が消えるように下記のようなVBAを作っていましたが
複数ページに検索ボックス等がたくさんあり、全部作るのがしんどくなってきました・・
また、検索した瞬間にも消えてほしいです。
色々わがままでしょうか・・何か良い案はありますでしょうか。

'検索するとき他条件が消える

Private Sub cbo処理月_GotFocus()
Me.cbo売上月.Value = ""
Me.cbo得意先.Value = ""
Me.txt案件NO検索.Value = ""

End Sub

cerophan
作成: 2020/07/29 (水) 14:47:44
最終更新: 2020/07/29 (水) 14:48:03
通報 ...
1

また、検索した瞬間にも消えてほしいです。

この検索はどのようにしてますか。VBAでしょうか。もし、そうならそのVBAを提示してください。

ただ、どのような検索条件の結果なのか確認するためにも、条件入力用コントロールの値は残っていた方がいいのよう思いますが。

検索条件クリアボタンを配置しておいて、そのクリックで条件入力用コントロールの値を消して、抽出も解除するようにすべきだと思います。

2
cerophan 2020/07/29 (水) 16:34:21 0029a@1c915

ほかのボックスに検索条件が残っていると、
条件を合体できていると勘違いされそうなので、
どこかのタイミングで自動で消えるようにしたいと考えていました。

いずれは、検索条件を合体させたい(検索した結果から新たに絞り込みできる)
とも考えていたのですが複雑になりそうでしょうか。
いろんなページに複数の検索ボックスを配置しているので、あまり複雑なら
クリアボタン1個配置にとどめようかと考えています。

検索ボックスの1つは以下になります。

Private Sub btn案件NO検索_Click()
    DoCmd.OpenForm "F_案件", , "", "[案件NO]=[Forms]![F_メインメニュー]![txt案件NO検索]"
End Sub

3
hatena 2020/07/29 (水) 17:17:16 修正

条件を合体できていると勘違いされそうなので、
どこかのタイミングで自動で消えるようにしたいと考えていました。

合体できない=一つのフィールドのみの条件という仕様にするなら、下記のようなコードにすればいいでしょう。

Private Sub btn案件NO検索_Click()
    Dim ctl As Control
   For Each ctl In Me.Controls
        Select Case ctl.ControlType
        Case acTextBox, acComboBox
            If ctl.Name <> "txt案件NO検索" Then ctl.Value = Null
        End Select
    Next

    DoCmd.OpenForm "F_案件", , "", "[案件NO]=[Forms]![F_メインメニュー]![txt案件NO検索]"
End Sub

このようなフォーム、コントロールが多数あるというなら、汎用関数にしてそれを各フォームから呼び出すという方法にもできますが、まずは上記のコードを理解してからですね。

いずれは、検索条件を合体させたい(検索した結果から新たに絞り込みできる)
とも考えていたのですが複雑になりそうでしょうか。

複数の抽出条件を設定したいということなら、下記を参考にしてください。

複数条件の抽出フォームの設計 その1 - hatena chips

上記はヘッダーに条件コントロールを配置して自身のフォームにフィルターをかけてますが、別のフォームを開く場合は、
生成された抽出条件(strFilter)を DoCmd.OpenForm のWhere条件引数に渡せばいいだけです。

7
セロハン 2020/09/07 (月) 14:40:30 0029a@1c915 >> 3

以前教えていただいた検索フォームを作成中です。
そこで、教えていただいたサイトを参考に下記コードを作成しましたが、うまく動きません。

""" If Not IsNull(Me.txt伝票NO) Then
        strFilter = strFilter & " AND " & BuildCriteria("伝票NO", 10, "" & Replace(Me.txt伝票NO, vbCrLf, " And ") & "")

    End If
        DoCmd.OpenForm "F_案件", acNormal, "", "Mid(strFilter,10)", , acNormal
"""

①txt伝票NOに、改行区切りで入れられた複数の伝票NOについて
全て検索する。
②伝票NOは短いテキスト。

このコードを使うと「strFilter」のパラメータを聞いてきます。
エラー業は
        DoCmd.OpenForm "F_案件", acNormal, "", "Mid(strFilter,10)", , acNormal です。

4
hiroton 2020/07/30 (木) 09:22:05 6f154@f966d

いろんなページに複数の検索ボックスを配置している

    DoCmd.OpenForm "F_案件", , "", "[案件NO]=[Forms]![F_メインメニュー]![txt案件NO検索]"

「検索」という機能があちこちに分散している上に、それに使う値も「検索」機能のあるフォーム(ページ)とは違う場所から持ってきているんですか?
「検索」機能で本当にやりたいことがよくわかりませんが、インターフェースの設計を見直したほうがいい気がします

「検索」用のフォームを独立してつくり、各ページにサブフォームとして埋め込むとか、「検索」フォームのポップアッププロパティを「はい」にして開くとかすれば、検索機能を何回も作る必要はなくなります

5
cerophan 2020/07/30 (木) 12:36:57 0029a@1c915

>hatena様
ありがとうございます!時間を取って確認しながら導入したいと思っております。

>hiroton様
なるほど、そこを変えた方がいいですね。現在はトップメニューと、
それぞれ中に入ったところにも手軽に検索できるように、ヘッダーに複数の検索ボックスを置いていました。
ポップアップで表示するように、検討してみたいと思います。
ありがとうございます。

6

それぞれのフォームで連結しているテーブルも異なり、検索対象のフィールドも異なるなら、ポップアップフォームで共通化するのはなかなかの難易度かと思います。
仕様の詳細が不明なのでなんともいえませんが。

もし少し仕様を明確にする方がいいでしょう。それがきまってなければ共通化しようがありません。

例えば「検索」(全件表示したまま該当レコードへ移動する)なのか「抽出」(フィルターをかける)なのか。

抽出結果は別フォームを開いて表示するのか、帳票フォームのヘッダーに条件を入力してそのフォームに抽出結果を表示するのか。

複数条件を設定する必要があるのか、ないのか。

とりあえず、「フォームフィルター」機能を使えば抽出機能(フィルターをかける機能)は簡単に実現できます。

■T'sWare Access Tips #590 ~フォームフィルタの使い方~

8
セロハン 2020/09/07 (月) 14:50:06 0029a@1c915

上記7番にて、以前いただいた投稿に返信したのですが
新しい投稿がわかりづらいかもしれないため、改めて下に追記させていただきます。
スミマセン。(コードブロックも間違えておりました)
↓ ↓
以前教えていただいた検索フォームを作成中です。
そこで、教えていただいたサイトを参考に下記コードを作成しましたが、うまく動きません。

    Dim strFilter As String, strExp As String, aryOpe As Variant
'途中省略     
 
If Not IsNull(Me.txt伝票NO) Then
         strFilter = strFilter & " AND " & BuildCriteria("伝票NO", 10, "" & Replace(Me.txt伝票NO, vbCrLf, " And ") & "")

    End If
         DoCmd.OpenForm "F_案件", acNormal, "", "Mid(strFilter,10)", , acNormal

End Sub

①txt伝票NOに、改行区切りで入れられた複数の伝票NOについて
全て検索する。
②伝票NOは短いテキスト。

上記のコードを使うと「strFilter」のパラメータを聞いてきます。
エラー行は
        DoCmd.OpenForm "F_案件", acNormal, "", "Mid(strFilter,10)", , acNormal です。

9
hiroton 2020/09/07 (月) 15:12:52 2d6b2@f966d

ちゃんと内容見てないけど
DoCmd.OpenForm "F_案件", acNormal, "", "Mid(strFilter,10)", , acNormal

DoCmd.OpenForm "F_案件", acNormal, "", Mid(strFilter,10), , acNormal

ここの「10」って数値もあんまり見ないので(正しいのかどうかわかりません)、このあたりプログラムがどう動くのかという基本を見直してみるといいと思います

10
セロハン 2020/09/07 (月) 15:46:05 0029a@1c915 >> 9

ありがとうございます。
おっしゃるとおり、「10」のところはお手本にしたコードの数字(6)が理解できず、
そのまま何やら勘違いして変更してしまっていました…
下記コードで実行してみたところ、絞り込み件数は0となりましたがエラーは出ませんでした。
伝票NO「0001 0002」を表示したいのですが、


strFilterに格納された変数
⇒" AND 伝票NO Like "0001" And 伝票NO Like "0002""

どこをなおせばよいのでしょうか…

11
セロハン 2020/09/07 (月) 15:48:31 0029a@1c915 >> 10

なぜかコードが消えてしまったのでもう一度記載します。
DoCmd.OpenForm "F_案件", acNormal, "", strFilter, , acNormal

このときのstrFilterに格納された変数
⇒" AND 案件NO Like "0001" And 案件NO Like "0002""

12
セロハン 2020/09/07 (月) 15:49:45 0029a@1c915

数値の左右には*の半角も入っています。(表示で消えています)

13
hiroton 2020/09/07 (月) 16:49:01 2d6b2@f966d

Mid関数もちゃんと使ってください

DoCmd.OpenForm "F_案件", acNormal, "", Mid(strFilter, 6), , acNormal
'または'
DoCmd.OpenForm "F_案件", acNormal, "", Mid(strFilter, Len(" AND ") + 1), , acNormal

6はマジックナンバーってやつですね。テンプレ的な記述ですが、意味のある形で記述しておくと後で見直した時も何をやっているのか分かりやすいコードになります

こういった検索なんかで複数の中からいくつかを選ぶ場合、例えば
「A and B and C」
「B and C」
「A and C」
「A」
のように、選択された項目数nに対して連結するための文字列がn-1必要という形になります。
コードを記述するなら

If (Aの条件があった場合) Then
  If strFilter <> "" Then strFilter = strFilter & " AND "
  strFilter = strFilter & Aの条件
End If
If (Bの条件があった場合) Then
  If strFilter <> "" Then strFilter = strFilter & " AND "
  strFilter = strFilter & Bの条件
End If
If (Cの条件があった場合) Then
  If strFilter <> "" Then strFilter = strFilter & " AND "
  strFilter = strFilter & Cの条件
End If

のように、毎回Ifでチェックしてもいいんですが、

If (Aの条件があった場合) Then strFilter = strFilter & " AND " & Aの条件
If (Bの条件があった場合) Then strFilter = strFilter & " AND " & Bの条件
If (Cの条件があった場合) Then strFilter = strFilter & " AND " & Cの条件

If strFilter <> "" Then
  '先頭に必ずいらない" AND "がついているので取り除く'
  strFilter = Mid(strFilter, Len(" AND ") + 1)
End If

のように作りこむとコードがすっきりするというテクニックです。このテクニックを使っているので、最後にフィルター文字列を指定する部分でMid(strFilter, 6)とするわけです


ついでですが
BuildCriteria関数の2番目に指定している「10」もマジックナンバーってやつです。関数の動きを切り替えるためのいわばモード指定なんですが、ここにはデータ型を指定することとなっています
標準関数で使うこういう数値には組み込み定数というのが用意されていて、このデータ型の場合、DataTypeEnum 列挙 (DAO)が使えます

BuildCriteria("伝票NO", 10, "" & Replace(Me.txt伝票NO, vbCrLf, " And ") & "")
'次の記述でも同じ'
BuildCriteria("伝票NO", dbText, "" & Replace(Me.txt伝票NO, vbCrLf, " And ") & "")

「10」だと10ってなんだよってなりますが「dbText」だと何となく意味がわかりますね。何か調べようと思った時も「dbText」なら検索のキーワードに使いやすいです

14
セロハン 2020/09/07 (月) 17:51:45 0029a@1c915

なぜ頭にANDがついているのか疑問だったので、6の件と共にようやく理解できました。
丁寧に解説していただき、助かりました。
「dbText」も何かわからず、逆にネットで検索して10にしてしまっていたのですが、同じものだったのですね…教えていただきありがとうございます!