MS Access 2003 でパラメータ化されたクエリを作成し、特定のフォーム要素の値をそのクエリにフィードして、対応する結果セットを取得し、それらを使用していくつかの基本的な計算を実行できるようにしたいと考えています。フォーム要素によって入力されるクエリのパラメーターを取得する方法を理解するのに、私は不足しています。VBA を使用する必要がある場合は、それで問題ありません。
5 に答える
フォーム上のコントロールへの参照は、Access クエリで直接使用できますが、それらをパラメーターとして定義することが重要です (そうしないと、最近のバージョンの Access での結果が、以前は信頼できたものから予測不能になる可能性があります)。
たとえば、MyForm の LastName コントロールでクエリをフィルター処理する場合は、これを条件として使用します。
LastName = Forms!MyForm!LastName
次に、フォーム参照をパラメーターとして定義します。結果の SQL は次のようになります。
PARAMETERS [[Forms]!MyForm![LastName]] Text ( 255 );
SELECT tblCustomers.*
FROM tblCustomers
WHERE tblCustomers.LastName=[Forms]![MyForm]![LastName];
ただし、この目的のためにクエリを保存する必要がある理由をお尋ねします。結果に対して何をしていますか?それらをフォームまたはレポートに表示しますか? その場合は、フォーム/レポートのレコードソースでこれを行い、保存したクエリをパラメーターに変更しないでおくことができます。これにより、プロンプトをポップアップしてパラメーターを入力することなく、他のコンテキストで使用できます。
一方、コードで何かをしている場合は、その場で SQL を記述し、フォーム コントロールのリテラル値を使用して WHERE 句を作成します。
コードのスニペットを次に示します。パラメータ txtHospital を使用してテーブルを更新します。
Set db = CurrentDb
Set qdf = db.QueryDefs("AddHospital")
qdf.Parameters!txtHospital = Trim(Me.HospName)
qdf.ReturnsRecords = False
qdf.Execute dbFailOnError
intResult = qdf.RecordsAffected
SQL のサンプルを次に示します。
PARAMETERS txtHospital Text(255);
INSERT INTO tblHospitals (
[Hospital] )
VALUES (
[txtHospital] )
この問題を回避するには、次の 3 つの従来の方法があります。
- パラメーターに何かクリーバーという名前を付けて、クエリの実行時にユーザーが値を入力するように求められるようにします。
- フォームの参照フィールド (おそらく非表示)
- その場でクエリを作成し、パラメーターを使用しないでください。
[?enter ISO code of the country]
フォームに次のようなものやフィールドへの参照を挿入する必要があるのは、私には間違っていると思います: [Forms]![MyForm]![LastName]
。
つまり、同じクエリを複数の場所で再利用したり、異なるフィールドにデータを提供したり、クエリの実行時にデータ入力を汚さないようにユーザーに頼らなければならないことを意味します。思い出すと、ユーザーが入力したパラメーターで同じ値を複数回使用するのは難しい場合があります。
通常、私は最後のオプションを選択してその場でクエリを作成し、必要に応じてクエリ オブジェクトを更新しました。ただし、これは SQL インジェクション攻撃 (偶発的または意図的に私のユーザーを知っている) に蔓延しており、厄介です。
だから私はいくつかの掘り下げを行い、ここで以下を見つけました( http://forums.devarticles.com/microsoft-access-development-49/pass-parameters-from-vba-to-query-62367.html ):
'Ed. Start - for completion of the example
dim qryStartDate as date
dim qryEndDate as date
qryStartDate = #2001-01-01#
qryEndDate = #2010-01-01#
'Ed. End
'QUOTEING "stallyon": To pass parameters to a query in VBA
' is really quite simple:
'First we'll set some variables:
Dim qdf As Querydef
Dim rst As Recordset
'then we'll open up the query:
Set qdf = CurrentDB.QueryDefs(qryname)
'Now we'll assign values to the query using the parameters option:
qdf.Parameters(0) = qryStartDate
qdf.Parameters(1) = qryEndDate
'Now we'll convert the querydef to a recordset and run it
Set rst = qdf.OpenRecordset
'Run some code on the recordset
'Close all objects
rst.Close
qdf.Close
Set rst = Nothing
Set qdf = Nothing
(私はそれを自分でテストしていません。旅行中に集めたものです。たまにこれをやりたいと思っていたのですが、前述のクラッジの1つを使用してしまいました)
編集 私はついにこれを使用する理由がありました。これが実際のコードです。
'...
Dim qdf As DAO.QueryDef
Dim prmOne As DAO.Parameter
Dim prmTwo As DAO.Parameter
Dim rst as recordset
'...
'open up the query:
Set qdf = db.QueryDefs("my_two_param_query") 'params called param_one and
'param_two
'link your DAP.Parameters to the query
Set prmOne = qdf.Parameters!param_one
Set prmTwo = qdf.Parameters!param_two
'set the values of the parameters
prmOne = 1
prmTwo = 2
Set rst = qdf.OpenRecordset(dbOpenDynaset, _
dbSeeChanges)
'... treat the recordset as normal
'make sure you clean up after your self
Set rst = Nothing
Set prmOne = Nothing
Set prmTwo = Nothing
Set qdf = Nothing
例を見てみましょう。パラメータ化されたクエリは次のようになります。
Select Tbl_Country.* From Tbl_Country WHERE id_Country = _
[?enter ISO code of the country]
この値 ([?enter ... country] の値) を、コントロールといくつかのデータを含むフォームから取得できるようにしたいと考えています。まあ...これは可能かもしれませんが、コードの正規化が必要です。
1 つの解決策は、値fid_Country
を保持するコントロールなど、特定のロジックに基づいてフォーム コントロールに名前を付けることです。id_Country
次に、クエリを文字列として持つことができます。
qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = [fid_country]"
要求されたすべてのデータをフォームに入力したら、「クエリ」ボタンを押します。ロジックはすべてのコントロールを参照し、それらがクエリに含まれているかどうかを確認し、最終的にパラメーターをコントロールの値に置き換えます。
Dim ctl as Control
For each ctl in Me.controls
If instr(qr,"[" & ctl.name & "]") > 0 Then
qr = replace(qr,"[" & ctl.name & "]",ctl.value)
End if
Next i
そうすることで、パラメーターが実際のデータに置き換えられた、完全に更新されたクエリが作成されます。fid_country のタイプ (文字列、GUID、日付など) に応じて、次のような最終的なクエリを取得するために、いくつかの追加の二重引用符を追加する必要がある場合があります。
qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = ""GB"""
レコードセットを開くために使用できる Access と完全に互換性のあるクエリは次のとおりです。
Set rsQuery = currentDb.openRecordset(qr)
ここで完了だと思います。
このテーマは、目的が Access アプリケーションの開発である場合に重要です。GUI からデータをクエリする標準的な方法をユーザーに提供する必要があります。クエリを起動するだけでなく、連続したフォームをフィルター処理し (Excel が "オートフィルター" オプションで行うのと同じように)、レポート パラメーターを管理する必要があります。幸運を!