【问题标题】:Modify an embedded Connection String in microsoft excel macro在 microsoft excel 宏中修改嵌入的连接字符串
【发布时间】:2013-11-21 06:46:09
【问题描述】:

我有一个 Excel 文档,其中包含一个宏,在运行时将修改该连接的 CommandText 以从 Excel 电子表格中传递参数,如下所示:

Sub RefreshData()
ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary")
  .OLEDBConnection.CommandText = "Job_Cost_Code_Transaction_Summary_Percentage_Pending @monthEndDate='" & Worksheets("Cost to Complete").Range("MonthEndDate").Value & "', @job ='" & Worksheets("Cost to Complete").Range("Job").Value & "'"
ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary").Refresh
End Sub

我希望刷新不仅可以修改连接命令,还可以修改连接,因为我还想将它与不同的数据库一起使用:

就像宏用电子表格中的值替换命令参数一样,我希望它也用电子表格中的值替换数据库服务器名称和数据库名称。

不需要完整的实现,只需修改与工作表中的值的连接的代码就足够了,我应该可以从那里开始工作。

我试图做这样的事情:

 ActiveWorkbook
 .Connections("Job_Cost_Code_Transaction_Summary")
 .OLEDBConnection.Connection = "new connection string"

但这不起作用。谢谢。

【问题讨论】:

  • 你需要看到Connection Strings并学习如何使用ADODB
  • 你有没有找到解决这个问题的方法?如果是这样,我将非常感谢您与我们分享。
  • 不幸的是,当前仍在手动编辑连接字符串。
  • 顺便说一句,属性是连接而不是连接字符串:ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary").OLEDBConnection.Connection = "new connection string"
  • 任何导致错误的想法:ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary").OLEDBConnection.Connection = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=ADCData_Doric;Data Source=doric-server5;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=LHOLDER-VM;Use Encryption for Data=False;Tag with column collation when possible=False"

标签: excel vba


【解决方案1】:

我的问题的答案如下。

所有其他答案大多是正确的,重点是修改当前连接,但我只想知道如何在连接上设置连接字符串。

错误归结为这一点。如果您查看我的屏幕截图,您会看到连接字符串是:

Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=ADCData_Doric;Data Source=doric-server5;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=LHOLDER-VM;Use Encryption for Data=False;Tag with column collation when possible=False

我试图用ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary").OLEDBConnection.Connection = "connection string"设置那个字符串

当我只是试图将完整的字符串分配给连接时,我遇到了一个错误。我能够使用该属性将当前连接字符串 MsgBox,但没有将连接字符串设置回来而不会收到错误。

我后来发现连接字符串需要在字符串前面加上OLEDB;

所以现在可以了!!!

ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary").OLEDBConnection.Connection = "OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=ADCData_Doric;Data Source=doric-server5;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=LHOLDER-VM;Use Encryption for Data=False;Tag with column collation when possible=False"

非常微妙,但这就是错误!

【讨论】:

    【解决方案2】:

    我认为你已经很接近实现你想要的了。

    我能够为 ODBCConnection 进行更改。抱歉,我无法设置 OLEDBConnection 进行测试,您可以根据自己的情况将 ODBCConnection 的出现更改为 OLEDBConnection

    尝试添加这 2 个 subs 并进行修改,并在 CommandTextConnection String 中输入您需要替换的内容。注意我放了.Refresh来更新连接,在需要实际数据刷新之前你可能不需要。

    您可以使用相同的拆分想法更改其他字段,然后稍后加入:

    Private Sub ChangeConnectionString(sInitialCatalog As String, sDataSource As String)
        Dim sCon As String, oTmp As Variant, i As Long
        With ThisWorkbook.Connections("Job_Cost_Code_Transaction_Summary").ODBCConnection
            sCon = .Connection
            oTmp = Split(sCon, ";")
            For i = 0 To UBound(oTmp) - 1
                ' Look for Initial Catalog
                If InStr(1, oTmp(i), "Initial Catalog", vbTextCompare) = 1 Then
                    oTmp(i) = "Initial Catalog=" & sInitialCatalog
                ' Look for Data Source
                ElseIf InStr(1, oTmp(i), "Data Source", vbTextCompare) = 1 Then
                    oTmp(i) = "Data Source=" & sDataSource
                End If
            Next
            sCon = Join(oTmp, ";")
            .Connection = sCon
            .Refresh
        End With
    End Sub
    
    Private Sub ChangeCommanText(sCMD As String)
        With ThisWorkbook.Connections("Job_Cost_Code_Transaction_Summary").ODBCConnection
            .CommandText = sCMD
            .Refresh
        End With
    End Sub
    

    【讨论】:

      【解决方案3】:

      您可以使用将 OLEDBConnection 和要更新的参数作为输入的函数,并返回新的连接字符串。它与 Jzz 的答案类似,但具有一定的灵活性,而无需在每次要更改 VBA 代码时都编辑连接字符串 - 最坏的情况是您必须向函数添加新参数。

      Function NewConnectionString(conTarget As OLEDBConnection, strCatalog As String, strDataSource As String) As String
      
          NewConnectionString = conTarget.Connection
          NewConnectionString = ReplaceParameter("Initial Catalog", strCatalog)
          NewConnectionString = ReplaceParameter("Data Source", strDataSource)
      
      End Function
      
      Function ReplaceParameter(strConnection As String, strParamName As String, strParamValue As String) As String
      
          'Find the start and end points of the parameter
          Dim intParamStart As Integer
          Dim intParamEnd As Integer
          intParamStart = InStr(1, strConnection, strParamName & "=")
          intParamEnd = InStr(intParamStart + 1, strConnection, ";")
      
      
          'Replace the parameter value
          Dim strConStart As String
          Dim strConEnd As String
          strConStart = Left(strConnection, intParamStart + Len(strParamName & "=") - 1)
          strConEnd = Right(strConnection, Len(strConnection) - intParamEnd + 1)
      
          ReplaceParameter = strConStart & strParamValue & strConEnd
      
      End Function
      

      请注意,我已根据用于特定应用程序的现有代码对其进行了修改,因此它已经过部分测试,可能需要进行一些调整才能完全满足您的需求。

      还要注意,它还需要某种调用代码,即(假设新目录和数据源存储在工作表单元格中):

      Sub UpdateConnection(strConnection As String, rngNewCatalog As Range, rngNewSource As Range)
      
          Dim conTarget As OLEDBConnection
          Set conTarget = ThisWorkbook.Connections.OLEDBConnection(strConnection)
      
          conTarget.Connection = NewConnectionString(conTarget, rngNewCatalog.Value, rngNewSource.Value)
          conTarget.Refresh
      
      End Sub
      

      【讨论】:

        【解决方案4】:

        我想在这里为这个古老的话题做一点贡献。 如果您的 Excel 文件中有许多连接,并且想要更改所有连接的数据库名称和数据库服务器,您也可以使用以下代码:

        • 它遍历所有连接并提取连接字符串
        • 每个连接字符串被拆分成一个字符串数组
        • 它遍历数组寻找正确的连接值来修改,其他的都没有触及
        • 它将数组重组为字符串并提交更改

        这样你就不需要使用replace并知道之前的值,字符串的其余部分将保持不变。 此外,我们可以引用单元格名称,因此您可以在 Excel 文件中使用名称

        希望对你有帮助

        Sub RelinkConnections()
        
        Dim currConnValues() As String
        
        For Each currConnection In ThisWorkbook.Connections
            currConnValues = Split(currConnection.OLEDBConnection.Connection, ";")
            For i = 0 To UBound(currConnValues)
                If (InStr(currConnValues(i), "Initial Catalog") <> 0) Then
                    currConnValues(i) = "Initial Catalog=" + Range("DBName").value
                ElseIf (InStr(currConnValues(i), "Data Source") <> 0) Then
                    currConnValues(i) = "Data Source=" + Range("DBServer").value
                End If
            Next
            currConnection.OLEDBConnection.Connection = Join(currConnValues, ";")
            currConnection.Refresh
        Next
        
        End Sub
        

        【讨论】:

          【解决方案5】:

          这应该可以解决问题:

          Sub jzz()
          
          Dim conn As Variant
          Dim connectString As String
          
          For Each conn In ActiveWorkbook.Connections
              connectString = conn.ODBCConnection.Connection
              connectString = Replace(connectString, "Catalog=ADCData_Doric", "Catalog=Whatever")
              connectString = Replace(connectString, "Data Source=doric-server5", "Data Source=Whatever")
          
              conn.ODBCConnection.Connection = connectString
          Next conn
          
          
          End Sub
          

          它循环工作簿中的每个连接并更改连接字符串(在 2 个替换语句中)。

          所以要修改你的例子:

          ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary").ODBCConnection.Connection = "new connection string"
          

          【讨论】:

            【解决方案6】:

            我认为您有必要保持相同的连接名称?否则,最简单的方法是忽略它并创建一个新的连接。

            您可以重命名连接,并使用该名称创建一个新连接:

            ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary").Name = "temp"
            'or, more drastic:
            'ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary").Delete
            
            ActiveWorkbook.Connections.Add "Job_Cost_Code_Transaction_Summary", _
                "a description", "new connection string", "command text" '+ ,command type
            

            之后,Delete 这个连接并恢复旧的连接/名称。 (我目前无法自己测试,所以小心行事。)

            或者,您可以更改当前连接SourceConnectionFile

            ActiveWorkbook.Connections("Job_Cost_Code_Transaction_Summary").OLEDBConnection.SourceConnectionFile = "..file location.."
            

            这通常引用保存在系统上的 .odc 文件(Office 数据连接),其中包含连接详细信息。您可以从 Window 的控制面板创建此文件。

            您尚未指定,但 .odc 文件可能是您当前连接使用的文件。

            同样,我无法测试这些建议,因此您应该进一步调查并采取一些预防措施 - 这样您就不会冒丢失当前连接详细信息的风险。

            【讨论】:

              猜你喜欢
              • 2023-04-03
              • 2013-05-17
              • 2018-11-29
              • 2015-05-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-16
              • 2011-02-05
              相关资源
              最近更新 更多