アクセス2000で選択クエリを使ってレポートを作成しました。このレポートをVB6.0から出力できるようにしています。現状ですとデータが全件出力されてしまうのでパラメータクエリで抽出しようと思うのですが、そのパラメータをVB側のテキストボックスなどに入力してアクセス側へ受け渡したいのです。どうすればよいのでしょうか?よろしくお願い致します。
DAOで接続しているのであれば、DAO.QueryDefオブジェクトを。
ADOの接続しているのであれば、ADO.Commandオブジェクトを使ってみてください。
それぞれのParametersコレクション/Parameterオブジェクト経由で、
パラメータを渡す事ができます。
もしくは、Jetのクエリが「ストアドプロシージャ」として実行できる事から、
Connection.ストアド名 引数1, 引数2, 引数3, ……, Recordset変数
の構文を利用する事もできます。たとえば、
===========
PARAMETERS [Param1] INTEGER, [Param2] TEXT;
SELECT * FROM [Table1] WHERE ID > [Param1] AND [UserName] Like [Param2];
===========
というクエリを、MyQuery という名で保存しているとして、ここに、
Param1=200, Param2="魔界%" というパラメータを渡すために、
Dim Con As ADODB.Connection
Dim RS As ADODB.Recordset
:
Set RS = New ADODB.Recordset
Con.MyQuery 200, "魔界%", RS
のように書く事ができます。
回答かなり感謝しております。実行してみたのですがエラーでMyQueryが存在するか確かめてくださいとのエラーがでてしまいました。
現状としましてはアクセスに”Q1”という名前のクエリを作成しまして、その中に”コード”というフィールドがあるのですがそこの抽出条件に"Between [開始コードを入力してください。:] And [終了コードを入力してください。:]" という構文を記入してコードでの抽出を行なっています。
VBでの構文は
Dim Cn As ADODB.Connection
Dim RS As ADODB.Recordset
MyQuery = "Between [開始コードを入力してください。:] And [終了コードを入力してください。:]"
Set RS = New ADODB.Recordset
cn.MyQuery 1, 100, RS
としました。全然見当違いのことをしてるのでしょうか?
> 現状としましてはアクセスに”Q1”という名前のクエリを作成しまして、
(中略)
> MyQuery = "Between [開始コードを入力してください。:] And [終了コードを入力してください。:]"
(中略)
> cn.MyQuery 1, 100, RS
違います。クエリ名は Q1 ですから、
cn.Q1 1, 100, RS
のようになります。
魔界の仮面弁士さん
レスありがとうございます。上記のように修正したのですが、どうも
cn.Q1 1, 100, RS のパラメータはアクセス側には渡っていないようです。
現にアクセス側で実行したときに開始コードを入力してください。というメッセージがVBで実行したときもでてきてしまいます。
> 開始コードを入力してください。というメッセージがVBで実行したときもでてきてしまいます。
あれれ。VB側でもメッセージが出てきますか…。
(Access VBAではなく、VBなのですよね?)
そのメッセージは、Accessが出すメッセージなので、Access VBAならばともかく、
VBでは出てくるというのは、ちょっと奇妙に思えます。
# 『パラメータが少なすぎます。(個数)を指定してください。』という
# パラメータ不足によるエラーなら、VBでも発生するかも知れませんが、
# その場合でも、Accessのような入力画面にはならなかったような…。
ちょっと2点ほど確認させてください。
(1) Q1が必要とするパラメータは、幾つありますか?
パラメータが2つだけなら、
cn.Q1 引数1, 引数2, RS
ですし、5つあるなら、
cn.Q1 引数1, 引数2, 引数3, 引数4, 引数5, RS
のように呼び出す事になります。
(アクションクエリの場合は、最後のRSは指定しません)
この時、Q1が他のクエリを参照している場合は、参照先のクエリ側が
必要としているパラメータも、あわせて指定する必要があります。
(2) Connection のメソッドとして呼び出す手法の替わりに、
先に書いた ADODB.Command オブジェクトを使った場合は、
正しく動作するのでしょうか?
ご迷惑かけてすいません。
(1) Q1が必要とするパラメータは、幾つありますか?
2つです。
(2) Connection のメソッドとして呼び出す手法の替わりに、
先に書いた ADODB.Command オブジェクトを使った場合は、
正しく動作するのでしょうか?
もう一度細かく今やっていることを書きます。
アクセス2000でクエリ(Q1とします。)とレポート(R1とします。)を作成しました。Q1は選択クエリで3つのテーブルから作成されています。(T1,T2,T3)とします。 R1はQ1を使って作成しました。(R1のプロパティのレコードソースという項目がQ1になっています。) Q1で”コード”というフィールドがあるのですがそこの抽出条件には Between[開始コードを入力してください] And [終了コードを入力してください] という命令文を記入しています。
これでレポートを開いた際に開始コードと終了コードを入力するボックスがでてきて当てはまるもののみレポート出力できるようにされています。
以上がアクセス側の現状です。
この動作をVB側から行ないたいのですが 開始コードと終了コードをあらかじめフォーム内のテキストボックスなんかに入力してコマンドボタンを押すとその範囲で抽出してレポートを出力できるようにしたいのです。
VB側のコードは現在こんなかんじです。このコードですとアクセス側でレポートを開いたときと同じようにパラメータ(開始コードと終了コード)を求めてきます。
On Error GoTo ErrorHandler
Dim Cn As ADODB.Connection
Dim RS As ADODB.Recordset
Set RS = New ADODB.Recordset
cn.Q1 1, 100, RS
'戻り値を初期化
AcPrint = True
'指定項目のチェック
If Len(DbName) = 0 Then
MsgBox "データベース名を指定して下さい。", vbOKOnly, "AcPrint Ver.1.1"
AcPrint = False
End If
If Len(ReportName) = 0 Then
MsgBox "レポート名を指定して下さい。", vbOKOnly, "AcPrint Ver.1.1"
AcPrint = False
End If
'Accessファイルを開く
Set oleAccess = Nothing
Set oleAccess = New Access.Application
oleAccess.OpenCurrentDatabase DbName, False
'Accessのレポートを開く
Select Case PrintMode
Case 0 'Preview
oleAccess.DoCmd.OpenReport ReportName, acPreview
oleAccess.DoCmd.Maximize
oleAccess.Visible = True
Case 1 'Print
oleAccess.DoCmd.OpenReport ReportName, acNormal
oleAccess.CloseCurrentDatabase
Set oleAccess = Nothing
Case Else
MsgBox "モードが誤っています。", vbOKOnly, "AcPrint Ver.1.1"
oleAccess.CloseCurrentDatabase
Set oleAccess = Nothing
AcPrint = False
End Select
Exit Function
'エラー処理
ErrorHandler:
Select Case Err.Number
Case 2202 'プリンタドライバ未インストール
MsgBox "プリンタドライバがインストールされていません。" & Chr$(13) & "プリンタドライバをインストールして下さい。", vbOKOnly, "AcPrint Ver.1.1"
Case 2455 '切り替え時の対応
Exit Function
Case 7866 'ファイルが見つからない
MsgBox "ファイルが見つかりません。" & Chr$(13) & "パス、ファイル名の確認、使用可能なファイルかを確認して下さい。", vbOKOnly, "AcPrint Ver.1.1"
Case Else
MsgBox "エラーNo:" & Err.Number & Chr$(13) & Err.Description, vbOKOnly, "AcPrint Ver.1.1"
End Select
AcPrint = False
End Function
レポートのデータソース自体が、パラメータクエリになっているのですか。
だとすると、ADOからの操作では無理ですね…。
(レポートはAccess側の機能なので、ADOからは制御できませんし)
逃げの手になってしまいますが、パラメータクエリを使うのを止めて、
条件指定用のワークテーブルを作成してみては如何でしょうか。
たとえば、Q1クエリ側は
WHERE [コード] BETWEEN DFIRST("P1", "T1") And DFIRST("P2", "T1")
のようにしておき、これに対応するワークテーブルとして、
CREATE TABLE T1 (P1 INTEGER, P2 INTEGER)
のような物を用意しておき、VB側から呼ぶときは、こんな感じにするとか。
Set Cn = oleAccess.CurrentProject.Connection
Cn.BeginTrans
Cn.Execute "DELETE FROM T1"
Cn.Execute "INSERT INTO T1 VALUES(1, 100)"
Cn.CommitTrans
Set Cn = Nothing
oleAccess.DoCmd.OpenReport ReportName, acPreview
ワークテーブルを使うのは効率的でないので
oleAccess.CurrentDb.CreateQueryDef "クエリ名", SQL文
を使ってできました。
ツイート | ![]() |