web-dev-qa-db-ja.com

多くの接続を作成するVBAを使用したExcel2010のクエリテーブル(QueryTables)

別のサイトで見つけたコードをフォローしています。これが私のコードの基本です:

Dim SQL As String
Dim connString As String

connString = "ODBC;DSN=DB01;UID=;PWD=;Database=MyDatabase"
SQL = "Select * from SomeTable"

With Worksheets("Received").QueryTables.Add(Connection:=connString, Destination:=Worksheets("Received").Range("A5"), SQL:=SQL)
.Refresh

End With

End Sub

これを行う際の問題は、これに割り当てられたボタンを押すたびに、新しい接続が作成され、ドロップされないように見えることです。テスト後にスプレッドシートを開くと、[接続]の下にリストされている接続の多くのバージョンがあります。接続接続1接続2

接続を閉じたり削除したりする方法も見つからないようです。 「.Refresh」の後に「.delete」を追加すると、1004エラーが発生します。データがバックグラウンドで更新されているため、この操作は実行できません。

接続を閉じるまたは削除する方法はありますか?

5
DavidStein

コードで毎回QueryTableを作成している理由を自問するかもしれません。それを行う理由はありますが、通常は必要ありません。

QueryTablesは、より一般的には設計時のオブジェクトです。つまり、(コードまたはUIを介して)QueryTableを1回作成し、QueryTableを更新して更新されたデータを取得します。

基になるSQLステートメントを変更する必要がある場合は、いくつかのオプションがあります。値の入力を求めるパラメータを設定するか、セルから取得することができます。 SQLを変更するための別のオプションは、既存のQueryTableのコードでSQLを変更することです。

Sheet1.QueryTables(1).CommandText = "Select * FROM ...."
Sheet1.QueryTables(1).Refresh

CommandTextを変更することで、異なる列または異なるテーブルを選択できます。別のデータベースの場合は、新しい接続が必要になりますが、それは非常にまれです。

それがあなたの質問に直接答えないことは知っていますが、毎回本当にQueryTableを追加する必要があるかどうかを判断することが最初のステップだと思います。

パラメータの詳細については、 http://dailydoseofexcel.com/archives/2004/12/13/parameters-in-Excel-external-data-queries/ 2003年のものであるため、矛盾はほとんどありません。それ以降のバージョンでは。基本は同じです。2007以降を使用している場合は、ListObjectオブジェクトについて学ぶ必要があるかもしれません。

9
Dick Kusleika

私も同じ問題を抱えていました。正しい方向への明確な一歩を踏み出した前の答えはPITAです。

しかし、それは私が私の検索を絞り込むことを可能にしました、そして勝者は...

http://msdn.Microsoft.com/en-us/library/bb213491(v = office.12).aspx

つまり、既存のQueryTableオブジェクトの場合は、次のようにします。

.MaintainConnection = False

作品はこれまでにないほど膨らみます。データが更新された後、DBロックファイルにアクセスする必要はありません。

7
Yotool

デフォルトでは、この方法で作成された新しい接続は「接続」と呼ばれることがわかりました。私が使用しているのは、接続を削除するがリストオブジェクトを保持するためのこのコードスニペットです。

Application.DisplayAlerts = False
ActiveWorkbook.Connections("Connection").Delete
Application.DisplayAlerts = True

最近追加された接続を削除するように簡単に変更できます(または、接続をインデックスで追跡する場合)。

Application.DisplayAlerts = False
ActiveWorkbook.Connections(ActiveWorkbook.Connections.Count).Delete
Application.DisplayAlerts = True

addメソッドを使用して別のクエリテーブルを追加する代わりに、接続のCommandTextプロパティを更新するだけです。ただし、ODBC接続のCommandTextプロパティを更新するときにバグがあることに注意する必要があります。一時的にOLEDB接続に切り替える場合は、CommandTextプロパティを選択してから、ODBCに切り替えても、新しい接続は作成されません。理由を聞かないでください...これは私にとってはうまくいきます。

新しいモジュールを作成し、次のコードを挿入します。

Option Explicit

Sub UpdateWorkbookConnection(WorkbookConnectionObject As WorkbookConnection, Optional ByVal CommandText As String = "", Optional ByVal ConnectionString As String = "")

With WorkbookConnectionObject
    If .Type = xlConnectionTypeODBC Then
        If CommandText = "" Then CommandText = .ODBCConnection.CommandText
        If ConnectionString = "" Then ConnectionString = .ODBCConnection.Connection
        .ODBCConnection.Connection = Replace(.ODBCConnection.Connection, "ODBC;", "OLEDB;", 1, 1, vbTextCompare)
    ElseIf .Type = xlConnectionTypeOLEDB Then
        If CommandText = "" Then CommandText = .OLEDBConnection.CommandText
        If ConnectionString = "" Then ConnectionString = .OLEDBConnection.Connection
    Else
        MsgBox "Invalid connection object sent to UpdateWorkbookConnection function!", vbCritical, "Update Error"
        Exit Sub
    End If
    If StrComp(.OLEDBConnection.CommandText, CommandText, vbTextCompare) <> 0 Then
        .OLEDBConnection.CommandText = CommandText
    End If
    If StrComp(.OLEDBConnection.Connection, ConnectionString, vbTextCompare) <> 0 Then
        .OLEDBConnection.Connection = ConnectionString
    End If
    .Refresh
End With

End Sub

このUpdateWorkbookConnectionサブルーチンは、OLEDBまたはODBC接続の更新でのみ機能します。接続は必ずしもピボットテーブルにリンクする必要はありません。また、別の問題を修正し、更新できるようにします。同じ接続に基づく複数のピボットテーブルがある場合でも、接続。

更新を開始するには、次のような接続オブジェクトとコマンドテキストパラメータを使用して関数を呼び出すだけです。

UpdateWorkbookConnection ActiveWorkbook.Connections("Connection"), "exec sp_MyAwesomeProcedure"

オプションで、接続文字列を更新することもできます。

1
Brian Pressler

接続を個別のオブジェクトとして宣言する必要があります。データベースクエリが完了したら、接続を閉じることができます。

目の前にVBA IDEがないので、不正確な点があれば失礼しますが、正しい方向を示しているはずです。

例えば。

Dim SQL As String
Dim con As connection

Set con = New connection
con.ConnectionString = "ODBC;DSN=DB01;UID=;PWD=;Database=MyDatabase"

Worksheets("Received").QueryTables.Add(Connection:=con, Destination:=Worksheets("Received").Range("A5"), SQL:=SQL).Refresh

con.close
set con = nothing
1
st0000

数年後もまだ関係があります...同じ問題と戦っています。これはそこにある最も役立つスレッドです。私の状況は上記の変形であり、それを見つけたら解決策を追加します。

データソースにAccessデータベースを使用しており、新しいシートにクエリテーブルを作成しています。次に、さらに2つの新しいシートを追加し、それぞれで同じ接続を使用してクエリテーブルを確立しようとしますが、アクセステーブルは異なります。最初のquerytableは問題なく機能し、.QueryTables(1).Deleteを使用して、querytableオブジェクトをNothingに設定し、切断します。

ただし、次のシートは、閉じられていない同じ接続を使用して新しいクエリテーブルを確立できません。クエリテーブルを削除する前に接続を切断する必要があると思います(そして以下の解決策を追加します)。上記のRasmusのコードは、考えられる解決策のように見えます。

0
Jim Snyder

更新の直後に削除する場合は、バックグラウンドではなく更新を実行して(最初のパラメーター-> [Falseの更新]を使用)、適切な一連のアクションを実行する必要があります。

0
Kodak

QueryTable.MaintainConnectionプロパティをFalseに設定してみてください...

「指定したデータソースへの接続を更新後、ブックが閉じるまで維持する場合は、MaintainConnectionをTrueに設定します。デフォルト値はTrueです。このためのUIチェックボックスがないようです(読み取り/ブール値を書く)」

0
Leighton