6

我正在关注我在另一个网站上找到的代码。这是我的代码的基础知识:

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

这样做的问题是每次他们点击分配给它的按钮时,它都会创建一个新连接并且似乎永远不会放弃它。我在测试后打开电子表格,在 Connections 下列出了许多版本的连接。连接 连接1 连接2

我似乎也找不到关闭或删除连接的方法。如果我在“.Refresh”之后添加“.delete”,我会收到 1004 错误。此操作无法进行,因为数据正在后台刷新。

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

4

8 回答 8

11

您可能会问自己,为什么每次都在代码中创建 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 对象。

于 2011-02-08T14:48:20.310 回答
7

我遇到过同样的问题。上一个答案虽然朝着正确方向迈出了明确的一步,但它是 PITA。

然而,它确实让我可以改进我的搜索,获胜者是......

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

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

.MaintainConnection = False

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

于 2011-08-04T02:39:18.363 回答
1

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

我面前没有 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
于 2011-02-07T21:09:19.530 回答
1

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

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

可以轻松修改它以删除最新添加的连接(或者如果您通过索引跟踪连接)。

Application.DisplayAlerts = False
ActiveWorkbook.Connections(ActiveWorkbook.Connections.Count).Delete
Application.DisplayAlerts = True
于 2012-06-19T12:30:20.813 回答
1

add您可以简单地更新连接的 CommandText 属性,而不是使用该方法添加另一个查询表。但是,您必须注意在更新CommandTextODBC 连接的属性时存在错误。如果您暂时切换到 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"

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

于 2015-06-25T15:53:55.327 回答
0

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

于 2012-08-20T08:12:45.567 回答
0

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

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

于 2014-02-20T00:29:23.667 回答
0

多年后仍然相关......解决同样的问题,这是最有用的线程。我的情况是上述情况的一种变体,我会在找到时添加我的解决方案。

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

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

于 2015-05-01T13:24:34.480 回答