繁体   English   中英

具有VBA的Excel 2010中带有VBA的Excel 2010中的查询表(QueryTables)

[英]Query Tables (QueryTables) in Excel 2010 with VBA with VBA creating many connections

我正在跟踪在另一个站点上找到的代码。 这是我的代码的基础:

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错误。 由于数据在后台刷新,因此无法执行此操作。

任何想法如何关闭或删除连接?

您可能会问自己,为什么每次在代码中都创建QueryTable。 有理由这样做,但是通常没有必要。

QueryTables通常是设计时对象。 也就是说,您一次创建了QueryTable(通过代码或UI),然后刷新了QueryTable以获取更新的数据。

如果需要更改基础SQL语句,则可以选择一些方法。 您可以设置提示输入值或从单元格获取值的参数。 更改SQL的另一种方法是更改​​现有QueryTable的代码。

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对象。

我遇到过同样的问题。 向正确方向迈出明确一步的先前答案是PITA。

但是,它的确使我可以优化搜索范围,而获胜者是...

http://msdn.microsoft.com/zh-cn/library/bb213491(v=office.12).aspx

即对于您现有的QueryTable对象,只需执行以下操作:

.MaintainConnection = False

作品如此膨胀。 刷新数据后,不再有Access DB锁定文件。

我发现默认情况下以这种方式创建的新连接称为“连接”。 我正在使用的是这段代码以删除连接,但保留listobject。

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"

您也可以选择更新连接字符串。

您应该将连接声明为单独的对象,然后在数据库查询完成后就可以将其关闭。

我前面没有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

如果要在刷新后立即删除,则不应该在后台进行刷新(使用第一个参数->刷新为False),以便您有适当的操作顺序

尝试将QueryTable.MaintainConnection属性设置为False ...

“如果要在刷新后并在关闭工作簿之前保持与指定数据源的连接,请将MaintenanceConnection设置为True。默认值为True!而且似乎没有用于此的UI复选框(读/写布尔)”

几年后仍然有意义……与同一个问题作斗争,这是那里最有帮助的话题。 我的情况是上述情况的一种,我将在找到解决方案后添加解决方案。

我正在使用Access数据库作为数据源,并在新表上建立一个querytable。 然后,我再添加两个新的工作表,并尝试在每个工作表上使用相同的连接建立一个查询表,但将其连接到不同的Access表。 第一个查询表工作正常,我使用.QueryTables(1).Delete并将查询表对象设置为Nothing使其断开连接。

但是,下一张表无法使用未关闭的相同连接建立新的查询表。 我怀疑(并将在下面添加解决方案)在删除查询表之前需要断开连接。 上面的Rasmus的代码似乎是可能的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM