VBでパラメータクエリのパラメータを指定したい

解決


ちきゆう  2004-11-19 18:48:59  No: 86764

アクセス2000で選択クエリを使ってレポートを作成しました。このレポートをVB6.0から出力できるようにしています。現状ですとデータが全件出力されてしまうのでパラメータクエリで抽出しようと思うのですが、そのパラメータをVB側のテキストボックスなどに入力してアクセス側へ受け渡したいのです。どうすればよいのでしょうか?よろしくお願い致します。


魔界の仮面弁士  2004-11-19 19:50:25  No: 86765

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

のように書く事ができます。


ちきゆう  2004-11-19 20:28:12  No: 86766

回答かなり感謝しております。実行してみたのですがエラーで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
としました。全然見当違いのことをしてるのでしょうか?


魔界の仮面弁士  2004-11-20 00:17:36  No: 86767

> 現状としましてはアクセスに”Q1”という名前のクエリを作成しまして、
(中略)
> MyQuery = "Between [開始コードを入力してください。:] And [終了コードを入力してください。:]"
(中略)
> cn.MyQuery 1, 100, RS

違います。クエリ名は Q1 ですから、
  cn.Q1 1, 100, RS
のようになります。


ちきゆう  2004-11-20 02:50:59  No: 86768

魔界の仮面弁士さん
レスありがとうございます。上記のように修正したのですが、どうも
cn.Q1 1, 100, RS  のパラメータはアクセス側には渡っていないようです。
現にアクセス側で実行したときに開始コードを入力してください。というメッセージがVBで実行したときもでてきてしまいます。


魔界の仮面弁士  2004-11-20 03:29:15  No: 86769

> 開始コードを入力してください。というメッセージが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 オブジェクトを使った場合は、
  正しく動作するのでしょうか?


ちきゆう  2004-11-20 04:04:01  No: 86770

ご迷惑かけてすいません。
(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


魔界の仮面弁士  2004-11-20 07:50:25  No: 86771

レポートのデータソース自体が、パラメータクエリになっているのですか。
だとすると、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


ちきゆう  2004-11-21 01:17:55  No: 86772

ワークテーブルを使うのは効率的でないので
oleAccess.CurrentDb.CreateQueryDef "クエリ名", SQL文
を使ってできました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加