2

Convert vba to vb6 and create a .dll - how to - 提示、技巧和风险中,讨论了如何将 VBA 代码转换为 VB.NET 代码并在 Excel 中将 VB.NET 中的函数作为 COM 访问。

在 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 包装器。

4

2 回答 2

2

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

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

using System.Runtime.InteropServices;

声明一个包含您要调用的函数的接口:

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

只有界面中列出的函数才能在 Excel 中使用。请注意,函数的返回类型是“对象”。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 要求所有返回类型都是二维对象数组,因此您需要以这种方式转换函数的返回值。

您还需要添加一些有助于注册和注销 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);
        }
    }
  • 在项目的“属性”屏幕中,在“应用程序”选项卡中,单击“程序集信息”,然后选中“使程序集 COM-Visible”。单击确定。
  • 在“构建”选项卡中,单击底部附近的“注册 COM 互操作”。
  • 构建项目。

在 Excel 中,单击开发人员功能区,单击“加载项”、“自动化”并向下滚动到您的项目。它将以 [namespace].[classname] 的形式列出

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

=func1(12)

MSDN博主也有关于这个的帖子,但它很旧

PS 如果您在转换到 VB.Net 时需要帮助,请告诉我,我当然可以提供帮助。

于 2013-01-25T15:46:02.947 回答
0

曾经有一种方法可以达到 excel 97,但由于存在安全风险而被删除。调用函数可以从 COM dll 调用函数。http://www.cpearson.com/excel/Call.htm

于 2013-01-13T13:29:11.783 回答