修改microsoft excel宏中的嵌入式连接字符串

时间:2013-11-21 06:46:10

标签: excel vba

我有一个包含宏的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

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

enter image description here

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

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

我试着这样做:

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

但这不起作用。感谢。

6 个答案:

答案 0 :(得分:12)

我的问题的答案如下。

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

这个错误归结于此。如果您查看我的屏幕截图,您将看到连接字符串是:

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"

设置该字符串

当我只是尝试将完整字符串分配给Connection时,我收到了错误。我能够将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"

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

答案 1 :(得分:2)

您可以使用将OLEDBConnection和参数更新为输入的函数,并返回新的连接字符串。它与Jzz的答案类似,但允许一定的灵活性,而无需在每次想要更改VBA代码时编辑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

答案 2 :(得分:2)

我认为你已经达到了你想要的目标。

我能够改变 ODBCConnection 。很抱歉,我无法设置 OLEDBConnection 进行测试,您可以在您的情况下将 ODBCConnection 的出现更改为 OLEDBConnection

尝试通过修改添加此2个潜艇,并在 CommandText 连接字符串中输入您需要替换的内容。注意我将.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 :(得分:1)

这应该可以解决问题:

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"

答案 4 :(得分:1)

我想在这里给出一个小小的贡献。 如果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 :(得分:0)

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

您可以重命名连接,并使用名称

创建一个新连接
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文件可能是您当前连接所使用的文件。

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