ACCESS VBA 日付で検索するフォームの作成方法

ACCESSではレコードを抽出するための検索フォームをよく作成します。

その中でも、日付での検索はかなり使われる機能と言えます。

今回は、日付で検索するフォームの作成方法をご紹介します。


こんにちは。
はこにわガジェット (@hakoniwagadget) です。

ACCESSを使った売上管理、顧客管理などのデータベース開発を行っています。
ACCESSは使いこなすために少しスキルが必要なものの、うまく活用すればExcelよりも業務の効率化が図れます。
この記事ではACCESSで実際に作成したフォームやレポートを、その作成方法と共にご紹介していきます。

完成形

ではまず、日付を使って検索するフォームの完成形を示します。

上記は売上レコードを検索するためのフォームです。
上段に検索条件として処理日を開始日、終了日の期間を指定して検索する項目を作っており、下段はその結果に応じたレコードが一覧表示されるようになっています。

レコードソースのクエリ

では、上記のフォームの作成方法を見ていきましょう。

まずはフォームのレコードソースとなるクエリを作成します。
ここではクエリを使っていますが、フォームに表示したい項目が網羅されていれば、テーブルでも問題ありません。

今回は以下の「LIST_売上明細」クエリを準備しました。

このテーブル、クエリの準備には特筆すべき部分はなく、単純に検索に必要なテーブルもしくはクエリをご準備ください。

フォームの作成

次にフォームを作成します。
フォームは、メニューのフォームデザインから作成します。

フォームデザイン

レイアウトを整えていって作成したフォームをデザインビューで見ると、下記になります。

画面右側のプロパティシートを見ていただくと、フォーム全体のレコードソースに先ほど準備したクエリ「LIST_売上明細」が指定されていることが分かります。

また、フォームの既定のビューには「帳票フォーム」を指定しています。

帳票フォームを指定することで、フォームの詳細セクションをレコード数分繰り返すことができます。
以下の赤枠部分ですね。

レコードを一覧表示するフォームを作成する際は、帳票フォームを使いますので覚えておいてください。

検索条件テキストボックスの配置

日付検索の機能を実装するため、フォームヘッダー部分には検索のためのテキストボックスやボタンを配置しています。
同じくデザインビューで見ていきましょう。

まずは検索条件を指定するためのテキストボックスです。
こちらは、ACCESSのメニューからテキストボックスを選択して配置します。

今回は「処理日検索FROM」「処理日検索TO」という2つのテキストボックスを準備しました。
どちらも非連結になっており、テーブルやクエリの値とは連動せずに単純にフォーム上に日付だけが入力できる状態にしてあります。

プロパティシートの書式を日付にすることで、日付型データの入力が可能です。

検索機能

次に、検索ボタンを配置します。

今回は下記のように検索ボタンを配置し、そのクリック時イベントとしてイベントプロシージャを設定しました。

プロパティシートの一番右の「…」ボタンを押すとVisual Basic Editor(VBE)が起動します。
以下がイベントプロシージャの内容です。


Private Sub 検索_ボタン_Click()

Dim filter_txt As String

'FROM、TOの前後不備チェック
If Me!処理日検索FROM <> "" And Me!処理日検索TO <> "" Then

    If Me!処理日検索FROM > Me!処理日検索TO Then

        MsgBox "期間指定が不適切です。再度入力してください。", vbCritical + vbOKOnly, "期間指定不備"
        Exit Sub

    End If

End If

'処理期間
If Me!処理日検索FROM <> "" Then
    
    If Me!処理日検索TO <> "" Then
        
        filter_txt = "処理日 >= #" & Me!処理日検索FROM & "# and 処理日 <= #" & Me!処理日検索TO & "#"
    
    Else
        
        filter_txt = "処理日 >= #" & Me!処理日検索FROM & "#"
        
    End If
        
ElseIf Me!処理日検索TO <> "" Then

    filter_txt = "処理日 <= #" & Me!処理日検索TO & "#"
        
End If
    
If filter_txt = "" Then

    Me.FilterOn = False

Else

    Me.Filter = filter_txt
    Me.FilterOn = True
    Me.OrderBy = "処理日 DESC"
    Me.OrderByOn = True

End If

End Sub
 

ここからはプロシージャの内容を解説します。

処理概要

まず、全体の処理の流れです。

このプロシージャでは検索条件をfilter_txtという変数に格納します。
この検索条件はフォームで指定された開始日、終了日をもとに動的に変更します。

そしてその検索条件をフォームのFilterプロパティに格納して、フィルターを実行することで検索結果を表示しています。

変数の定義

最初に使用する変数を定義します。


 Dim filter_txt As String
 

このfilter_txtはフォームで指定した検索条件を格納するための変数です。
そのため、テキスト型になっています。

FROM、TOの前後不備チェック

次に、フォームでの検索条件指定の不備をチェックします。

今回でいうと日付の開始日と終了日を指定していますので、開始日の方が終了日よりも後になっているとおかしいですよね。
そこでその前後に矛盾がないかをチェックします。


 If Me!処理日検索FROM <> "" And Me!処理日検索TO <> "" Then
 

最初のこのIf文は、フォームにある検索条件を指定するためのテキストボックスのFROMとTOの両方に条件が指定されているかをチェックしています。
<>はNotの意味ですので、上記の条件は処理日検索FROMも処理日検索TOも空白ではないとき、つまり、開始日と終了日の両方に条件が指定されているとき、という指定をしています。

なぜなら、FROM、TOの前後の不備は両方のテキストボックスに値が入力されているときしか発生しないからです。

そのうえで、この条件に合致した場合のみ前後のチェックを以下で行っています。


    If Me!処理日検索FROM > Me!処理日検索TO Then

        MsgBox "期間指定が不適切です。再度入力してください。", vbCritical + vbOKOnly, "期間指定不備"
        Exit Sub

    End If
 

ここは単純ですね。
処理日検索FROMか処理日検索TOよりも大きかったときは、MsgBox関数でエラーメッセージを出し、Exit Subで処理を中断しています。

ここまでで、前後の不備がチェックできました。

検索条件式の作成

そしていよいよ検索条件のテキストを作成します。
以下の部分です。


'処理期間
If Me!処理日検索FROM <> "" Then
    
    If Me!処理日検索TO <> "" Then
        
        filter_txt = "処理日 >= #" & Me!処理日検索FROM & "# and 処理日 <= #" & Me!処理日検索TO & "#"
    
    Else
        
        filter_txt = "処理日 >= #" & Me!処理日検索FROM & "#"
        
    End If
        
ElseIf Me!処理日検索TO <> "" Then

    filter_txt = "処理日 <= #" & Me!処理日検索TO & "#"
        
End If
 

処理日検索のFROMとTOのどちらに値が入力されているかによって、最終的に作成する条件式が変わってきます。
そのため、If文でFROM、TOのそれぞれが空白でないかをチェックして分岐させています。

FROMにもTOにも値が入力されている、つまり日付の開始と終了を両方指定している場合は


 filter_txt = "処理日 >= #" & Me!処理日検索FROM & "# and 処理日 <= #" & Me!処理日検索TO & "#"
 

になります。
処理日検索FROMよりも該当の処理日が大きく、かつ、処理日検索TOよりも該当の処理日が小さいものを抽出する、という条件式です。

ここでMe!処理日検索FROMやMe!処理日検索TOは、売上検索フォームに設置されたテキストボックスに入力された値を指しています。

また、それぞれの前後に「#」を付けているのが、これが日付型のデータだからです。
ACCESSでは日付型の値は前後に「#」を付けることで日付として扱うことができます。

今回、処理日自体は日付型データですので、その値と比較するためには検索条件側も日付型データで指定する必要があります。
間違えやすいので注意しましょう。

同様に、処理日検索FROMだけを指定した場合は、


 filter_txt = "処理日 >= #" & Me!処理日検索FROM & "#"
 

処理日検索TOだけを指定した場合は、


 filter_txt = "処理日 <= #" & Me!処理日検索TO & "#"
 

となります。
これは、先ほどのFROM、TOを両方指定したものから片方だけを抜き出した形ですね。

ここまででフォームで入力された条件をFilter_txtに格納することができました。
ただ、もう一つだけ考慮すべきパターンがあります。

それは、フォームで検索条件が何も指定されなかった場合です。
これを考慮しておかないと実行時にVBAが、「Filter_txtに入力する値がない」とエラーを出してしまいます。

そこで、


If filter_txt = "" Then

    Me.FilterOn = False 
 

を入れています。

ここまでの処理でFilter_txtが空白だった場合は、Me.FilterOn = False、つまりフィルター処理を行わずに終了する、という意味です。
これで検索条件が指定されない場合のエラーを回避できます。

そしてそのElse側、つまり検索条件が指定された場合は、


Else

    Me.Filter = filter_txt
    Me.FilterOn = True
    Me.OrderBy = "処理日 DESC"
    Me.OrderByOn = True

End If
 

という処理を行います。

Me.Filter、つまり売上検索フォームのフィルタープロパティにここまでに生成したFilter_txtの値を代入し、Me.FilterOn = Trueでフィルターを適用します。
ついでにMe.OrderByでソート順も変更しています。

これで日付条件を指定して検索する機能が作成できました。

この機能は検索条件が増えた場合も、上記のVBAでFilter_txtを作っていく箇所に、新たに追加した検索条件に該当する式を追加するだけで動作しますので、非常に汎用性高く利用することが可能です。

以上、日付で検索するフォームの作成方法をご紹介しました。


ACCESSを使いこなせば、業務の効率化や自動化が実現できます。
しかし、自分でACCESSを学ぶには時間がない、難しそうで不安、という方も多いでしょう。

そんな時は、ACCESS開発歴20年以上、過去に100以上のACCESSデータベースを開発してきた私(@hakoniwagadget)にお任せください。

ACCESSの新規開発、既存のACCESSの修正、ACCESSの操作レッスンなど様々なサービスをご提供しています。
ご興味のある方は下記のサービス一覧をご覧ください。

サービス一覧

最後までお読みいただき、ありがとうございました。