代码之家  ›  专栏  ›  技术社区  ›  Rory

用于更改外部数据查询连接的Excel宏-例如,从一个数据库指向另一个数据库

  •  2
  • Rory  · 技术社区  · 16 年前

    我正在寻找一个宏/vbs来更新所有外部数据查询连接以指向不同的服务器或数据库。这是一个手工操作的痛苦,在2007年以前的Excel版本中,有时似乎不可能手工操作。

    有人有样品吗?我看到有不同类型的连接“oledb”和“odbc”,所以我想我需要处理不同格式的连接字符串?

    4 回复  |  直到 10 年前
        1
  •  4
  •   Rory    16 年前

    我最后写了以下内容,提示您输入连接详细信息,创建一个连接字符串,然后更新所有外部数据查询以使用该连接字符串。

    '''' Prompts for connection details and updates all the external data connections in the workbook accordingly.
    '''' Changes all connections to use ODBC connections instead of OLEDB connections.
    '''' Could be modified to use OLEDB if there's a need for that.
    Sub PromptAndUpdateAllConnections()
        Dim Server As String, Database As String, IntegratedSecurity As Boolean, UserId As String, Password As String, ApplicationName As String
        Dim ConnectionString As String
        Dim MsgTitle As String
        MsgTitle = "Connection Update"
    
        If vbOK = MsgBox("You will be asked for information to connect to the database, and this spreadsheet will be updated to connect using those details.", vbOKCancel, MsgTitle) Then
            Server = InputBox("Database server or alias and instance name, e.g. 'LONDB01' or 'LONDB01\INST2'", MsgTitle)
            If Server = "" Then GoTo Cancelled
            Database = InputBox("Database name", MsgTitle, "a default value")
            If Database = "" Then GoTo Cancelled
            IntegratedSecurity = (vbYes = MsgBox("Integrated Security? (i.e. has your windows account been given access to connect to the database)", vbYesNo, MsgTitle))
            If Not IntegratedSecurity Then
                UserId = InputBox("User Id", MsgTitle)
                If UserId = "" Then GoTo Cancelled
                Password = InputBox("Password", MsgTitle)
                If Password = "" Then GoTo Cancelled
            End If
            ApplicationName = "Excel Reporting"
    
            ConnectionString = GetConnectionString(Server, Database, IntegratedSecurity, UserId, Password, ApplicationName)
            UpdateAllQueryTableConnections ConnectionString
            MsgBox "Spreadsheet Updated", vbOKOnly, MsgTitle
        End If
        Exit Sub
    Cancelled:
        MsgBox "Spreadsheet not updated", vbOKOnly, MsgTitle
    End Sub
    
    '''' Generates an ODBC connection string from the given details.
    Function GetConnectionString(Server As String, Database As String, IntegratedSecurity As Boolean, _
        UserId As String, Password As String, ApplicationName As String)
    
        Dim result As String
    
        If IntegratedSecurity Then
            result = "ODBC;DRIVER=SQL Server;SERVER=" & Server & ";DATABASE=" & Database _
                    & ";Trusted_Connection=Yes;APP=" & ApplicationName & ";"
        Else
            result = "ODBC;DRIVER=SQL Server;SERVER=" & Server & ";DATABASE=" & Database _
                    & ";UID=" & UserId & ";PWD=" & Password & ";APP=" & ApplicationName & ";"
        End If
    
        RM_GetConnectionString = result
    End Function
    
    '''' Sets all external data connection strings to the given value (regardless of whether they're
    '''' currently ODBC or OLEDB connections. Appears to change type successfully.
    Sub UpdateAllQueryTableConnections(ConnectionString As String)
        Dim w As Worksheet, qt As QueryTable
        Dim cn As WorkbookConnection
        Dim odbcCn As ODBCConnection, oledbCn As OLEDBConnection
        For Each cn In ThisWorkbook.Connections
            If cn.Type = xlConnectionTypeODBC Then
                Set odbcCn = cn.ODBCConnection
                odbcCn.SavePassword = True
                odbcCn.Connection = ConnectionString
            ElseIf cn.Type = xlConnectionTypeOLEDB Then
                Set oledbCn = cn.OLEDBConnection
                oledbCn.SavePassword = True
                oledbCn.Connection = ConnectionString
            End If
        Next
    End Sub
    
        2
  •  1
  •   GSerg    16 年前

    连接字符串格式在很大程度上与Excel无关,因为Excel会将其传递给数据提供程序。

    手动更新一个查询表,然后执行如下操作:

    dim w as worksheet, q as querytable
    
    for each w in thisworkbook.worksheets
      for each q in w.querytables
        q.connection = SampleSheet.querytables("PreparedQueryTable").connection
      next
    next
    
        3
  •  1
  •   Rajiv Singh    10 年前

    即使我们可以刷新特定的连接,它也会刷新所有链接到它的数据透视。

    对于此代码,我已根据Excel中的表创建切片器:

    此代码适用于数据库中的切片器:

    Sub UpdateConnection()
        Dim ServerName As String
        Dim ConnectionString As String
        Dim DatabaseNameCount As Integer
    
        DatabaseNameCount = ActiveWorkbook.SlicerCaches("Slicer_Name").VisibleSlicerItems.Count
    
        If DatabaseNameCount = 1 Then
            ServerName = ActiveWorkbook.SlicerCaches("Slicer_Name").VisibleSlicerItems.Item(1).Name
            ConnectionString = GetConnectionString(ServerName)
            UpdateAllQueryTableConnections ConnectionString
        Else
            MsgBox "Please Select One Value", vbOKOnly, "Slicer Info"
        End If
    End Sub
    

    此代码用于从同一工作簿中的Excel表创建的切片器:

    Sub UpdateConnection()
            Dim ServerName As String
            Dim ServerNameRaw As String
            Dim CubeName As String
            Dim CubeNameRaw As String
            Dim ConnectionString As String
    
            ServerNameRaw = ActiveWorkbook.SlicerCaches("Slicer_ServerName").VisibleSlicerItemsList(1)
            ServerName = Replace(Split(ServerNameRaw, "[")(3), "]", "")
    
            CubeNameRaw = ActiveWorkbook.SlicerCaches("Slicer_CubeName").VisibleSlicerItemsList(1)
            CubeName = Replace(Split(CubeNameRaw, "[")(3), "]", "")
    
            If CubeName = "All" Or ServerName = "All" Then
                MsgBox "Please Select One Cube and Server Name", vbOKOnly, "Slicer Info"
            Else
                ConnectionString = GetConnectionString(ServerName, CubeName)
                UpdateAllQueryTableConnections ConnectionString, CubeName
            End If
        End Sub
    

    为所需的初始目录创建连接和更新连接的通用代码:

    Function GetConnectionString(ServerName As String, CubeName As String)
            Dim result As String
            result = "OLEDB;Provider=MSOLAP.5;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=" & CubeName & ";Data Source=" & ServerName & ";MDX Compatibility=1;Safety Options=2;MDX Missing Member Mode=Error;Update Isolation Level=2"
            '"OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=" & CubeName & ";Data Source=" & ServerName & ";Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False"
            GetConnectionString = result
        End Function
    
        Sub UpdateAllQueryTableConnections(ConnectionString As String, CubeName As String)
            Dim cn As WorkbookConnection
            Dim oledbCn As OLEDBConnection
            Dim Count As Integer, i As Integer
            Dim DBName As String
            DBName = "Initial Catalog=" + CubeName
    
            Count = 0
            For Each cn In ThisWorkbook.Connections
                If cn.Name = "ThisWorkbookDataModel" Then
                    Exit For
                End If
    
                oTmp = Split(cn.OLEDBConnection.Connection, ";")
                For i = 0 To UBound(oTmp) - 1
                    If InStr(1, oTmp(i), DBName, vbTextCompare) = 1 Then
                        Set oledbCn = cn.OLEDBConnection
                        oledbCn.SavePassword = True
                        oledbCn.Connection = ConnectionString
                        Count = Count + 1
                    End If
                Next
            Next
    
            If Count = 0 Then
                 MsgBox "Nothing to update", vbOKOnly, "Update Connection"
            ElseIf Count > 0 Then
                MsgBox "Connection Updated Successfully", vbOKOnly, "Update Connection"
            End If
        End Sub
    
        4
  •  0
  •   Butch BArker    11 年前

    oledbcn.connection=connectionString导致Excel 2013崩溃

    推荐文章