excelcom互操作中的方法重载
本文关键字:方法 重载 互操作 excelcom | 更新日期: 2023-09-27 18:05:50
我在这里遇到了很多方法重载的麻烦,不知道为什么每次只调用一个方法,而不管我传入的参数的数量。下面是示例代码:
[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将被调用,而不是基方法。看起来整个类都被第一个方法卡住了,无法继续。
COM互操作不支持重载:请参阅MSDN文章中的"重载"一节。
类型库导出器将通过添加前缀(例如_2)来重命名重载成员。
Excelfriend, 不能将多态化为一个工作表函数。一个称为
GETSALESFORWEEK
的工作表函数只能有一个入口点。如果你提供两个,就说GETSALESFORWEEK(int WeekNumber)
和GETSALESFORWEEK(string WeekName)
,然后Excel 2007将显示这些功能为GETSALESFORWEEK
和GETSALESFORWEEK_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();
}
}