ExcelとAccessのスキルアップをサポートするサイトです

ExcelとAccessの学習室

【Access VBA】RecordSourceを使ったコンボボックス検索の基本

この記事で学習できること
  • RecordSourceプロパティを使って、フォームの表示データを動的に切り替える方法が理解できる
  • RecordSource方式の仕組みとメリットを理解し、フォーム設計に応用できるようになる
  • Access VBAで安全にRecordSourceを扱うための基本コードと注意点を身につけられる

Accessで作成したフォームに「検索機能」をつけたいと思ったことはありませんか?
たとえば、商品名や担当者名を選ぶだけで、該当するデータだけをすぐに表示できたら便利ですよね。

このような検索機能は、コンボボックスを使うことで手軽に実現できます。
コンボボックスで選択した値をもとに、フォームのデータを自動的に絞り込む仕組みを作れば、ユーザーは複雑な操作をしなくても、目的の情報をすぐに見つけられるようになります。

Accessでは、コンボボックスでデータを検索する方法はいくつかありますが、今回はその中の一つであるRecordSourceを使ったVBAテクニックを紹介します。
Access初心者の方でも理解できるよう、コンボボックス自体の設定から条件選択後のデータ絞り込みまで、順を追って説明していきます。

さらに、サンプルデータベースもダウンロードできるようにしているので、Zipファイルを解凍してご使用ください。

 ≫ サンプルデータベース(Filter_Example_Combo.accdb)

なぜRecordSourceを使った方法がおすすめなのか

Accessでコンボボックスによる検索を実装する方法には、RecordSourceプロパティFilterプロパティFindFirstメソッドの3つがあります。
その中でも「RecordSource」を使う方法は、次の理由から最もおすすめです。

  • SQL文を通してデータベースの仕組みを理解できる
  • PythonやJavaScriptなど、他の言語にも応用しやすい能
  • <li複数条件での検索に柔軟に対応できる

RecordSourceプロパティを使う場合、フォームの表示データをSQL文で指定します。
SQL(Structured Query Language)はデータベース操作の共通言語であり、多少の文法差はあるものの、ほぼすべてのデータベースシステムで利用されています。
特にデータベースの経験が浅い方にとっては、RecordSourceを通してSQL文を学ぶことが、今後のスキルアップにつながるでしょう。

また、PythonJavaScriptといった他の開発言語でも、RecordSourceを使ったVBAコードとよく似た考え方で検索処理を記述できます。
これらの言語でもFilterFindFirstに相当する処理はありますが、構文やデータの扱い方が異なるため、多言語に展開していくことを考えるなら、まずRecordSource方式に慣れておくのが近道です。

さらに、複数の条件を組み合わせて検索する場合も、SQL文のWHERE句を変更するだけで対応できるため、追加のロジックを書かずに柔軟な絞り込みを実現できるという利点があります。
Accessで検索機能を作る際の基本形として、まずはこの方法をしっかり理解しておくとよいでしょう。

RecordSourceに慣れた段階で、FilterFindFirstメソッドにも挑戦すると、より幅広い検索手法を使い分けられるようになります。

RecordSourceを使ったコンボボックスの動作

では、実際にコンボボックスで条件を設定し、RecordSourceプロパティを使って絞り込む動作を確認してみましょう。

サンプルデータベースを開くと、ナビゲーションウインドウにフォームが6つ設置されているのが確認できます。

フォーム名が「F01部品マスタM~」となっている下半分の3つがメインフォームで、こちらに検索用の機能を実装しています。
上半分の「F01部品マスタDS~」はデータシートフォームで、部品マスタのデータを表示させるためのサブフォームです。

本記事で学習するフォームは「F01部品マスタM_01_Single」です。
他のフォームについては次回詳しく解説します。

では、対象のフォーム「F01部品マスタM_01_Single」を開きましょう。
1つのコンボボックス、検索と検索クリアのボタンが設置されています。

大分類マスタのコンボボックスを選ぶと、大分類マスタに登録されているデータの選択が可能です。

大分類の「機械部品」を選択後、検索を実行します。

検索条件に合致した商品のみが表示されました。

レコードセレクタを確認すると、検索前は119件だったのですが、検索後は25件だけに絞られています。

また、「検索クリア」をクリックすることで、検索前の状態に戻すことができます。

今回の動作をGIF動画にまとめて下に掲載しておきます。
矢印(カーソル)は見えませんが、大まかな動きはイメージできるかと思います。

プログラムの中身を確認

VBEを起動させ、「F01部品マスタM_01_Single」のコードを表示させます。
対象のオブジェクトを直接ダブルクリックしてもいいですし、右クリック後に「コードを表示」を選択してもよいです。

フォームの中には4つのイベントプロシージャが入っています。

  • Form_Load() ⇒ フォームを開く
  • 検索_Click() ⇒ 検索ボタンをクリック
  • 検索クリア_Click() ⇒ 検索クリアボタンをクリック
  • 戻る_Click() ⇒ 戻るボタンをクリック

検索に関係する上3つのプロシージャの中身を見ていきましょう。

イベントプロシージャの解説

フォームを開いた時 : レコードセレクタとRouSourceを設定

フォームを開いた時に自動的に作動するプログラム『Form_Load()』のコードです。

Private Sub Form_Load()

    Me.RecordSelectors = False ' レコードセレクタを非表示にする
    Me.NavigationButtons = False ' 移動ボタンを非表示にする
    
    '分類選択の設定
    Me.大分類選択.RowSourceType = "Table/Query"
    Me.大分類選択.RowSource = "SELECT 大分類名 FROM T00大分類マスタ;"
    Me.大分類選択.Value = ""
    
    'データシートフォームの範囲設定
    Me.F01部品マスタDS_01_Single.Form.RecordSource = "SELECT * FROM Q01部品マスタ表示用;"
    
End Sub

上の動作をプロパティウインドウでも設定できますが、今後のメンテナンスのことを考えるとVBEに書き残した方がおすすめです。


では、一つずつ分解して解説します。

前半部分では、メインフォームのレコードセレクタなどを無効にします。

    Me.RecordSelectors = False ' レコードセレクタを非表示にする
    Me.NavigationButtons = False ' 移動ボタンを非表示にする

仮に、設定がデフォルト(True)のままだと、どんな状態なのでしょうか?
フォームの下端に、レコード番号表示と検索窓が残ったままです。

非表示(False)に設定することで、表示を隠してよりスッキリした画面に仕上がります。

Trueの状態でもAccessデータベースの使い勝手は特に変わりませんが、メインフォームにレコード移動や検索は不要です。
不要な機能はできるだけ表面に出さず、必要な情報にした方が、ユーザーにとって親切な画面構成だと言えるでしょう。

では、後半のコンボボックスのリストを再設定するコードです。

    '分類選択の設定
    Me.大分類選択.RowSourceType = "Table/Query"
    Me.大分類選択.RowSource = "SELECT 大分類名 FROM T00大分類マスタ;"
    Me.大分類選択.Value = ""

サンプルデータベースでは、RowSourceTypeをTable/Query(テーブル・クエリ)で設定しています。
そんな時は必ずSQL文でRowSourceを設定しましょう。

一般的によく使われるのは、マスタデータをそのままSELECT文で表現する方法です。
更にユーザーに親切なリストを設けたい場合は、DISTINCT文を使って明細データのみに含まれる項目だけをリスト化することも可能です。
DISTINCT文については当ブログでも解説していますので、よかったらのぞいてみてください。

https://sys-daddy.com/lesser-known-sql-of-access/

また、ここではコンボボックスの値は空欄にしていますが、ユーザーに初期値だと判別できるように、「全て」など特定の文字列を表示させるのもアリです。

他にはRowSourceTypeにValue(値)を使う方法もあります。
Valueを設定した場合は、AddItemメソッドでRowSourceを一つずつ追加します。

以下はサブフォームのレコードソースを設定するコードで、サブフォームに全レコードをデフォルト設定させています。

    'データシートフォームの範囲設定
    Me.F01部品マスタDS_01_Single.Form.RecordSource = "SELECT * FROM Q01部品マスタ表示用;"

RowRourceと同じく、SQL文を積極的に使用しましょう。

検索ボタンを押した時(RecordSourceの変更)

検索ボタンを押した時に作動するコードです。

Private Sub 検索_Click()

    If Me.大分類選択.Value <> "" Then
        Me.F01部品マスタDS_01_Single.Form.RecordSource = "SELECT * FROM Q01部品マスタ表示用 WHERE 大分類名 ='" & Me.大分類選択.Value & "';"
    Else
        Me.F01部品マスタDS_01_Single.Form.RecordSource = "SELECT * FROM Q01部品マスタ表示用;"
    End If
    
End Sub

コンボボックスの値をSQL文のWhere句に設定します。
もしコンボボックスが空欄の場合、全てのデータがを表示するようになっています。

検索クリアボタンを押した時(RecordSourceをリセット)

検索クリアボタンをクリックしたときに作動するコードです。

Private Sub 検索クリア_Click()

    Me.F01部品マスタDS_01_Single.Form.RecordSource = "SELECT * FROM Q01部品マスタ表示用;"
    Me.大分類選択.Value = ""

End Sub

コンボボックスとサブフォームを初期状態に戻します。

複数のコンボボックスを使う方法

本記事では、シンプルに一つのコンボボックスで検索をかける方法を解説していますが、実務では複数のコンボボックスを使う機会が多いです。

3つのコンボボックスを使って検索する方法についてはこちらの記事で解説しています。

https://sys-daddy.com/access-vba-combo-box-data-search2/

RecordSourceを安全に扱うためのチェックポイント

RecordSourceを使った検索はとても便利ですが、SQL文の書き方を誤ると正しいデータが表示されないことがあります。
実務で安定して使うためには、次の3つのチェックポイントを意識しておきましょう。

  • Where句の囲み文字を正しく使用する(文字列・数理・日付)
  • Null値や空文字を考慮して条件を組み立てる
  • Requeryを忘れずに実行する

RecordSourceを安全に設定するためには、基本的なSQL文を正しく書けることが前提になります。
特にWHERE句では、データ型に応じて囲み文字が異なります。

  • 文字列 → クォート(’)
  • 日付 → シャープ(#)
  • 数値 → なし

コンボボックスやテキストボックスが未入力のままSQL文が作成されることも想定しておかなければいけません。
入力チェックも入れると、より精度高くRecordSourceを設定できるでしょう。

RecordSourceを更新しただけではフォームの内容は切り替わりません。
最後に Me.Requery を実行して、最新のデータを再表示する必要があります。

もしサブフォームを再描画したい場合は、
Me!サブフォーム名.Form.Requery のように対象フォームを指定します。

まとめ

今回は、Accessフォームのコンボボックスを使ってデータを検索するVBAプログラミングについて解説しました。

コンボボックスを使ったデータ検索はAccessではよく使う機能で、開発者でない一般ユーザーでも直観で操作できるので、利用者の生産性向上に貢献できます。

また、本記事でも解説しましたが、SQL文を使ってコンボボックスやサブフォームの範囲を設定できるようになっておくことがとても大事です。
基礎をしっかりと身につければ、コンボボックスの数が増えても容易に対応できます。

本記事の内容を現場で有効にいかしていただければうれしいです。