Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过COM将对象从VBA传递到.NET时不一致_.net_Vba_Com - Fatal编程技术网

通过COM将对象从VBA传递到.NET时不一致

通过COM将对象从VBA传递到.NET时不一致,.net,vba,com,.net,Vba,Com,我定义了以下接口,以向COM公开.NET类: [InterfaceType(ComInterfaceType.InterfaceIsDual)] [Guid("6A983BCC-5C83-4b30-8400-690763939659")] [ComVisible(true)] public interface IComClass { object Value { get; set; } object GetValue(); void SetValue(object v

我定义了以下接口,以向COM公开.NET类:

[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("6A983BCC-5C83-4b30-8400-690763939659")]
[ComVisible(true)]
public interface IComClass
{
    object Value { get; set; }

    object GetValue();

    void SetValue(object value);
}
此接口的实现非常简单:

[ClassInterface(ClassInterfaceType.None)]
[Guid("66D0490F-718A-4722-8425-606A6C999B82")]
[ComVisible(true)]
public class ComClass : IComClass
{
    private object _value = 123.456;

    public object Value
    {
        get
        {
            return this._value;
        }

        set
        {
            this._value = value;
        }
    }

    public object GetValue()
    {
        return this._value;
    }

    public void SetValue(object value)
    {
        this._value = value;
    }
}
然后,我使用RegAsm注册了此文件,并尝试通过以下代码从Excel调用它:

Public Sub ComInterop()

    Dim cc As ComClass
    Set cc = New ComClass

    cc.SetValue (555.555)

    valueByGetter = cc.GetValue 
    valueByProperty = cc.Value 

    cc.Value = 555.555 

End Sub
当我单步执行此代码时,valueByGetter=555.5555和valueByProperty=555.555与预期一致。然而,我在最后一行得到一个“objectrequired”运行时错误

为什么通过setter方法设置值有效,但通过属性设置失败?我需要做什么改变才能使物业按预期运行


编辑:我得到了一些有用的回答,所以我的补充问题是“这个问题会出现在用其他语言编写的COM客户端上,还是特定于VBA?”。

您需要在最后一行使用Set关键字:

Set cc.Value = 555.555

您是否尝试过类似(vb有点生疏,您明白了):


您的接口将导出到类型库,如下所示:

dispinterface IComClass {
    properties:
    methods:
        [id(00000000), propget]
        VARIANT Value();
        [id(00000000), propputref]             // <=== problem here
        void Value([in] VARIANT rhs);
        [id(0x60020002)]
        VARIANT GetValue();
        [id(0x60020003)]
        void SetValue([in] VARIANT Value);
};
Dim cc As Object ' this one changed from ComClass
Set cc = New ComClass
...
cc.Value = 555.555
dispinterface图标类{
特性:
方法:
[id(00000000),propget]
变量值();

[id(00000000),propputref]/这似乎是
tlbexp
和MS Advice使用如下延迟绑定调用的问题:

dispinterface IComClass {
    properties:
    methods:
        [id(00000000), propget]
        VARIANT Value();
        [id(00000000), propputref]             // <=== problem here
        void Value([in] VARIANT rhs);
        [id(0x60020002)]
        VARIANT GetValue();
        [id(0x60020003)]
        void SetValue([in] VARIANT Value);
};
Dim cc As Object ' this one changed from ComClass
Set cc = New ComClass
...
cc.Value = 555.555
您可以将其提前绑定,然后尝试更简单的修复:

Set cc.Value = CVar(555.555)

当我尝试调试失败时,出现编译错误:object required。您是否尝试将调试器附加到excel进程,并介入并查看其确切位置?不确定您指的是哪个调试器。如果我通过VS.net将excel作为外部程序启动来调试.net代码,我将无法到达设置部分的断点值属性,表示这是excel问题。如果你是说直接调试excel,我不知道从哪里开始-你能给我一些详细信息吗?谢谢。谢谢你提供的信息-不是我想要的答案:)那么这个问题只会发生在VBA客户端吗?我一直在通过VBA测试COM接口,但无法控制客户端将使用的语言。您真的必须支持变体吗?您真的必须支持早期绑定吗?您的问题中没有足够的信息来进行调用。我觉得早期绑定+intellisense使我的API的消费者更容易使用(因此支持调用更少!).至于支持变量(对象),考虑到我需要Value接受的类型,我可以指定Value是一个字符串,并对其进行适当的解释,但这对.NET客户端来说似乎很奇怪(可能并不奇怪,因为它是object…)。在任何情况下,您是否认为原始问题是VBA或更一般的COM问题?您的后期绑定建议有效,但CVar方法会产生与以前相同的错误(我尝试过使用和不使用Set关键字)。您知道我是否会遇到来自以不同语言编写的客户端的相同问题吗?例如,这是COM问题还是VBA问题?这是.Net COM互操作问题。您确定
CVar
不会更改错误消息吗?我再次检查了CVar方法,但它肯定失败:(考虑到这是一个.NET COM互操作问题,并且其他客户端可能没有后期绑定选项,听起来我需要用getter/setter替换属性,或者更改属性类型。这个答案和nobugz的答案都非常有用。他的答案对问题的起因提供了更多的背景信息,so我已经把他的答案定为公认的答案——希望没问题。