要添加到已经存在的答案:使用 .NET 4.0,在您的 VBA 项目中使用 C# dll 实际上非常简单,而无需注册 COM。
编辑:我刚刚用C:\windows\Microsoft.NET\Framework\v2.0.50727 中的mscorlib.tlb 和mscoree.tlb 尝试了这个——加载在3.5 中编译的程序集——它工作得很好。所以显然你不需要 .NET 4.0。
以下是如何在您的 VBA 项目中使用 C# dll 的示例。由this答案稍作修改。
1) 在您的 VBA 项目中添加对以下类型库的引用(工具->引用):
C:\windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb
C:\windows\Microsoft.NET\Framework\v4.0.30319\mscoree.tlb
(如果您运行的是 64 位 Office,请使用 Framework64 文件夹)
2) 在您的 C# 项目中,确保将 [ComVisible(true)] 属性添加到您的类中:
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace VB6FuncLib
{
[ComVisible(true)]
public class VB6FuncLib
{
public VB6FuncLib()
{ }
public void test()
{
MessageBox.Show("Test Successful");
}
}
}
您不需要选中“注册 COM 互操作”选项。这仅用于构建标准 COM 对象。您也不必检查“使程序集 COM 可见”,除非您希望整个程序集可见(这也将消除对 COMVisible 属性的需要)。
3) 在您的 VBA 代码中,使用以下代码添加一个新模块:
Sub Test()
Dim Host As mscoree.CorRuntimeHost
Set Host = New CorRuntimeHost
Host.Start
Dim Unk As IUnknown
Host.GetDefaultDomain Unk
Dim AppDomain As AppDomain
Set AppDomain = Unk
Dim ObjHandle As ObjectHandle
Set FS = CreateObject("Scripting.FileSystemObject")
Path = FS.GetParentFolderName(CurrentDb().Name)
Set ObjHandle = AppDomain.CreateInstanceFrom(Path & "\VB6 Function Library.dll", "VB6FuncLib.VB6FuncLib")
Dim ObjInstance As Object
Set ObjInstance = ObjHandle.Unwrap
ObjInstance.test
Host.Stop
End Sub
4) 将 DLL 复制到与您的 Office 项目相同的文件夹中,并在 VBA 中运行 Test() 子程序。
注意事项:
应该注意,这种技术的一个限制是,如果 .DLL 存储在远程网络共享上,它将无法工作。一个简单的解决方案是将其复制到正在使用它的每台 PC 上的同一本地文件夹中。另一种解决方案是将二进制文件包含在您的 Access 应用程序/VBA 项目中,并让 MS-Access 导出它们。可以实现的一种方法是将它们以 Base64 格式存储在表格或电子表格中,然后将它们转换并导出为二进制文件。
通过创建与 DLL 一起使用的类型库(通过使用 tlbexp),并在我的 VBA 项目中添加对 TLB 的引用,我能够使早期绑定(以及因此 Microsoft IntelliSense)工作,但它确实很复杂有点重要,因为它需要您的 VBA 应用程序知道 DLL 和 TLB 文件在哪里(并且还需要有人确保它们在那里)。