【问题标题】:C# COM Object VBA function or interface marked as restricted or the function uses an automation type not supportedC# COM Object VBA 函数或接口标记为受限或函数使用不支持的自动化类型
【发布时间】:2014-04-09 06:22:31
【问题描述】:

我有以下 C# COM 对象:

[ComVisible(true), GuidAttribute("FD87D0EA-1D00-4189-801A-987D5F8ABD2C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRegistration
{
    string RegisterForm(string server, string database, string username, string password, string catalogId, string date, string AxyaContextFile);
    void RegisterFormAcknowledge(string server, string database, string username, string password, long formId, bool isPrinted, string message);
}

当我从 Word 200 调用方法 RegisterFormAcknowledge 时,我得到以下编译异常: 标记为受限的函数或接口,或函数使用不受支持的自动化类型

这是Word宏代码

    Set printer = New MyCOMObject.Registration
    printer.RegisterFormAcknowledge "test", "test", "test", "test", 12345, False, "CatalogWordTemplate Not Found"

有人知道为什么吗? VB6 不支持长类型? 第一种方法RegisterForm运行良好。

【问题讨论】:

  • public void RegisterFormAcknowledge(string server, string database, string username, string password, long formId, bool isPrinted, string message)
  • 我只是将参数“long formId”更改为“int formId”,它可以工作。有谁知道为什么?
  • 是的,long 是一个带符号的 64 位 整数,它与自动化不兼容。另一方面,int 是一个带符号的 32 位 整数,它是自动化兼容的。
  • 那么,如果我想传递一个大于 int.Max 的值,我应该通过字符串传递,并在 C# 代码中解析它?
  • 视情况而定。如果没有签名,你可以使用uint,并且限制大约是Int32.MaxValue的两倍,即UInt32.MaxValue

标签: c# vba com ms-word


【解决方案1】:
  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

这是一个错误,VB6 和 VBA 需要一个调度接口。 Boilerplate 是使用 ComInterfaceType.InterfaceIsAutoDual 以便客户端代码可以使用早期和后期绑定。您几乎肯定需要在实现此接口的类上修复 [ClassInterface] 属性,因为您实际上可以进行调用,请使用 ClassInterfaceType.None

使用 long 作为参数类型是行不通的,它不是 VB6 支持的类型。 VB1 最初是一个 16 位工具,因此 Integer 是 16 位,Long 是 32 位。 64 位积分没有类型。如果打算使用 VB6 Long,请使用 int。如果不是,那么您需要考虑 Double,最多 15 位或 String。

【讨论】:

  • +1 用于获取属性。我喜欢阅读your answers
  • 不要搞砸了,但 64 位版本的 Office 确实有一个 LongLong 类型,它一个 64 位整数。
【解决方案2】:

C# 的long 是一个有符号64 位 整数,它不是automation-compatible。另一方面,C# 的int 是一个有符号32 位 整数,它是自动化兼容的。

您询问了大整数,例如 372036854775807。

这个特别需要49位来表示。 C# 的double 是标准的double float,可以表示最多需要53 位的整数。

还有 C# 的 decimal,它映射到例如VBA 的Decimal(在VARIANT 内)。如果您愿意,可以将其编组为例如VBA 的 Currency,一个有符号的 64 位整数,在参数定义之前带有 [MarshalAs(UnmanagedType.Currency)] 属性。

对于较大的值,您最好使用string。也就是说,如果你真的可以在 VBA 中处理它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    相关资源
    最近更新 更多