如何在 C# 中创建 VBA.Collection() 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4446755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 12:25:14  来源:igfitidea点击:

How to create VBA.Collection() object in c#

.netvbac#-4.0excel-vbaexcel

提问by Maciej

I need create Interop VBA.Collection object from C# code
I have reference to Interop.VBA in my project

我需要从 C# 代码创建 Interop VBA.Collection 对象
我在我的项目中引用了 Interop.VBA

When I'm calling that:

当我打电话时:

var col = new VBA.Collection()

In runtime I've got an error saying that dll is not registered...
I found that: http://support.microsoft.com/kb/323737/en-us

在运行时我有一个错误说 dll 未注册...
我发现:http: //support.microsoft.com/kb/323737/en-us

It might work but I don't have VB6 compiler on my box.
I wonder you know other workaround (or maybe someone can compile this ActiveX to me?)

它可能会工作,但我的机器上没有 VB6 编译器。
我想知道您知道其他解决方法(或者也许有人可以将这个 ActiveX 编译给我?)

回答by Foole

I haven't tried this, but it might work.

我没有试过这个,但它可能会奏效。

Create an import library for VB6's VBA6.dll. Create your own implementation of its _Collection interface. Use this implementation in place of the VBA.Collection class.

为 VB6 的 VBA6.dll 创建一个导入库。创建您自己的 _Collection 接口实现。使用此实现代替 VBA.Collection 类。

class MyCollection : VBA._Collection
{
    private Dictionary<object, object> _items = new Dictionary<object, object>();

    public void Add(ref object Item, [System.Runtime.InteropServices.OptionalAttribute]ref object Key, [System.Runtime.InteropServices.OptionalAttribute]ref object Before, [System.Runtime.InteropServices.OptionalAttribute]ref object After)
    {
        // Ignoring the Before and After params for simplicity
        _items.Add(Key, Item);
    }

    public int Count()
    {
        return _items.Count;
    }

    public System.Collections.IEnumerator GetEnumerator()
    {
        return _items.Values.GetEnumerator();
    }

    public dynamic Item(ref object Index)
    {
        return _items[Index];
    }

    public void Remove(ref object Index)
    {
        _items.Remove(Index);
    }
}

回答by toddmo

I have adapted this for vb.net, and had to fix the key coming to the add, because it's null when missing.

我已经为 vb.net 调整了这个,并且必须修复添加的密钥,因为它在丢失时为空。

I will edit this post after I test it. I need to make sure it works when VB6 calls a .Net dll, passing it a vba collection as a parameter, and the .Net dll passes another vba collection back as the return value. Man, if it works this will save me so much trouble!

我会在测试后编辑这篇文章。我需要确保它在 VB6 调用 .Net dll,将 vba 集合作为参数传递给它时工作,并且 .Net dll 将另一个 vba 集合作为返回值传递回来。伙计,如果它有效,这将为我省去很多麻烦!

Public Class VBACollection
  Implements VBA._Collection

  Private _items As New Dictionary(Of Object, Object)

  Public Sub Add(ByRef Item As Object, Optional ByRef Key As Object = Nothing, Optional ByRef Before As Object = Nothing, Optional ByRef After As Object = Nothing) Implements VBA._Collection.Add
    ' Ignoring the Before and After params for simplicity
    Key = If(Key, Item)
    _items.Add(Key, Item)
  End Sub

  Public Function Count() As Integer Implements VBA._Collection.Count
    Return _items.Count
  End Function

  Public Function GetEnumerator() As System.Collections.IEnumerator Implements VBA._Collection.GetEnumerator, System.Collections.IEnumerable.GetEnumerator
    Return _items.Values.GetEnumerator()
  End Function

  Public Function Item(ByRef Index As Object) As Object Implements VBA._Collection.Item
    Return _items(Index)
  End Function

  Public Sub Remove(ByRef Index As Object) Implements VBA._Collection.Remove
    _items.Remove(Index)
  End Sub
End Class

EDIT:

编辑:

No, this does not work with VB6. VB6 says:

不,这不适用于 VB6。VB6 说:

"Class does not support Automation or does not support expected interface"

“类不支持自动化或不支持预期的接口”

The class it's talking about here is my class that uses VBACollection instead of VBA.Collection. VBACollection is not an identical stand-in for VBA.Collection. I'd like to find out why and try to fake COM out into accepting it.

它在这里谈论的类是我的类,它使用 VBACollection 而不是 VBA.Collection。VBACollection 不是 VBA.Collection 的完全替代品。我想找出原因并尝试伪造 COM 以接受它。