我使用Visual Studio 2005 Tools for Office为Excel 2003创建了一个COM加载项。加载项代码如下所示:
[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互操作,我已经注册了DLL:
regasm.exe /tlb NLog4VBA.dll
当我打开Excel时,我转到工具 - >加载项,单击“自动化”,然后添加NLog4VBA.Logger。然后我可以去插入 - >单击功能,从类别列表中选择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在加载项对话框中可见:
我仍然不知道为什么这不起作用: - (
答案 0 :(得分:1)
COMAddIns集合可以通过数字索引进行索引,也可以通过所需组件的 ProgId 字符串进行索引。确保您的ProgId实际上是“NLog4VBA.Logger”(通过.NET中的ProgId
属性)并验证该对象是否已使用此id注册(您可以在注册表中轻松检查,搜索您指定的GUID) )。
答案 1 :(得分:0)
事实证明我的VBA代码非常错误; here答案是礼貌Jan Karel Pieterse:
我认为你需要做点什么 像这样:
Private Sub CommandButton1_Click() 'Declare an object variable using the referenced lib. 'if all is well, intellisense will tell you what the proper object name is: Dim objLogger as NLog4VBA 'Create an instance of the object Set objLogger = New NLog4VBA 'Now use the object objLogger.Object.Debug "My Context", "My Message" End Sub