Microsoft Access 掲示板

検索コンボボックスの選択肢追加

17 コメント
views
4 フォロー

お世話になっております。
現在、「年月日」のフィールドについて、クエリで「年月」にしぼりこみ
クエリ「年月」を参照したコンボボックスを使って
「年月」で絞り込むための検索機能を作っています。

そのリストの中で、「年月」が存在しない(まだ未入力)レコードがあり、
コンボボックスに「未入力」を追加したいと思っています。
ちなみに現在空白のフィールドをそのままコンボボックスに残してみましたが
空白のみが絞り込まれて検索されることはできませんでした…

どうしたらよいでしょうか。説明下手ですみません。ご教示のほど、よろしくお願いします。

cerophan
作成: 2020/06/24 (水) 16:40:07
最終更新: 2020/06/24 (水) 16:41:12
通報 ...
1
hatena 2020/06/24 (水) 18:42:47 修正

ユニオンクエリで追加すればどうでしょうか。

下記は「すべて」を追加する方法ですのて、これを参考に「未入力」を追加すればいいでしょう。

コンボボックス(リストボックス)のリストに"(すべて)"を追加する - hatena chips

具体的にどのようなSQLにすればいいか分からない場合は、現状のリストボックスの値集合ソースのクエリのSQLを提示してください。

2
cerophan 2020/06/24 (水) 20:14:31 a6218@1c915

ありがとうございます!ちなみに、「下記は」というのはどの件でしょうか。見落としがあったら申し訳ありません。

3

あっ、ごめんなさい(;^ω^)
リンクを貼り付けたつもりでしたが、できてませんでした。回答を修正しましたので、リンク先を参考にしてください。

4
hiroton 2020/06/26 (金) 08:27:30 85dae@f966d

フォームのレコードソースと「年月」クエリに検索用のフィールド
年月検索用: Format(Nz([年月日]," 未入力"),"yyyymm")
を用意してあげればいいかなぁと

" 未入力"部分には「未入力」の前に半角スペースが入っています

5
cerophan 2020/08/07 (金) 00:12:02 0029a@1c915

こちらの件、ずっと解決できず課題になっていました。
下記sqlを作ったのですが、うまくいきません…なぜでしょうか…
①元のデータが降順にならない。
②すべてが表示されない。

SELECT DISTINCT T_案件.年月
FROM T_案件
ORDER BY T_案件.年月 DESC
UNION
SELECT "(すべて)" AS 案件NO FROM T_案件;

6
cerophan 2020/08/07 (金) 07:56:29 0029a@1c915 >> 5

あ・・わかりました、
上記SQLをcbo年月に入れて、下記をVBAに入れています。
これが、②に対応できていないんですね・・もう少し考えてみます。

Private Sub cbo年月_Click()
    DoCmd.SetFilter "", "[年月] Like [Forms]![F_案件]![cbo年月]", ""
End Sub

7
cerophan 2020/08/07 (金) 08:37:07 0029a@1c915

下記作成しましたが、何を選択してもなにも表示されない状態になりました。
また、コンボボックス内に空白の選択肢ができてしまいます。

SELECT "(すべて)" AS 年月
FROM T_案件
UNION SELECT 年月
FROM T_案件;

'年月選択 更新後処理
Private Sub cbo年月_AfterUpdate()
    If Me.cbo年月 = "" Then
        Me.Filter = ""
        Me.FilterOn = True
    Else
        Me.Filter = "年月=" & Me.cbo年月
        Me.FilterOn = True
    End If
End Sub

8
cerophan 2020/08/07 (金) 08:47:08 0029a@1c915 >> 7

上記は、値集合ソースとvbaに入力しているものです。

9
cerophan 2020/08/07 (金) 21:59:18 0029a@1c915

修正しました!
しかし、まだ問題点が残っています。

①年月がなぜか選べなくなった。(選択すると表示されるレコードが0になる)
②(空欄)の選択肢を一番上に持ってくる方法がわからない。

【VBA】
Private Sub cbo年月_AfterUpdate()

    If Me.cbo年月 = "(空欄)" Then
        Me.Filter = ""
        Me.FilterOn = True
    Else
        Me.Filter = "年月=" & Me.cbo年月
        Me.FilterOn = True
    End If
End Sub

【値集合ソース】
SELECT DISTINCT "(空欄)" AS 年月
FROM T_案件
WHERE (((T_案件.年月) Is Null))
UNION SELECT DISTINCT 年月
FROM T_案件
ORDER BY 年月 DESC;

★下記のVBAにすると、きちんと絞り込み表示ができます。
Private Sub cbo年月_Click()
    DoCmd.SetFilter "", "[年月] Like [Forms]![F_案件]![cbo年月]", ""
End Sub

11
cerophan 2020/08/07 (金) 22:57:47 0029a@1c915 >> 9

【VBA】すみません・・修正しました。

Private Sub cbo年月_AfterUpdate()

    If Me.cbo年月 = "(空欄)" Then
        Me.Filter = "年月 Is Null"
        Me.FilterOn = True
    Else

        Me.Filter = "年月 ='" & Me!cbo年月 & "'"
        Me.FilterOn = True
    End If
End Sub

★残り問題点
①(空欄)が選択肢の一番下に表示されるのを一番上に持ってきたい
②選択肢の中に空のものがあるのを表示しないようにしたい。

10

現状のファイルを送信フォームから送ってもらった方が速そうです。

12
cerophan 2020/08/07 (金) 23:19:54 0029a@1c915 >> 10

何度も連投してしまい、申し訳ありません。自己解決する度、お答えする手間をかけないようにと思って都度都度投稿してしまっておりました…
現状のファイルをお送りしたい気持ちは山々なのですが、難しい状況です。
お言葉、ありがとうございます。

今回の件は、下記で解決とすることにしました。
大変お騒がせしました。

★降順にしていたものを昇順としたが、その他の問題は解決。
【値集合ソース】
SELECT DISTINCT "(空欄)" AS 年月
FROM T_案件
WHERE (((T_案件.年月) Is Null))
UNION SELECT DISTINCT T_案件.年月
FROM T_案件
WHERE (((T_案件.年月) Is Not Null));

13

簡単なサンプルを作成してみました。
下記のリンクでダウンロードできます。

案件管理.zip

14

サンプルの解説

テーブル T_案件 に 日付/時刻型の「年月日」フィールドがある。
「年月日」は未入力(NUll)のレコードもある。

上記のテーブルから帳票フォームを作成する。
フォームヘッダーにコンボボックスを「cbo年月」を配置する。

値集合ソース

SELECT DISTINCT
 Format(Format([年月日],"yyyy/mm"),"&;""(空欄)""") AS 年月,
 [年月日] Is Null AS N
FROM T_案件
ORDER BY 2, 1 DESC; 

テーブルに未入力のレコードが存在するのでユニオンクエリにする必要はなかったです。
Format([年月日],"yyyy/mm") で年月日を年月に変換、
さらに Format(・・・,"&;""(空欄)""") をかぶせることで、Nullを(空欄)に変換。

(空欄)を先頭に持ってくるようにするために、[年月日] Is Null AS N というフィールドを追加

ORDER BY 2, 1 DESC;
の数字は何列目かを指定しています。下記と同じ意味になります。
ORDER BY [年月日] Is Null, Format(Format([年月日],"yyyy/mm"),"&;""(空欄)""") DESC;
フィールドの式が長いときは簡略化できるので便利です。


cbo年月の更新後処理のイベントプロシージャ

Private Sub cbo年月_AfterUpdate()
    If Nz(Me.cbo年月) = "" Then
        Me.Filter = ""
        Me.FilterOn = False
    ElseIf Me.cbo年月 = "(空欄)" Then
        Me.Filter = "年月日 Is Null"
        Me.FilterOn = True
    Else
        Me.Filter = "年月日>=#" & Me!cbo年月 & "# AND 年月日<#" & _
                     DateAdd("m", 1, Me!cbo年月) & "#"
        Me.FilterOn = True
    End If
End Sub

cbo年月 が未選択の時は全件表示、
"(空欄)"を選択したときは年月日が空欄のレコードを抽出、
年月を選択したときは、その年月のレコードを抽出。

年月でフィルターをかける時、
Me.Filter = "Format([日付],"yyyy/mm")='" & Me!cbo年月 & "'"
とした方がコードは短くなるが、インデックスが無効になるので、処理を軽くしたい場合は上のコードのように年月日フィールドに直接条件を設定するようにしたほうがよい。
詳細は下記参照。

抽出条件でインデックスが無効になる場合 - hatena chips

15
cerophan 2020/08/08 (土) 07:44:28 0029a@1c915 >> 12

とても丁寧な解説、本当にありがとうございます。じっくり読み解きたいと思います。心から感謝申し上げます。

16
セロハン 2020/08/08 (土) 10:06:09 0029a@1c915 >> 12

内容確認しました!とても勉強になりました。
「抽出条件でインデックスが無効になる場合」につきましては、また新しい知識なので勉強したいと思います。インデックスもいまいち理解できていなかったので貴重なお話をありがとうございます。

17

データ数が多くて処理が重く感じた時点で、インデックスを付けることを検討するということでもいいです。
インデックスとは、百科事典・学術書などの最後についている索引のようなものと考えればいいでしょう。
それが、あると検索や抽出が高速になります。