さまざまな時間にさまざまな方法でフィルター処理したいクエリがあります。関連するクエリ フィールドの条件フィールドにパラメーターを配置することでこれを実行した方法ですが、特定のフィールドではなく、他のフィールドでのみフィルター処理したい場合が多くあります。クエリの特定の呼び出しのフィルタリングをバイパスできるように、ある種のワイルドカードを基準パラメーターに渡す方法はありますか?
6 に答える
次のようにクエリを作成する場合:
PARAMETERS ParamA Text ( 255 );
SELECT t.id, t.topic_id
FROM SomeTable t
WHERE t.id Like IIf(IsNull([ParamA]),"*",[ParamA])
パラメータが入力されていない場合は、すべてのレコードが選択されます。
*
キーワードを使用したワイルドカードはLIKE
、ANSI-89 クエリ モードでのみ目的の効果を持つことに注意してください。
多くの人が、Access/Jet のワイルドカード文字は常に * であると誤解しています。そうではありません。Jet には 2 つのワイルドカードがあります。ANSI-92 クエリ モードの % と ANSI-89 クエリ モードの * です。
ADO は常に ANSI-92 で、DAO は常に ANSI-89 ですが、Access インターフェイスはどちらでもかまいません。
データベース オブジェクト (つまり、mdb ファイルに永続化されるもの) で LIKE キーワードを使用する場合は、よく考えてください: 誰かがこのデータベースを、私が通常使用するものとは異なるクエリ モードを使用して使用するとどうなるでしょうか? テキスト フィールドを数字のみに制限したいとし、検証ルールを次のように記述したとします。
NOT LIKE "*[!0-9]*"
誰かが無意識のうちに (または別の方法で) ADO 経由で .mdb に接続した場合、上記の検証ルールにより、数値以外の文字を含むデータを追加することが許可され、データの整合性が失われます。良くない。
常に両方の ANSI クエリ モードをコーディングするほうがよい IMO。おそらく、これは両方のモードを明示的にコーディングすることで実現するのが最善です。
NOT LIKE "*[!0-9]*" AND NOT LIKE "%[!0-9]%"
しかし、より複雑な Jet SQL DML/DDL を使用すると、これを簡潔に実現するのが非常に難しくなる可能性があります。そのため、クエリ モードに関係なく、ANSI-92 クエリ モードのワイルドカード文字を使用する ALIKE キーワードを使用することをお勧めします。
NOT ALIKE "%[!0-9]%"
ALIKE は文書化されていないことに注意してください (これが、元の投稿がマークダウンされた理由だと思います)。これを Jet 3.51 (Access97)、Jet 4.0 (Access2000 から 2003)、および ACE (Access2007) でテストしたところ、問題なく動作しました。以前にこれをニュースグループに投稿し、Access MVP の承認を得ました。通常、私は文書化されていない機能を自分で避けますが、この場合は例外として、Jet は 10 年近く廃止されており、Jet を存続させている Access チームはエンジンに大きな変更 (またはバグ修正) を行うことに関心がないようです。 )、ジェットエンジンを非常に安定した製品にする効果があります。
Jet の ANSI クエリ モードの詳細については、「ANSI SQL クエリ モードについて」を参照してください。
前の質問の前の例に戻ります。パラメータ化されたクエリは、次のような文字列です。
qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = [fid_country]"
fid_Country の性質 (数値、テキスト、GUID、日付など) に応じて、ジョーカー値と特定の区切り文字に置き換える必要があります。
qr = replace(qr,"[fid_country]","""*""")
ワイルド カードを完全に許可するには、元のクエリを次のようにすることもできます。
qr = "Select Tbl_Country.* From Tbl_Country _
WHERE id_Country LIKE [fid_country]"
その後、次のような fid_Country のワイルド カード値を取得できます。
qr = replace(qr,"[fid_country]","G*")
それが完了したら、文字列を使用してレコードセットを開くことができます
set rs = currentDb.openRecordset(qr)
これが役立つかどうかはわかりません。VBAではなく保存されたクエリを使用してこれを実行したいと思うからです。ただし、実行できる最も簡単な方法は、VBAで行ごとにクエリを作成し、そこからレコードセットを作成することです。
非常にハックな方法は、保存されたクエリをその場で書き直してからアクセスすることです。ただし、同じDBを使用している人が複数いる場合は、競合が発生する可能性があり、次の開発者を混乱させる可能性があります。
プログラムでデフォルト値をクエリに渡すこともできます(前の質問で説明したように)
現在のフィルターで使用したくないフィールドのパラメーターとして * を渡すことで、null 以外の値を返すことができます。Access 2003 (およびおそらくそれ以前のバージョンとそれ以降のバージョン) でlike [paramName]
、数値、テキスト、日付、またはブール型フィールドの基準として を使用している場合、アスタリスクは (指定した他の基準に一致する) すべてのレコードを表示します。null 値も返したい場合はlike [paramName] or Is Null
、基準として使用して、すべてのレコードを返すことができます。(これは、コードでクエリを作成している場合に最適です。既存のクエリを使用していて、フィルタリングする値があるときに null 値を返したくない場合、これは機能しません。)
メモ フィールドをフィルタリングする場合は、別の方法を試す必要があります。
私はあなたができるとは思わない。どのようにクエリを実行していますか?
開いている変数がたくさんあるクエリが必要な場合は、それを vba モジュールまたはクラスに入れて呼び出し、毎回文字列を作成できるようにします。