在 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 并进行修改,并在 CommandText 和 Connection 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 宏中修改嵌入的连接字符串的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 VBA 在 Excel 宏中删除具有两列的重复项?