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

Posted

技术标签:

【中文标题】在 microsoft excel 宏中修改嵌入的连接字符串【英文标题】:Modify an embedded Connection String in microsoft excel macro 【发布时间】: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" 【参考方案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 文件可能是您当前连接使用的文件。

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

【讨论】:

以上是关于在 microsoft excel 宏中修改嵌入的连接字符串的主要内容,如果未能解决你的问题,请参考以下文章

Excel VBA 宏后期绑定

excel宏中的运行时错误424

如何使用 VBA 在 Excel 宏中删除具有两列的重复项?

如果组合框为空,则 Excel 宏中的警告消息

让通配符在 Microsoft Word 的 VBA 宏中的查找和替换功能中起作用

Excel VBA 宏中的数组