MS Access Tips/Sample and VBA and Blog customize etc...

フォームに独自の検索機能を実装する

以前の記事、フォームの Recordset, RecorsetClone, RecordSet.Clone の違いとは? で、フォーム上の複数レコードを更新する場合は、RecordSet.Clone か更新クエリを利用するのが圧倒的に高速だというのを実験で確認しました。

では、Recordset, RecorsetClone には出番がないのでしょうか。それぞれの動作の違いは上の記事で考察しましたが、それを理解すれば適切な使い道はあります。

例えば、更新せずに別のレコードの値を持ってくるだけなら、RecorsetClone が最適でしょう。例えば、フォームで前レコードの値を複写する関数 では、RecorsetClone を使ってます。

検索機能のように特定のレコードへ移動したいというときは、Recordsetプロパティを使うとシンプルに記述できます。今回は、Recordsetプロパティを使用した検索機能の実装例です。

FrmSearch.png

難易度:

仕様

テーブル「社員」をレコードソースとするフォーム上に、フィールド名を選択するコンボボックス「cbFieldName」、検索条件を入力するテキストボックス「txtCriteria」、3個のコマンドボタン「cmdFindFirst」「cmdFindNext」「cmdFindPrevious」があるとします。検索条件には、>=, <=, Between And, などの演算子が使えます。また、テキスト型のフィールドなら曖昧検索の * 等のワイルドカード等が使えます。

数値型の条件例
>=100
<=40 Or >=80

日付型の設定例
2009/06/15
between 2009/06/15 And 2009/07/15

テキスト型の設定例
*ABC*
ABC*

コンボボックス「cbFieldName」

値集合タイプ フィールドリスト
値集合ソース 社員

フォームモジュール

ヘルプのサンプルやWEBで公開されいてるコードですと、RecordsetCloneを使った例が多いですが、Recordsetを使った方がコードがシンプルになります。ただし、RecordsetプロパティはAC2000から実装された物なので、AC97以前のバージョンではRecordsetCloneを使うことになります。

サンプルMDB が下記からダウンロードできます。
FrmSearch_07.zip (Access 2007-2010 形式 - 25kb)
FrmSearch.zip (Access 2002-2003 形式 - 25kb)
FrmSearch_2k.zip (Access 2000 形式 - 23kb)

拍手する

5 Comments

兵庫TERU says..."2か所で抽出したい(フォームに独自の検索機能を実装する)"

2か所で抽出をしたい時に、
対象フィールド①,検索条件①
対象フィールド②,検索条件② と項目をふやしたとします。
その時に、【次に検索】を押すと2つの項目で比較したいのですが上手くできません。
例)山本さんが沢山いて、福岡県の山本さんを抽出したいと思い
対象フィールド①・・・氏名  検索条件①・・・山本*
対象フィールド②・・・自宅都道府県  検索条件②・・・福岡*
と入力して、抽出したいのです。

Private Sub cmdFindNext_Click()
Dim rs As DAO.Recordset, criteria As String

On Error GoTo ErrorHandler

Set rs = Me.Recordset
criteria = BuildCriteria(Me.cbFieldName, rs(Me.cbFieldName).Type, Me.txtCriteria) And BuildCriteria(Me.cbFieldName2, rs(Me.cbFieldName2).Type, Me.txtCriteria2)
rs.FindNext criteria
If rs.NoMatch Then MsgBox "これより後に該当するデータはありません。"

Exit Sub
ErrorHandler:
MsgBox Err.Description

End Sub

で、実行すると
「型が一致しませんと出ます」

このようにandで繋げると思っていたのですが、違うみたいでした。
どうすればよろしいのでしょうか?

よろしくお願いします。

2017.02.27 15:45 | URL | #Yv5y4T.2 [edit]
兵庫TERU says..."もう一点"

現在、片方だけ入力して抽出すると、
「このコレクションには項目がありません」
【OK】
とエラーがでるので、こちらもクリアできるように教えてください。

よろしくお願いします。

2017.02.27 16:27 | URL | #Yv5y4T.2 [edit]
兵庫TERU says..."上記2点完了?"

hatenaさん、おはようございます、色々と勉強させていただいております。

下記のようにすることにより、質問していた2点はクリア出来たかと思います。

それと判定(hantei)の項目を追加しました。
判定には、AND/OR を入力します。

何かおかしなところはありますか?
またここはこのようにする方が良いよって思う所があれば教えてください。

Private Sub cmdFindNext3_Click()

Dim rs As DAO.Recordset, criteria As String
Dim criteria1 As String
Dim criteria2 As String

On Error GoTo ErrorHandler

Set rs = Me.Recordset
criteria1 = BuildCriteria(Me.cbFieldName, rs(Me.cbFieldName).Type, Me.txtCriteria)

If IsNull(Me![cbFieldName2]) Then
criteria = criteria1
Else
criteria2 = BuildCriteria(Me.cbFieldName2, rs(Me.cbFieldName2).Type, Me.txtCriteria2)
If Me![hantei] = "AND" Then
criteria = criteria1 & " AND " & criteria2
Else
criteria = criteria1 & " OR " & criteria2
End If
End If

rs.FindNext criteria
If rs.NoMatch Then MsgBox "これより後に該当するデータはありません。"

Exit Sub
ErrorHandler:
MsgBox Err.Description

End Sub

よろしくお願いします。

2017.02.28 10:25 | URL | #Yv5y4T.2 [edit]
hatena says..."re:上記2点完了?"

問題ないと思います。

最初の質問の型エラーはの原因は、

criteria = BuildCriteria(Me.cbFieldName, rs(Me.cbFieldName).Type, Me.txtCriteria) And BuildCriteria(Me.cbFieldName2, rs(Me.cbFieldName2).Type, Me.txtCriteria2)

だと、
BuildCriteriaが返すのは文字列ですので、
"文字列" AND "文字列"
ということになります。
AND演算子は論理演算子ですので、
AND 演算子の前後は、Boolean型(True/False)または数値型を返す式でないと駄目なので、
型エラーになります。

AND 演算子
https://msdn.microsoft.com/ja-jp/library/office/gg251591(v=office.15).aspx

文字列連結は &演算子です。

& 演算子
https://msdn.microsoft.com/ja-jp/library/office/gg264104.aspx

2017.02.28 23:06 | URL | #5uE6dEgY [edit]
兵庫TERU says..."ありがとうございました"

hatenaさん、ありがとうございました。

また分からない所があれば、教えてください。

2017.03.01 15:02 | URL | #Yv5y4T.2 [edit]

Leave a reply






Trackbacks

trackback URL
http://hatenachips.blog34.fc2.com/tb.php/128-c57c718a
該当の記事は見つかりませんでした。