1

我在 Excel/VBA 中使用 .NET/ComVisible 程序集时遇到问题。我在 .NET 中将几个参数定义为“对象”,因此它们将在 VBA 中转换为 Variant,因为 VBA 中的可选参数需要使用 Variant 类型。

问题是当我尝试在 Excel/VBA 中使用该对象时,我收到“运行时错误'424':需要对象”。我认为我在 C# 界面中缺少属性,该属性将添加一个“ propput ”方法而不是“ propputref ”方法,该方法将允许变量中的值,但我在互联网上没有找到任何答案,只是类似的问题。我看到了 System.Reflection.BindingFlags,但这似乎只适用于编译时和运行时代码,不适用于接口定义。

底层数据类型是双精度的,我需要它为空或通过 COM/VBA 的双精度。我对字符串参数没有问题,只是变体/双精度。

这是C#接口:

[ComVisible(true)]
[Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ISampleParameters
{
    object GrossObservedValue { get; set; }
    string TableName { get; set; }
    // Rest of parameters removed for simplicity
}

这是 C# 对象:

[ComVisible(true)]
[Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
[ClassInterface(ClassInterfaceType.None)]
public class SampleParameters : ISampleParameters
{
    private double? grossObservedValue;
    private string tableName;

    public object GrossObservedValue
    {
        get
        {
            return grossObservedValue;
        }
        set
        {
            try
            {
                if (value == null)
                    grossObservedValue = null;
                else
                    grossObservedValue = Convert.ToDouble(value);
            }
            catch
            {
                throw;
            }
        }
    }
}

这是VBA的用法:

Dim Parameters As New SampleParameters
Parameters.GrossObservedValue = 1.23
' Causes: Run-time error '424': Object required

这是来自 OleView 的类型库 IDL:

[
  odl,
  uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX),
  version(1.0),
  dual,
  oleautomation,
  custom(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, TempNamespace.ISampleParameters)    
]
interface ISampleParameters : IDispatch {
    [id(0x60020000), propget]
    HRESULT GrossObservedValue([out, retval] VARIANT* pRetVal);
    [id(0x60020000), propputref]
    HRESULT GrossObservedValue([in] VARIANT pRetVal);
    [id(0x60020001), propget]
    HRESULT TableName([out, retval] BSTR* pRetVal);
    [id(0x60020001), propput]
    HRESULT TableName([in] BSTR pRetVal);
};

似乎唯一的解决方案是手动生成 IDL,然后将其导入 .NET,就像在这个线程中使用 VB.NET 和 VB6一样。那是唯一的解决方案吗?这篇关于The Essentials for Using COM in Managed Code的文章也非常好,但没有涵盖在 .NET/C# 中定义接口。

4

1 回答 1

0

此错误通常是由于 COM 组件注册不正确造成的。

您为您的组件使用了什么注册方法?

于 2009-10-02T12:03:50.377 回答