I have a situation where a VB.Net COM Class in not inheriting functions accessible to the parent class when accessing the interface via VBA.
I.e. I have a VB.Net COM Class (myParent) and a VB.net COM Subclass (myChild).
I have searched and found something similar here: Exposing inherited members of a COM vb.net class but the solution "try this" did not seem to exist?
<ComClass(MyParent.ClassId, MyParent.InterfaceId, MyParent.EventsId)>
Public Class MyParent
#Region "COM GUIDs"
Public Const ClassId As String = "386e628c-872b-41ee-abb2-d2a5dfb4e51e"
Public Const InterfaceId As String = "f4b194f1-9dc9-4f37-93d8-57cb97e05593"
Public Const EventsId As String = "4320826d-a02c-4360-b8b5-4c98569c2b2e"
#End Region
Public Sub New()
MyBase.New()
End Sub
Public Function parent_hello_world() As Boolean
MsgBox("Hello from Parent")
Return True
End Function
End Class
<ComClass(MyChild.ClassId, MyChild.InterfaceId, MyChild.EventsId)>
Public Class MyChild
Inherits MyParent
#Region "COM GUIDs"
Public Const ClassId As String = "65674d29-7bb7-447e-8282-47b9873cec4a"
Public Const InterfaceId As String = "cbcdfb17-c8b9-42e2-bed7-b516b9df6111"
Public Const EventsId As String = "22a8959c-7594-4584-b53d-a087246be623"
#End Region
Public Sub New()
MyBase.New()
End Sub
Public Function child_hello_world() As Boolean
MsgBox("Hello from Child")
Return True
End Function
End Class
And the below code (when executed from VBA) fails:
Sub test_me()
Dim tip As New TestInheritance.MyParent
Dim tic As New TestInheritance.MyChild
tip.parent_hello_world() 'this works - directly from parent
tic.child_hello_world() 'this works - child function
tic.parent_hello_world() 'throws an error - not accessible?
End Sub
Is there any solution for this aside from needing to redefine the interfaces in the child class?
Thanks so much.
COM uses a hyper-pure interface-based paradigm under the hood. You are doing battle with the way it is mapped onto the VB.NET and VBA languages. Implementation inheritance is a problem on the VB.NET side, the compiler rewrites your class to implement two interfaces. The default interface maps the members of the class, a second non-default interface maps the inherited members.
That's a problem on the VBA side, mostly because it has no direct support for interfaces at all. You can only use the default interface directly, obtaining a reference to another interface requires using the Set keyword. Like this:
Dim child As New TestInheritance.MyChild
child.child_hello_world
Dim parent As TestInheritance.MyParent
Set parent = child
parent.parent_hello_world
That works just fine, but certainly no great reason to be enthusiastic about it. Biggest problem is that this is code that is completely undiscoverable. The reason you asked this question, nothing in the auto-complete dialog in the VBA text editor told you that this can work. You'd have to write a manual to let your client programmer know about it. And if the client programmer prefers late-binding then he's completely stuck.
One thing you might consider to help him get it right is exposing the base class directly through a property, about the shortest code you'll ever write:
Public ReadOnly Property Parent As MyParent
Get
Return Me
End Get
End Property
Now it is highly discoverable in VBA and you'll have no problem arriving at:
Dim child As New TestInheritance.MyChild
child.child_hello_world
child.parent.parent_hello_world
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With