2011-05-10 56 views
4

我有一個工作簿,其中包含由宏更新的數據透視表。該數據被刷新之前,雖然,連接字符串得到改變:使用Excel VBA更改連接字符串時創建的新數據連接

With ThisWorkbook.Connections("Data").ODBCConnection 
    .Connection = [Redacted] 
    .CommandText = "EXEC ExtractCases " & Client 
    .BackgroundQuery = False 
    .Refresh 
End With 

這似乎會導致數據透視表創建一個新的連接(或者叫做ConnectionData1,我似乎無法找出什麼它的確可以在它們之間做出選擇)並且指出這一點。所以,我再要補充線這樣的:

Sheets("Pivot").PivotTables("Pivot").ChangeConnection ThisWorkbook.Connections("Data") 
Sheets("Pivot").PivotTables("Pivot").PivotCache.Refresh 

這似乎工作(當它不除外),但留下了很多死連接工作簿敲周圍造成混亂。

我已經試過手動刪除Connection連接,但隨後突然名字本身Data1本身沒有明顯的原因,系統被打亂,因爲不存在Connection不能被刪除。

有什麼明顯的我做錯了嗎?是否有一些神奇的方法可以解決這個問題,所以它不會在第一個地方造成這種頭痛?

注意:我在Excel 2010中運行此代碼,但工作簿必須在2003年之前可以打開;然而,我在發佈之前刪除了VB模塊,所以2010宏的東西很好,只是在工作簿中的東西可能會被絆倒... ...

+0

成才的Theres我還不完全瞭解。你每次都改變(必須改變)連接嗎?或者由excel神奇地完成? – pintxo 2011-05-11 06:38:59

+0

@cmmi:我需要每次更改連接 - 這是一份針對我們公司的所有客戶端運行的報告,並且每次都只有該客戶端的數據。 – Margaret 2011-05-16 02:29:20

回答

3

我在Excel 2010中遇到過同樣的問題(可能是相同的早期版本,我不知道)。

我已經嘗試了與您相同的方法,即在編輯連接字符串的commandText後,更改了VBA代碼中的數據透視表的連接。和你一樣,我注意到有時候成功和其他時候失敗。

我還沒有找到問題出現的原因,以及上述方法在哪些情況下會導致成功或失敗。

我有,但是,找到一個有效的解決方案: 在你的VBA代碼,您需要執行上述命令如下步驟:

  1. 更改CommandText的(正如你知道的結果創建數據透視表正在使用的新的 連接)。
  2. 刪除舊的連接字符串。
  3. 將步驟1中的連接字符串重命名爲在步驟2中刪除的連接字符串的名稱。
  4. 刷新數據透視表。

注意:這隻適用於只有一個透視表使用連接。如果您通過複製第一個透視表(即它們共享相同的透視緩存)創建了額外的透視表,上述過程將不起作用(我不知道爲什麼)。

但是,如果您只使用一個透視表和連接字符串,則該方法將起作用。

1

刷新連接後,您可以添加此代碼。

With ThisWorkbook 
    .RefreshAll 
End With 
0

有同樣的問題。工作表上有一個開始日期和結束日期字段,用於修改數據透視表中數據的週期。爲工作表添加了以下代碼:

Private Sub Worksheet_Change(ByVal Target As Range) 
    'Update the query when the date range has been changed. 
    If (Target.Row = Worksheets("Revenue").Range("StartDate").Row Or _ 
     Target.Row = Worksheets("Revenue").Range("EndDate").Row) And _ 
     Target.Column = Worksheets("Revenue").Range("StartDate").Column Then 

     FilterTableData 

    End If 
End Sub 

Sub FilterTableData() 
    'Declare variables 
    Dim noOfConnections As Integer 
    Dim loopCount As Integer 
    Dim conn As WorkbookConnection 
    Dim connectionName As String 
    Dim startDate As Date 
    Dim endDate As Date 
    Dim strMonth As String 
    Dim strDay As String 
    Dim startDateString As String 
    Dim endDateString As String 

    'Remove current connections 
    'Note: Excel creates a new connection with a new name as soon as you change the query for the connection. To avoid 
    ' ending up with multiple connections delete all connections and start afresh. 

    'First delete all fake connections 
    noOfConnections = ActiveWorkbook.Connections.Count 
    For loopCount = noOfConnections To 1 Step -1 
     Set conn = ActiveWorkbook.Connections.Item(loopCount) 
     If conn Is Nothing Then 
      conn.Delete 
     End If 
    Next loopCount 

    'Then delete all extra connections 
    noOfConnections = ActiveWorkbook.Connections.Count 
    For loopCount = noOfConnections To 1 Step -1 
     If loopCount = 1 Then 
      Set conn = ActiveWorkbook.Connections.Item(loopCount) 
      conn.Name = "Connection1" 
     Else 
      Set conn = ActiveWorkbook.Connections.Item(loopCount) 
      conn.Delete 
     End If 
    Next loopCount 

    'Create date strings for use in query. 
    startDate = Worksheets("Revenue").Range("B1") 
    strDay = Day(startDate) 
    If Len(strDay) = 1 Then 
     strDay = "0" & strDay 
    End If 
    strMonth = Month(startDate) 
    If Len(strMonth) = 1 Then 
     strMonth = "0" & strMonth 
    End If 
    startDateString = Year(startDate) & "-" & strMonth & "-" & strDay & " 00:00:00" 

    endDate = Worksheets("Revenue").Range("B2") 
    strDay = Day(endDate) 
    If Len(strDay) = 1 Then 
     strDay = "0" & strDay 
    End If 
    strMonth = Month(endDate) 
    If Len(strMonth) = 1 Then 
     strMonth = "0" & strMonth 
    End If 
    endDateString = Year(endDate) & "-" & strMonth & "-" & strDay & " 00:00:00" 

    'Modify the query in accordance with the new date range 
    With conn.ODBCConnection 
     .CommandText = Array(_ 
     "SELECT INVOICE.ACCOUNT_PERIOD, INVOICE.INVOICE_NUMBER, INVOICE_ITEM.LAB, INVOICE_ITEM.TOTAL_PRICE, ", _ 
     "INVOICE.INVOICED_ON" & Chr(13) & "" & Chr(10) & _ 
     "FROM Lab.dbo.INVOICE INVOICE, Lab.dbo.INVOICE_ITEM INVOICE_ITEM" & Chr(13) & "" & Chr(10) & _ 
     "WHERE INVOICE.INVOICE_NUMBER = INVOICE_ITEM.INVOICE_NUMBER AND ", _ 
     "INVOICE.INVOICED_ON > {ts '" & startDateString & "'} AND INVOICE.INVOICED_ON < {ts '" & endDateString & "'} ") 
    End With 

    'Refresh the data and delete any surplus connections 
    noOfConnections = ActiveWorkbook.Connections.Count 
    If noOfConnections = 1 Then 
     'Rename connection 
     ActiveWorkbook.Connections.Item(1).Name = "Connection" 

     'Refresh the data 
     ActiveWorkbook.Connections("Connection").Refresh 
    Else 
     'Refresh the data 
     ActiveWorkbook.Connections("Connection").Refresh 

     'Delete the old connection 
     ActiveWorkbook.Connections("Connection1").Delete 
    End If 

    'Refresh the table 
    ActiveSheet.PivotTables("Revenue").Update 
End Sub 
1

我不相信它是導致您的問題的連接字符串的更新。更新導致創建額外連接的ODBC連接的CommandText屬性時存在錯誤。如果您臨時切換到OLEDB連接,請更新您的CommandText屬性,然後切換回ODBC,它不會創建新連接。不要問我爲什麼......這隻適用於我。

我創建了一個模塊,允許您更新CommandText和/或連接字符串。插入此代碼到一個新的模塊:

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", "ODBC;..." 
+0

這很好地解決了我的問題,無需刪除不需要的連接。用兩個連接測試它,一個連接一個樞軸表,另一個連接兩個連接。 – Zajonc 2017-01-08 18:39:18