这是一个关于从Excel(或VBA)调用.NET的三种主要方法的规范化答案。
这三种方式都适用于.NET 4.0。
1. XLLs
第三方供应商Add-In Express提供了XLL功能,但它是免费的且易于使用的Excel-DNA作者在此处https://stackoverflow.com/users/44264
以下是来自Excel-DNA页面的摘录:https://excel-dna.net/
简介
Excel-DNA是一个独立项目,用于将.NET集成到Excel中。使用Excel-DNA,您可以使用C#,Visual Basic.NET或F#制作本机(.xll)Excel插件,提供高性能的用户定义函数(UDF),自定义功能区界面等。您的整个插件可以打包到单个.xll文件中,无需安装或注册。
入门指南
如果您正在使用支持NuGet包管理器的Visual Studio版本(包括Visual Studio 2012 Express for Windows Desktop),则制作Excel-DNA插件的最简单方法是:
在Visual Basic、C#或F#中创建新的类库项目。
使用管理NuGet包对话框或包管理器控制台安装Excel-DNA包:
PM> Install-Package Excel-DNA
请添加您的代码 (C#、Visual Basic.NET 或 F#):
using ExcelDna.Integration;
public static class MyFunctions
{
[ExcelFunction(Description = "My first .NET function")]
public static string SayHello(string name)
{
return "Hello " + name;
}
}
编译、加载并在Excel中使用您的函数:
=SayHello("World!")
2. 自动化插件
这篇由Eric Carter撰写的文章向我们展示了如何做到这一点,但是文章缺少大量图片,因此我将整篇文章复制/粘贴,并重新创建了图片以进行保存。
参考资料:https://blogs.msdn.microsoft.com/eric_carter/2004/12/01/writing-user-defined-functions-for-excel-in-net/
Excel允许创建可在 Excel 公式中使用的用户定义函数。开发人员必须创建一种称为 XLL 的特殊类型的 DLL。Excel还允许您在 VBA 中编写自定义函数,这些函数可在 Excel 公式中使用。不幸的是,Excel 不支持或建议编写使用托管代码的 XLL。如果您愿意冒险,那么有一些解决方案可实现此场景——在网络上搜索“托管XLL”。
幸运的是,有一种更简单的方法可以创建不需要创建 XLL dll 的用户定义函数。Excel XP、Excel 2003 和 Excel 2007 支持称为自动化插件的东西。自动化插件可以很容易地在 C# 或 VB.NET 中创建。我将在本例中向您展示 C# 的一个示例。
首先,启动 Visual Studio 并创建名为 AutomationAddin 的新 C# 类库项目。
然后,在您的 Class1.cs 文件中,输入下面显示的代码。使用 Visual Studio 的“工具”菜单中的“生成 GUID”创建自己的 GUID 来替换 GUID。
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace AutomationAddin
{
[Guid("A33BF1F2-483F-48F9-8A2D-4DA68C53C13B")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class MyFunctions
{
public MyFunctions()
{
}
public double MultiplyNTimes(double number1, double number2, double timesToMultiply)
{
double result = number1;
for (double i = 0; i < timesToMultiply; i++)
{
result = result * number2;
}
return result;
}
[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type type)
{
Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, "Programmable"));
RegistryKey key = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, "InprocServer32"), true);
key.SetValue("", System.Environment.SystemDirectory + @"\mscoree.dll",RegistryValueKind.String);
}
[ComUnregisterFunctionAttribute]
public static void UnregisterFunction(Type type)
{
Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, "Programmable"), false);
}
private static string GetSubKeyName(Type type, string subKeyName)
{
System.Text.StringBuilder s = new System.Text.StringBuilder();
s.Append(@"CLSID\{");
s.Append(type.GUID.ToString().ToUpper());
s.Append(@"}\");
s.Append(subKeyName);
return s.ToString();
}
}
}
完成代码后,在解决方案浏览器中双击项目下的属性节点,显示项目的属性。点击“生成”选项卡,勾选“注册COM互操作”。如果您在Windows Vista或更高版本上运行,还需要执行额外的步骤。必须使用管理员特权运行Visual Studio才能注册COM互操作。保存项目并退出Visual Studio。然后在开始菜单中找到Visual Studio并右键单击它,选择“以管理员身份运行”。重新打开Visual Studio中的项目,然后选择“生成”来构建插件。
现在启动Excel,按照以下步骤打开自动化服务器对话框:
Launch Excel and click the Microsoft Office button in the top left corner of the window.
Choose Excel Options.
Click the Add-Ins tab in the Excel Options dialog.
Choose Excel Add-Ins from the combo box labeled Manage. Then click the Go button.
Click the Automation button in the Add-Ins dialog.
要找到您创建的类,请在Automation插件列表中查找AutomationAddin.MyFunctions:
现在,让我们尝试在Excel中使用函数“MultiplyNTimes”。首先创建一个简单的电子表格,其中包含一个数字,第二个数字是要将第一个数字乘以的数字,第三个数字是要将第一个数字乘以第二个数字的次数。以下是一个示例电子表格:
单击工作簿中数字下方的空单元格,然后单击公式栏中的“插入函数”按钮。从可用公式对话框中,展开“或选择一个类别”下拉框,并选择“AutomationAddin.MyFunctions”。
然后单击“MultiplyNTimes”函数,如下所示:
单击“确定”按钮后,Excel会弹出一个对话框,帮助您从电子表格中获取函数参数,如下所示:
最后,单击“确定”,查看您的最终电子表格,如下所示,在单元格C3中使用自定义公式。
3. 从Excel VBA调用.Net
使用Automation.AddIn项目中的代码,我们可以轻松地从Excel VBA调用MultiplyNTimes函数。
首先,在Excel中添加对DLL的引用,为此,您需要在VB编辑器中。按Alt + F11,然后点击工具菜单和引用:
选择AutomationAddin DLL:
添加VBA代码以调用.Net DLL:
Sub Test()
Dim dotNetClass As AutomationAddIn.MyFunctions
Set dotNetClass = New AutomationAddIn.MyFunctions
Dim dbl As Double
dbl = dotNetClass.MultiplyNTimes(3, 2, 5)
End Sub
神奇的是!
请注意,如果您在C#中使用类,您需要使用ClassInterface标记它们,使用一个带有ComVisible = true标记的接口:如何在Excel VBA中使用CLR类?
最后,一些由“Andrew Whitechapel”撰写的关于Excel和.Net的优秀的MSDN文章- 谷歌搜索它们