在Excel中访问作为COM公开的.NET函数

在转换vba到vb6并创build一个.dll – 如何 – 提示,提示和风险 ,讨论了如何将VBA代码转换为VB.NET代码并在Excel中以COM的forms访问VB.NET中的函数。

在Excel中,函数必须通过VBA以这种方式访问​​:

Public Function getParameterNumberOfMaterial() As Integer Dim myclass as New ExcelExample.ExcelVB getParameterNumberOfMaterial = myclass.getParameterNumberOfMaterial() End Function 

这意味着每个暴露给用户的VBA函数,当转换到VB.NET时,我必须写上一个包装。

有没有办法直接使用这个函数而不用写VBA包装? 也就是说,在Excel中,用户可以直接使用getParameterNumberOfMaterial() ,就像原始的VBA函数一样,不需要我写一个VBA包装器。

您可以直接从Excel中直接调用.NET中的.NET函数,尽pipe您需要稍微修改它们,以便与COM和Excel兼容。 这个例子将在C#中,因为这是我所熟悉的,但在VB.Net中的概念应该是相同的。

打开一个新的Class项目,并添加一行来导入InteropServices库:

 using System.Runtime.InteropServices; 

声明一个将包含你想要调用的函数的接口:

 public interface ISample { object func1(int p1); object func2(string p1); } 

只有界面中列出的function将在Excel中可用。 注意函数的返回types是'object'。 Excel是正确显示表格中的结果所必需的。

声明将实现接口的类,并通过COM公开:

 [ClassInterface(ClassInterfaceType.None)] // the proper way to declare COM-visible classes public class Sample : ISample { public object func1(int p1) { // sample implementation object[,] retval = new object[1,1] retval[0,0] = "a"; return retval; } public object func2(string p1) { // .... } 

Excel希望所有的返回types都是二维的对象数组,所以你需要用这种方式来转换函数的返回值。

您还需要添加一些帮助注册和取消注册DLL的函数:

  // helper function to get Registry key of given type private static string GetSubKeyName(Type type) { return "CLSID\\{" + type.GUID.ToString().ToUpper() + "}\\Programmable"; } // called when class is being registered [ComRegisterFunctionAttribute] public static void RegisterFunction(Type type) { // register the automation DLL function will be visible to Excel RegistryKey key = Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type)); if (key != null) { key.SetValue(string.Empty, Environment.SystemDirectory + @"\mscoree.dll"); } } // called when class is being unregistered [ComUnregisterFunctionAttribute] public static void UnregisterFunction(Type type) { try { // remove automation DLL from registry Registry.ClassesRoot.DeleteSubKeyTree(GetSubKeyName(type)); } catch (Exception ex) { Debug.Print(ex.Message + ex.StackTrace); } } 
  • 在项目的“属性”屏幕中,在“应用程序”选项卡中,单击“assembly信息”,然后选中“使assembly体可见”。 点击OK。
  • 在“Build”选项卡中,单击底部附近的“Register for COM Interop”。
  • build立这个项目。

在Excel中,单击开发人员function区,单击“加载项”,“自动化”,然后向下滚动到您的项目。 它将以[namespace]的forms列出。[classname]

您现在应该可以直接在Excel工作表中调用函数:

 =func1(12) 

从MSDN的博客上也有一篇文章 ,但是相当老了

PS如果有任何这个部分你需要与转换为VB.Net协助,请让我知道,我当然可以协助。

过去曾经是一种超越97的方法,但作为安全风险被删除。 调用函数可以调用COM DLL的函数。 http://www.cpearson.com/excel/Call.htm