Reputation: 10805
I need create Interop VBA.Collection object from C# code
I have reference to Interop.VBA in my project
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
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?)
Upvotes: 5
Views: 6253
Reputation: 22416
I have adapted this for vb.net, and had to fix the key coming to the add, because it's null when missing.
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!
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:
"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.
Upvotes: 0
Reputation: 4850
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.
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);
}
}
Upvotes: 5