我的最终目标是用 C# 构建一个类库 (Calculator.dll),其中包含可通过 VBA 访问 Excel 的函数。
我原本希望避免注册 dll,而是在 VBA 代码中使用 Declare Function 语句,但显然这是不可能的,我的研究表明我需要使类库 COM-Visible,然后注册它,并将其添加为 VBA 项目的引用。 在早期的 Visual Studio 版本中,这似乎是单击项目属性对话框中的框的问题,但我在 VS2022 中没有看到该框?!
这些是我在“玩具”示例中采取的步骤,以及我遇到的问题。
(1) 我使用Calculate 类和一个简单的方法来添加两个整数,构建了以下.dll。 由于我们使用 32 位 Excel,所以我将其配置为 x86。
namespace ClassLibraryCalculator
{
public class Calculate
{
public int Add(int a,int b){ return a + b; }
}
}
(2) 在命令提示符下,以管理员身份运行,我尝试运行 regsvr32“ClassLibraryCalculator.dll”但遇到错误“..已加载但未找到入口点 DllRegisterServer”
经过搜索,据说解决这个问题的方法是修改项目属性,这是(在早期版本的VS中?)一个对话框
有一个复选框,但我在 Visual Studio 2022 项目属性中没有看到任何与 COM 相关的内容。
首先确保创建一个“类库(.NET Framework)”类型的项目,该项目使用经典的 Windows .net Framework(如版本 4.8)。不要选择基于.NET Standard并支持多种不同操作系统的“类库”项目类型。
创建项目后,在解决方案资源管理器中右键单击该项目并选择“属性”,打开项目属性。
在项目属性中,转到“应用程序”,然后单击“程序集信息”。
在“Assenmbly Information”对话框中,启用“Make assembly COM-Visible”复选框。
有关详细信息,请参阅将简单的 C# DLL 转换为 COM 互操作组件
请注意,您可以使用项目属性的“Build”区域中的“Register for COM interop”设置来注册 DLL(VS 需要以管理员权限运行)。当尝试从命令行注册时,不要使用“regsvr32”,而是使用“regasm”。请注意,regasm 有 32 位和 64 位版本可用。使用正确的。
更多重要提示:
请注意,“任何 CPU”将不起作用。如果您想同时支持 32 位和 64 位 Office 实例,您需要构建 dll 的两个变体并注册它们。
这是我用于测试的示例类:
using System;
using System.Runtime.InteropServices;
namespace ClassLibrary4
{
[Guid("ECB682F0-8AF1-40EA-B73A-1FACF3C7F742")]
public interface IClass1
{
void Test();
}
[Guid("4EC93EC5-FA8C-4E82-8931-E47D979BDA93")]
public class Class1 : IClass1
{
public void Test()
{
System.Console.Beep();
}
}
}
请注意,您不能使用这些 GUID,而必须使用您自己的 GUID。为此,请使用 Visual Studio 中的“工具 > 创建 GUID”命令。
以下是我在激活引用后如何使用 VBA 中的类:
' Declare variable with interface type
Dim c As ClassLibrary4.IClass1
' Create from class type
Set c = New ClassLibrary4.Class1
' Use.
c.Test
如果您想在 .NET Core 中执行此操作,请不要选中“注册 COM 互操作”框,而是将其放入您的项目文件中:
<PropertyGroup>
<EnableComHosting>true</EnableComHosting>
</PropertyGroup>
没有理由坚持使用旧的 .NET 框架。