我有一个Excel文件,其中包含由多个数据透视表利用的一系列OLEDB连接。我想创建一个VBA函数,以在关闭文件时从该几个连接字符串中删除所有密码(这样用户的密码将不会保留)。首先,我以为我需要做的就是将“保存密码”属性设置为false,如下所示:
Public Sub RemovePasswordByNamePrefix()
Dim cn As Object
Dim oledbCn As OLEDBConnection
For Each cn In ThisWorkbook.connections
Set oledbCn = cn.OLEDBConnection
oledbCn.SavePassword = False
Next
End Sub
应该可以正常工作,在关闭文件并重新打开文件时,您应该不再在连接字符串中看到密码。不应“保存”:
错误,密码仍然存在...已被“保存”。不知道该功能应该做什么。也许那里指的是不同的密码?因此,我尝试了big hammer approach,不幸的是它有它自己的挑战,到目前为止,我还没有解决这个问题。
我不太确定该怎么做...为什么这么不安全?对于包含此类连接字符串的每个文件,它都会保留纯文本密码,任何访问该文件的人都可以轻松读取。
也许我可以进行某种正则表达式以仅从文件中删除密码?当我在界面中执行此操作时,我的多维数据集将刷新并提示我输入凭据,(我想知道)如果在VBA中执行了该操作,即使触发器在关闭时效果很好,也会发生这种情况吗?
底线:什么是防止这些密码在关闭后保留在文件中的最佳方法?
答案 0 :(得分:5)
@TomJohnRiddle指出,我应该考虑像following question.一样修改连接字符串。最初,我担心采用这种方法可能会在修改连接字符串后提示用户登录屏幕。但是,由于我没有更好的主意,因此我尝试了一下,而且似乎可行,这是我在模仿的内容:
Public Sub RemovePasswordByNamePrefix()
Dim cn As Object
Dim oledbCn As OLEDBConnection
Dim regEx As New RegExp
regEx.Pattern = "Password=[^;]*;"
For Each cn In ThisWorkbook.connections
Set oledbCn = cn.OLEDBConnection
oledbCn.SavePassword = False
oledbCn.connection = regEx.Replace(oledbCn.connection, "")
oledbCn.CommandText = "" 'My app repopulates this after open
Next
End Sub
似乎可行:
因此,我认为我会采用这种方法,但是我仍然愿意接受其他建议。清除所有内容并完全重新加载会很不错,但到目前为止还没有appear to be possible.
我还关心哪些版本的VBA支持"Regex" references。我想要与Excel 2010+ 32/64位兼容的东西。我尚未在任何较旧的版本上对此进行测试(我当前正在运行Office 365)。我认为一切正常,但是过去我一直unpleasantly surprised经历过这些事情。
答案 1 :(得分:2)
有关SQL Server身份验证Authentication in SQL Server的信息,请参见。在那里,您可以使用100%Windows身份验证,也可以使用混合模式(Windows身份验证和密码)。如果您确实想从连接字符串中清除密码,请不要使用混合模式身份验证进行安装,只需运行100%Windows身份验证即可。但是,可能已经部署了一些使用密码编写的代码,因此可能并不总是实用的。
因此,禁止输入密码的另一种方法是使用
Integrated Security=true;
在您的连接字符串中。关于这个主题的Stack Overflow question受到了广泛欢迎。
答案 2 :(得分:0)
@NigelHeffernan建议使用一种稍有不同的方法,这是一个没有正则表达式的版本:
event_generate
我不确定这种方法的好处(除了缺少另一个库引用),而且我还没有在一个连接字符串/一台机器之外进行测试。我的连接字符串不包含“扩展属性”字段,也许这种方法不适用于这种情况。
答案 3 :(得分:0)
您似乎正在使用DSN,如果您在GUI中使用默认的连接管理工具,则Excel会创建DSN。使用DSN时,即使您未选择“保存密码”,ODBC驱动程序有时也会将明文密码输入到注册表中。
与其允许Excel管理您的连接,还需要您自己对其进行管理。这是MS MVP Ben Clothier的一些示例代码。您将必须修改连接字符串以匹配您的用例。您可能可以在删除现有连接之前复制其详细信息。
Public Function InitConnect(UserName As String, Password As String) As Boolean
‘ Description: Should be called in the application’s startup
‘ to ensure that Access has a cached connection
‘ for all other ODBC objects’ use.
On Error GoTo ErrHandler
Dim dbCurrent As DAO.Database
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
‘<configuration specific to MySQL ODBC driver>
strConnection = “ODBC;DRIVER={MySQL ODBC 5.1 Driver};” & _
“Server=” & ServerAddress & “;” & _
“Port=” & PortNum & “;” & _
“Option=” & Opt & “;” & _ ‘MySql-specific configuration
“Stmt=;” & _
“Database=” & DbName & “;”
Set dbCurrent = DBEngine(0)(0)
Set qdf = dbCurrent.CreateQueryDef(“”)
With qdf
.Connect = strConnection & _
“Uid=” & UserName & “;” & _
“Pwd=” & Password
.SQL = “SELECT CURRENT_USER();”
Set rst = .OpenRecordset(dbOpenSnapshot, dbSQLPassThrough)
End With
InitConnect = True
ExitProcedure:
On Error Resume Next
Set rst = Nothing
Set qdf = Nothing
Set dbCurrent = Nothing
Exit Function
ErrHandler:
InitConnect = False
MsgBox Err.Description & ” (” & Err.Number & “) encountered”, _
vbOKOnly + vbCritical, “InitConnect”
Resume ExitProcedure
Resume
End Function
注意: 这是为MS Access而不是Excel编写的。概念都是一样的。您可能想尝试在Access中创建前端,然后将视图从Access导出到Excel。这样可以更好地控制到后端的链接,并允许您在Access中使用SQL来定义要导出到Excel的内容。