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

4
我需要从C#代码中创建Interop VBA.Collection对象。 我的项目中有对Interop.VBA的引用。
当我调用它时:
var col = new VBA.Collection()

在运行时,我收到了一个错误,说dll没有注册...
我找到了这个链接:http://support.microsoft.com/kb/323737/en-us

这可能有用,但是我没有在我的电脑上安装VB6编译器。
我想知道您是否知道其他解决方法(或者也许有人可以为我编译这个ActiveX控件?)


1
那个页面说“只有Visual Basic 6.0应用程序才能创建VBA.Collection类的实例”。你需要Collection做什么?也许有另一种方法可以实现你想要达到的目的。 - Foole
我正在使用为VBA编写的DLL。需要管理其中一个属性,该属性是Collection类型。 - Maciej
2个回答

5

我没有尝试过这个方法,但它可能有效。

为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);
    }
}

你真是太棒了!这个函数运行得很好!在Add()函数中,应该更改Key和Item参数的顺序(即第一个是Key)。 - Maciej
这很酷!如何将Item设置为默认属性,以便您可以执行VBA.Collection(1)并返回第一个项目? - ArcherBird
@ArcherBird,你应该将这个问题作为一个新问题提出来,这样才能得到适当的讨论。 - Foole

0

我已经将其适配到vb.net,并且不得不修复添加时出现的键为空的问题,因为它在缺失时为空。

测试后,我会编辑这篇文章。我需要确保当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

编辑:

不,这无法在VB6中工作。 VB6会显示以下消息:

"类不支持自动化或不支持所期望的接口"

此处所指的类是使用VBACollection而不是VBA.Collection的我的类。 VBACollection不能完全替代VBA.Collection。 我想找出原因并尝试欺骗COM以接受它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接