无法访问VBA中的COM公开方法

pea*_*kit 8 .net com vba visual-studio-2008

我试图在VBA中访问COM公开的方法.

问题:我在VBA中看到了所有默认方法(例如GetHashCode,GetTypeToString),但没有看到COM接口的一部分,特别是写成COM可见的(如下getStringValue()所示).

设置细节:

  • Visual Studio 2008
  • Windows 7 x64
  • Office 2007
  • .NET 3.5

接口'IGetMyString.cs'

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace SimpleCOMAssembly
{
    [ComVisible(true), GuidAttribute("4153A1AC-ECE9-4f66-B56C-1DDEB6514D5D")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    interface IGetMyString
    {
        [DispId(1)]
        string getStringValue();
    }
}
Run Code Online (Sandbox Code Playgroud)

实现'GetMyString.cs'

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace SimpleCOMAssembly
{
    [ComVisible(true), GuidAttribute("0A3D4D65-CF50-4020-BF13-77001F8AAABE")]
    [ProgId("SimpleCOMAssembly.GetMyString")]
    [ClassInterface(ClassInterfaceType.None)]
    public class GetMyString : IGetMyString
    {
        public GetMyString() { }

        [ComVisible(true), Description("Get my string")]
        public string getStringValue()
        {
            return "hello";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在Build属性中,我选中了'Make Assembly COM Visible'(见下面的快照)

在此输入图像描述

还要求Visual Studio 2005制作'注册COM互操作'(见下面的快照)

在此输入图像描述

最后,作为一个post build事件,我运行regasm.exe来注册.DLL以及.TLB到注册表,如下所示:

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\regasm /codebase "$(TargetPath)" /tlb:"$(TargetDir)$(TargetName).lib"
Run Code Online (Sandbox Code Playgroud)

在Excel对象资源管理器视图中,我启用了COM服务器(上面写的SimpleCOMAssembly),现在在对象资源管理器中它没有列出COM接口方法(见下文) 在此输入图像描述

有人可以帮我知道我错过了什么导致COM接口方法无法在VBA中显示?

编辑 附加ITypeLib生成的TLB的视图 在此输入图像描述

Han*_*ant 6

Excel 对象浏览器屏幕截图清楚地显示了一个问题。请注意 GetHashcode、GetType 和 ToString 方法是如何可见的。这些是从 System.Object 继承的方法。但是您的代码段明确(并且正确)使用 [ClassInterface(ClassInterfaceType.None)] 以便隐藏类实现。

它不是隐藏的。不太确定这是怎么发生的,早期尝试的旧类型库可以解释它。但是您的构建步骤非常可疑,您提供的帮助太多了。“使程序集类型 COM 可见”选项是强制构建系统公开 .NET 类型的一种非常粗略的方法。但是您的代码正在使用精致的右上小指在喝茶时向上的方式向 COM 公开类型。其中包括 [ComVisible(true)] 属性、复选框的作用以及 [ClassInterface] 属性(复选框不执行的功能)。

所以问题是你要求构建系统实现两个接口。无论它从基类继承什么,在你的情况下是 _Object,加上它从声明中继承的东西,在你的情况下是 IMyGetString。这很好,并且完全兼容 COM,但 VBA 不是一个很好的 COM 使用者。它只喜欢 [Default] 接口,在你的情况下就是 _Object 。从截图中清晰可见。

所以关闭“使程序集 COM 可见”选项。

并在调用 Regasm 的构建后事件或“注册 COM 互操作”复选框之间进行选择。两种方式都这样做只会使您不知道为什么不起作用的可能性增加一倍。只有在需要为 64 位版本的 Office 注册程序集时才需要后期构建。