この特集のトップページへ
Chapter 7:プレゼンテーション層の構築

7.4.6 顧客の検索
●[検索]ボタンが押されたときの処理
 では次に,ユーザーがFig.7-37COMBO_SEARCHFIELDコンボボックスから検索列を選択し,TXT_SEARCHテキストボックスに検索文字列を入力し,BTN_SEARCHボタン([検索]ボタン)を押したときに,その条件と合致するレコードにマーキーを合わせる処理を実装する。

○文字列の検索
 条件と合致するレコードにマーキーを合わせるということはつまり,条件と合致するレコードをカレントレコードにするということである。この処理自体は,すでに説明したADODB.RecordsetオブジェクトのFindメソッドを使えば実現できる。

 たとえば,ユーザーがCOMBO_SEARCHFIELDコンボボックスで“顧客名”という列(顧客情報テーブルのNAMEフィールドに相当する)を選択し,TXT_SEARCHテキストボックスに“ソフトバンク”と入力し,また,検索方向として“下”(OPT_DOWNラジオボタン)を選択したとする。DGrid_Customerデータグリッドが表示しているADODB.Recordsetオブジェクトはグローバル変数g_objRecに保存されているから,次のようにFindメソッドを呼び出せば,その時点のカレントレコードから下に向かって条件と合致するレコードを検索し,それをカレントレコードとすることができる。

g_objRec.Find "NAME='ソフトバンク'", _
              1, adSearchForward

 ただしこの場合,NAMEフィールドの値とユーザーが入力した値である“ソフトバンク”とが完全に一致しなければ,見つかったことにならない。ユーザーの利便性を考えると,完全一致ではなく,「入力された文字列から始まるもの」を検索の対象にしたほうがよいと思われる。そのような部分一致検索を実現するには,“=”演算子の代わりに“like”演算子を使えばよい。たとえば,次のようにする。

g_objRec.Find "NAME like 'ソフトバンク*'", _
              1, adSearchForward

 “*”は任意の1文字以上にマッチする特別な値で,上記のようにすると,NAMEフィールドの値が“ソフトバンク”から始まるものを検索の対象とする。すなわちこの条件では,“ソフトバンク”以外に“ソフトバンクパブリッシング”“ソフトバンクジーディーネット”などもマッチすることになる。


One Point!like演算子は,SQLのSELECT文におけるWHERE句でも使うことができる。ただし,SELECT文でlike演算子を使うときには,パターンマッチングの文字列として“*”ではなく“%”を用いる(ADOのドキュメントには明記されていないが,ADODB.RecordsetオブジェクトのFindメソッドでも,“*”の代わりに“%”を使用できる)。

One Point!like演算子を使うとき,“NAME like '*ソフトバンク*'”のように検索対象文字列の前後に“*”を指定すると,NAMEフィールドの一致条件は「任意の文字列で始まり,あいだに“ソフトバンク”という文字列が含まれ,任意の文字で終わるもの」となる。つまりこれは,「NAMEフィールドの値に“ソフトバンク”という文字列が含まれるもの」を意味する。ただし,ADODB.RecordsetオブジェクトのFindメソッドにおいては,“*”は,先頭だけに指定したりあいだだけに指定したりすることはできない(SQLのSELECT文においてはその書式は許される)。たとえば,“NAME like '*ソフトバンク'”として,末尾が“ソフトバンク”で終わるものを検索条件としたり,“NAME like 'ソ*ク'”のように“ソ”で始まり“ク”で終わるものを検索条件としたりすることはできないのである。これは,FindメソッドがOLE DBの検索機能を使っているためである。OLE DBの検索機能は,「ある特定の文字列から始まるもの」か「ある特定の文字列を含むもの」しか検索することできない仕様になっているため,そのような制限が生じる。

 このように,like演算子を使えば,ある文字列から始まる値を検索するという処理を実現できる。一般に,ユーザーが入力する文字列というのは完全な情報ではない。うろ覚えで入力されたり,入力の手間を省くために省略されたりすることもある。そのため,完全に一致するものを検索の対象とするよりも,ユーザーが先頭からいくつかの文字を入力すれば,その文字列から始まるものを検索する,といった仕様にしたほうが使い勝手がよいと思われる。そこで今回は,=演算子を使った完全一致ではなく,like演算子を使った部分一致を採用することにしよう。


One Point! より利便性を高めるならば,ユーザーが入力した値をある程度まで正規化して検索することも考えるとよい。たとえば,全半角の同一視,ひらがなとカタカナの同一視,顧客名の前後に付くことが予想される「(株)」や「(有)」といった語句の有無の同一視,などである。しかし,これらを同一視する処理をADODB.RecordsetオブジェクトのFindメソッドの機能だけで実現するのは困難なので,今回は割愛させていただく。これらを同一視したいのであれば,データベースに書き込む時点で,(1)全角文字はすべて半角文字にしてから格納する,(2)ひらがなはカタカナに変換してから格納する,……といった具合に正規化して書き込み,検索するときにも正規化したものをFindメソッドの値として引き渡す,といった実装が必要となるだろう。しかし実際には,ユーザーが入力したデータのうち,ひらがなをカタカナに強制的に書き換えてデータベースに格納するといった処理は,ユーザーの意図を反映せず好ましくない(たとえば,会社名などは固有名詞であるから,勝手にひらがなをカタカナに書き換えてしまうことは許されないはずである)。そのため,データを格納するフィールドとは別に検索用のフィールドをデータベーステーブルに用意して,そこに検索用の正規化されたデータを書き込むという手法をとることになるだろう。
prevpg.gif Chapter 7 31/65 nextpg.gif