我使用Visual Studio 2005 Tools for Office创建了一个用于Excel2003的COM加载项。外接程序代码如下所示:
[guid(“eac0992e-ac39-4126-b851-a57ba3fa80b8”)]
[可见(真)]
[程序ID(“nlog4vba.logger”)]
[类接口(ClassInterfaceType.AutoDual)]
公共类记录器
{
公共双调试(字符串上下文、字符串消息)
{
trace.writeline(消息);
返回消息。长度;
}
[ComRegisterFunctionAttribute]
公共静态void寄存器函数(类型类型类型)
{
registry.classesroot.createSubkey(getSubKeyName(type,“programmable”));
registry key key=registry.classesroot.openSubkey(getSubKeyName(type,“inProcServer32”),true);
key.setvalue(“”,system.environment.systemdirectory+@“\mscoree.dll”,registryvaluekind.string);
}
[取消注册功能属性]
公共静态void unregisterfunction(类型类型类型)
{
registry.classesroot.deleteSubkey(getSubKeyName(type,“programmable”),false);
}
私有静态字符串GetSubKeyName(类型类型,字符串SubKeyName)
{
system.text.stringbuilder s=新建system.text.stringbuilder();
s.append(@“clsid \”);
s.append(type.guid.toString().toUpper());
s.append(@“\”);
s.append(子关键字名称);
返回s.toString();
}
}
< /代码>
我已将项目设置为注册COM互操作,并已将dll注册为:
regasm.exe/tlb nlog4vba.dll
< /代码>
打开Excel时,我将转到“工具”->加载项,单击“自动化”,然后添加nlog4vba.logger。然后,我可以转到Insert->函数,从类别列表中选择nlogvba.logger,然后选择Debug。
最终结果是包含如下内容的单元格:
=debug(“my context”,“my message”)。
< /代码>
显示值为:
< PRE> >代码> 10
< /代码>
这就是一切。在我的VBA代码中,我可以转到“工具”->引用并添加nlog4vba。然后我将以下代码添加到工作表上的按钮中:
private sub commandbutton1_click())
application.comaddins(“nlog4vba.logger”).object.debug“我的上下文”,“我的消息”
结束子
< /代码>
这会失败,因为ComAddins(“nlog4vba.logger”)失败的原因是:
运行时错误“9”:下标超出范围
< /代码>
有人能告诉我,我需要做什么才能使我的vba代码可以访问debug()方法(这比从单元格中调用该方法更有用)?
我肯定我这里遗漏了一些简单的东西。
编辑日期:2010/09/07:我已经更新了代码段,以包含下面Jim建议的[ProgID]属性;问题仍然存在。我可以在注册表中看到该对象:
[hkey_classes_root\clsid \ eac0992e-ac39-4126-b851-a57ba3fa80b8]
@=“nlog4vba.logger”(nlog4vba.logger)
[hkey_classes_root\clsid \ eac0992e-ac39-4126-b851-a57ba3fa80b8 \实现的类别]
[hkey_classes_root\clsid \ eac0992e-ac39-4126-b851-a57ba3fa80b8 \实现的类别\ 62c8fe65-4ebb-45e7-b440-6e39b2dbf29]
[hkey_classes_root\clsid \ eac0992e-ac39-4126-b851-a57ba3fa80b8 \inprocserver32]
@=“C:\\windows\\system32\\mscoree.dll”
“threadingModel”=“两者”
“class”=“nlog4vba.logger”类
“assembly”=“nlog4vba,version=1.0.0.0,culture=neutral,publicKeyToken=null”
“runtimeversion”=“2.0.50727版”
“codebase”=“文件:///c:/projects/nlog4vba/nlog4vba/bin/debug/nlog4vba.dll”
[hkey_classes_root\clsid \ eac0992e-ac39-4126-b851-a57ba3fa80b8 \inprocserver32\1.0.0.0]
“class”=“nlog4vba.logger”类
“assembly”=“nlog4vba,version=1.0.0.0,culture=neutral,publicKeyToken=null”
“runtimeversion”=“2.0.50727版”
“codebase”=“文件:///c:/projects/nlog4vba/nlog4vba/bin/debug/nlog4vba.dll”
[hkey_classes_root\clsid \ eac0992e-ac39-4126-b851-a57ba3fa80b8 progid]
@=“nlog4vba.logger”(nlog4vba.logger)
[hkey_classes_root\clsid \ eac0992e-ac39-4126-b851-a57ba3fa80b8 \可编程]
< /代码>
此外,ProgID在“加载项”对话框中可见:

我仍然不知道这为什么不起作用:—(
[Guid("EAC0992E-AC39-4126-B851-A57BA3FA80B8")]
[ComVisible(true)]
[ProgId("NLog4VBA.Logger")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Logger
{
public double Debug(string context, string message)
{
Trace.WriteLine(message);
return message.Length;
}
[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 Interop,并已将DLL注册为:
regasm.exe /tlb NLog4VBA.dll
打开Excel时,我将转到“工具”->加载项,单击“自动化”,然后添加nlog4vba.logger。然后,我可以转到Insert->函数,从类别列表中选择nlogvba.logger,然后选择Debug。
最终结果是一个包含如下内容的单元格:
=Debug("My Context","My Message")
…显示值为:
10
这就是一切。在我的VBA代码中,我可以转到“工具”->引用并添加nlog4vba。然后我将以下代码添加到工作表上的按钮中:
Private Sub CommandButton1_Click()
Application.COMAddIns("NLog4VBA.Logger").Object.Debug "My Context", "My Message"
End Sub
这会失败,因为ComAddins(“nlog4vba.logger”)在以下情况下失败:
Run-time error '9': Subscript out of range
有人能告诉我,我需要做什么才能使我的VBA代码可以访问debug()方法(这比从单元格中调用该方法更有用)?
我肯定我错过了一些简单的东西。
2010/09/07编辑:我已经更新了代码片段以包含Jim在下面建议的[ProgID]属性;问题仍然存在。我可以在注册表中看到该对象:
[HKEY_CLASSES_ROOT\CLSID\{EAC0992E-AC39-4126-B851-A57BA3FA80B8}]
@="NLog4VBA.Logger"
[HKEY_CLASSES_ROOT\CLSID\{EAC0992E-AC39-4126-B851-A57BA3FA80B8}\Implemented Categories]
[HKEY_CLASSES_ROOT\CLSID\{EAC0992E-AC39-4126-B851-A57BA3FA80B8}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]
[HKEY_CLASSES_ROOT\CLSID\{EAC0992E-AC39-4126-B851-A57BA3FA80B8}\InprocServer32]
@="C:\\WINDOWS\\system32\\mscoree.dll"
"ThreadingModel"="Both"
"Class"="NLog4VBA.Logger"
"Assembly"="NLog4VBA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v2.0.50727"
"CodeBase"="file:///C:/projects/nlog4vba/NLog4VBA/bin/Debug/NLog4VBA.dll"
[HKEY_CLASSES_ROOT\CLSID\{EAC0992E-AC39-4126-B851-A57BA3FA80B8}\InprocServer32\1.0.0.0]
"Class"="NLog4VBA.Logger"
"Assembly"="NLog4VBA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v2.0.50727"
"CodeBase"="file:///C:/projects/nlog4vba/NLog4VBA/bin/Debug/NLog4VBA.dll"
[HKEY_CLASSES_ROOT\CLSID\{EAC0992E-AC39-4126-B851-A57BA3FA80B8}\ProgId]
@="NLog4VBA.Logger"
[HKEY_CLASSES_ROOT\CLSID\{EAC0992E-AC39-4126-B851-A57BA3FA80B8}\Programmable]
此外,ProgID在“加载项”对话框中可见:

我仍然不知道为什么这不起作用:-(