Excel COM 互操作中的方法重载

发布于 2024-11-30 07:26:09 字数 1860 浏览 1 评论 0原文

我在这里遇到了很多方法重载的问题,并且不知道为什么每次只调用一个方法,而不管我传递的参数数量有多少。下面是示例代码。

[ClassInterface(ClassInterfaceType.AutoDual), ComVisible(true)]
public class myClass
{
    //constructor
    public myClass() {}

    //base method
    public string myfunction(string id, string pk) {return results;}

    //overloading method 1
    public string myfunction(string id, string pk, string param1) { return results;}

    //overloading method 2
    public string myfunction(string id, string pk, string param1, string param2) {return results;}



    [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();
        }

}

因此,当我在 Excel 中测试它时,基本方法运行良好,并且可以获得预期值。但是,如果我使用方法重载尝试其余两个函数,则会失败。他们只是因为某种原因没有被召唤。我在代码中遗漏了什么吗?有人可以帮我吗?非常感谢。

编辑:

通过一些实验,我发现只有一种方法可以被识别,通常是第一种方法。因此,如果我交换基本方法和重载方法 1 之间的顺序,则将调用重载方法 1 而不是基本方法。看起来全班都陷入了第一种方法,无法继续下去。

I am having a lot of troubles with method overloading here and have no idea why only one method gets called each time regardless the number of parameters I pass into. Below is the sample code.

[ClassInterface(ClassInterfaceType.AutoDual), ComVisible(true)]
public class myClass
{
    //constructor
    public myClass() {}

    //base method
    public string myfunction(string id, string pk) {return results;}

    //overloading method 1
    public string myfunction(string id, string pk, string param1) { return results;}

    //overloading method 2
    public string myfunction(string id, string pk, string param1, string param2) {return results;}



    [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();
        }

}

So when I tested it in Excel, the base method worked fine and I could get the expected value. However, it would fail if I tried the rest two functions using method overloading. They simply didn't get called for some reason. Am I missing something in the code? Can anyone help me please? Thanks very much.

Edit:

Through some experiments, it occurs to me that there only 1 method can be recognized, which normally is the first method. So if I swap the order between base method and overloading method 1, the overloading method 1 will be called instead of the base method. Looks like the whole class just gets stuck in the first method and wouldn't go on.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

懷念過去 2024-12-07 07:26:09

COM Interop 不支持重载:请参阅这篇 MSDN 文章。

类型库导出器将通过附加前缀(例如_2)来重命名重载的成员。

COM Interop does not support overloading: see the "Overloading" section in this MSDN article.

The Type Library Exporter will rename overloaded members by appending a prefix (e.g. _2).

坏尐絯 2024-12-07 07:26:09

Excel朋友,您无法对工作表函数进行多态化。一个
称为 GETSALESFORWEEK 的工作表函数只能有一个
入口点。如果您提供两个,请输入 GETSALESFORWEEK(int WeekNumber)
GETSALESFORWEEK(string WeekName) 那么 Excel 2007 将公开这些
功能如 GETSALESFORWEEKGETSALESFORWEEK_2

来源: http://blogs.msdn.com/b/gabhan_berry/archive/2008/04/07/writing-custom-excel-worksheet-functions-in-c_2d00_sharp.aspx

好吧,我想这回答了我的问题问题。遗憾的是,自定义 Excel 函数没有方法重载:(

解决方案:

[ClassInterface(ClassInterfaceType.AutoDual), ComVisible(true)]
public class myClass
{
    //constructor
    public myClass() {}

    //base method
    /**public string myfunction(string id, string pk) {return results;}**/

    //overloading method 1
    /**public string myfunction(string id, string pk, string param1) { return results;}**/

    //just use 1 method, but make the last two arguments optional by setting default values
    public string myfunction(string id, string pk, string param1 = "", string param2 = "") {return results;}

    [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();
    }
}

Excelfriend, you can't polymorphize a a worksheet function. A
worksheet function called, say, GETSALESFORWEEK can only have one
entry point. If you provide two, say GETSALESFORWEEK(int WeekNumber)
and GETSALESFORWEEK(string WeekName) then Excel 2007 will expose these
functions as GETSALESFORWEEK and GETSALESFORWEEK_2.

Source: http://blogs.msdn.com/b/gabhan_berry/archive/2008/04/07/writing-custom-excel-worksheet-functions-in-c_2d00_sharp.aspx

Well I guess that answers my questions. Sadly, no method overloading for custom Excel functions :(

Solution:

[ClassInterface(ClassInterfaceType.AutoDual), ComVisible(true)]
public class myClass
{
    //constructor
    public myClass() {}

    //base method
    /**public string myfunction(string id, string pk) {return results;}**/

    //overloading method 1
    /**public string myfunction(string id, string pk, string param1) { return results;}**/

    //just use 1 method, but make the last two arguments optional by setting default values
    public string myfunction(string id, string pk, string param1 = "", string param2 = "") {return results;}

    [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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文