我有一个Excel模板,在VBA代码中使用硬编码的Ms Access MDB路径,用于连接到Access表并保存,检索数据。
我将MS Access数据库迁移到具有Excel模板用户的集成身份验证的SQL Server。
我的问题是,存储SQL Server数据库连接字符串并在Excel 2007 VBA中将其重新存储以保存和检索数据的建议方式/最佳实践是什么?
过去,我做了以下事情。
使用具有连接字符串的注册表项设置。然后在VBA中,编写一个读取注册表项并返回连接字符串的函数。
在Excel模板中有一个“设置”隐藏工作表,其中包含连接字符串的命名单元格。通过访问该命名范围来读取VBA中的连接字符串。
使用与Excel模板一起使用的.INI txt文件。 (这不是理想的,我想避免这种情况,因为它构建了对该外部文件的依赖)
我不喜欢#1,因为我想尽可能避免写入/读取注册表。 #2感觉还不错,以为我不确定是否有更好的“清洁”方式。
有什么想法吗?
答案 0 :(得分:29)
我会安全地存储连接字符串凭据
下载并安装Visual Studio Express 2012 for Windows (FREE)
以管理员身份打开它并创建一个新项目。选择 Visual C#
,然后 Class Library
并将其重命名为 HiddenConnectionString
在 Solution Explorer 中,将 Class1.cs
重命名为 MyServer.cs
右键单击解决方案资源管理器中的 MyConnection
项目,然后选择 Add Reference
在搜索框中输入activeX
并勾选Microsoft ActiveX Data Objects 6.1 Library
将以下代码复制并粘贴到 MyServer.cs
中,完全替换文件中的内容。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.IO;
using ADODB;
namespace HiddenConnectionString
{
[InterfaceType(ComInterfaceType.InterfaceIsDual),
Guid("2FCEF713-CD2E-4ACB-A9CE-E57E7F51E72E")]
public interface IMyServer
{
Connection GetConnection();
void Shutdown();
}
[ClassInterface(ClassInterfaceType.None)]
[Guid("57BBEC44-C6E6-4E14-989A-B6DB7CF6FBEB")]
public class MyServer : IMyServer
{
private Connection cn;
private string cnStr = "Provider=SQLOLEDB; Data Source=SERVER\\INSTANCE; Initial Catalog=default_catalog; User ID=your_username; Password=your_password";
public MyServer()
{
}
public Connection GetConnection()
{
cn = new Connection();
cn.ConnectionString = cnStr;
cn.Open();
return cn;
}
public void Shutdown()
{
cn.Close();
}
}
}
在代码中找到cnStr
变量,并在更新中找到您的连接字符串详细信息。
右键单击 Solution Explorer 中的*HiddenConnectionString
*解决方案,然后选择“属性”。
点击左侧的 Application
标签,然后点击 Assembly Info
并勾选Make Assembly COM-Visible
点击左侧菜单中的*Build*
,然后勾选Register For COM Interop
注意:如果您正在为64位Office进行开发,请确保将 Build 菜单上的 Platform Target
更改为x64
!这对于64位Office COM库是必需的,以避免任何与ActiveX相关的错误。
右键单击解决方案资源管理器中的 HiddenConnectionString
,然后从菜单中选择 Build
。
如果一切正常,则应成功生成HiddenConnectionString.dll
和HiddenConnectionString.tlb
。现在转到此路径
C:\Users\administrator\Documents\Visual Studio 2012\Projects\HiddenConnectionString\HiddenConnectionString\bin\Debug
你应该看到你的文件。
现在打开Excel并转到VBE。点击Tools
,然后选择References
。
点击浏览按钮,然后导航至HiddenConnectionString.tlb
。
此外,添加对Microsoft ActiveX Object 6.1 Library
的引用 - 这样您就可以使用ADODB库了。
现在右键单击 Project Explorer 窗口中的任意位置,然后插入新的 Module
将以下代码复制并粘贴到其中
Option Explicit
Sub Main()
Dim myCn As MyServer
Set myCn = New MyServer
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open "Select * from [TABLE_NAME]", myCn.GetConnection
Range("A1").CopyFromRecordset rs
rs.Close
myCn.Shutdown
Set rs = Nothing
Set myCn = Nothing
Columns.AutoFit
End Sub
将[TABLE_NAME]
替换为数据库中的实际表名。
点击 F5 或点击功能区上的绿色播放按钮。
如果一切正常,您现在应该在电子表格上看到返回的表格。
我的样本:
如你所见。添加对您自己的COM库的引用并将登录凭据和其他敏感数据存储在已编译的.dll
内可保护您的数据(连接字符串)。对*.dll
文件进行反编译以获取任何合理的信息非常困难。有各种编码技术来保护你的*.dll
甚至更多,但我现在不打算详细介绍。这本身就达到了你的要求。
myCn.GetConnection
返回在引用的COM库中初始化的ADODB.Connection
对象。不会向Excel用户显示连接字符串或敏感数据(实际上没有其他人也没有)。
您可以修改C#代码以接受来自VBA的参数,即登录,密码,初始目录,要执行的查询等...如果您的用户在SQL Server实例上具有不同的权限,那么这不会是一个坏事允许人们登录的想法。
注意:C#代码和VBA中没有添加错误处理。如果您打算使用我上面描述的技术,我强烈建议您继续努力。
答案 1 :(得分:2)
如何将其存储在CustomDocumentProperties
下?
注意:我不确定,如果工作簿(基于给定模板)将继承模板中使用CustomDocumentProperties
定义的属性。