如何在VBA中安全地存储连接字符串详细信息

时间:2010-07-09 22:45:25

标签: vba connection-string

我有一个Excel模板,在VBA代码中使用硬编码的Ms Access MDB路径,用于连接到Access表并保存,检索数据。

我将MS Access数据库迁移到具有Excel模板用户的集成身份验证的SQL Server。

我的问题是,存储SQL Server数据库连接字符串并在Excel 2007 VBA中将其重新存储以保存和检索数据的建议方式/最佳实践是什么?

过去,我做了以下事情。

  1. 使用具有连接字符串的注册表项设置。然后在VBA中,编写一个读取注册表项并返回连接字符串的函数。

  2. 在Excel模板中有一个“设置”隐藏工作表,其中包含连接字符串的命名单元格。通过访问该命名范围来读取VBA中的连接字符串。

  3. 使用与Excel模板一起使用的.INI txt文件。 (这不是理想的,我想避免这种情况,因为它构建了对该外部文件的依赖)

  4. 我不喜欢#1,因为我想尽可能避免写入/读取注册表。 #2感觉还不错,以为我不确定是否有更好的“清洁”方式。

    有什么想法吗?

2 个答案:

答案 0 :(得分:29)

我会安全地存储连接字符串凭据

下载并安装Visual Studio Express 2012 for Windows (FREE)

以管理员身份打开它并创建一个新项目。选择 Visual C# ,然后 Class Library 并将其重命名为 HiddenConnectionString

enter image description here

Solution Explorer 中,将 Class1.cs 重命名为 MyServer.cs

enter image description here

右键单击解决方案资源管理器中的 MyConnection 项目,然后选择 Add Reference

在搜索框中输入activeX并勾选Microsoft ActiveX Data Objects 6.1 Library

enter image description here

将以下代码复制并粘贴到 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

enter image description here

点击左侧菜单中的*Build*,然后勾选Register For COM Interop

enter image description here

注意:如果您正在为64位Office进行开发,请确保将 Build 菜单上的 Platform Target 更改为x64!这对于64位Office COM库是必需的,以避免任何与ActiveX相关的错误。


右键单击解决方案资源管理器中的 HiddenConnectionString ,然后从菜单中选择 Build

如果一切正常,则应成功生成HiddenConnectionString.dllHiddenConnectionString.tlb。现在转到此路径

C:\Users\administrator\Documents\Visual Studio 2012\Projects\HiddenConnectionString\HiddenConnectionString\bin\Debug

你应该看到你的文件。

enter image description here


现在打开Excel并转到VBE。点击Tools,然后选择References

点击浏览按钮,然后导航至HiddenConnectionString.tlb

此外,添加对Microsoft ActiveX Object 6.1 Library的引用 - 这样您就可以使用ADODB库了。

enter image description here

现在右键单击 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 或点击功能区上的绿色播放按钮。

enter image description here

如果一切正常,您现在应该在电子表格上看到返回的表格。

我的样本:

enter image description here


如你所见。添加对您自己的COM库的引用并将登录凭据和其他敏感数据存储在已编译的.dll内可保护您的数据(连接字符串)。对*.dll文件进行反编译以获取任何合理的信息非常困难。有各种编码技术来保护你的*.dll甚至更多,但我现在不打算详细介绍。这本身就达到了你的要求。

myCn.GetConnection返回在引用的COM库中初始化的ADODB.Connection对象。不会向Excel用户显示连接字符串或敏感数据(实际上没有其他人也没有)。

您可以修改C#代码以接受来自VBA的参数,即登录,密码,初始目录,要执行的查询等...如果您的用户在SQL Server实例上具有不同的权限,那么这不会是一个坏事允许人们登录的想法。


注意:C#代码和VBA中没有添加错误处理。如果您打算使用我上面描述的技术,我强烈建议您继续努力。


答案 1 :(得分:2)

如何将其存储在CustomDocumentProperties下?

注意:我不确定,如果工作簿(基于给定模板)将继承模板中使用CustomDocumentProperties定义的属性。