1

I've developed a VB.NET library (partially developed on C# as well) that heavily depends on inheriting from an abstract generic base class, and I'm trying to figure out the best practice for this. I Sadly have to do it using framework 3.5.

Public MustInherit Class MyBaseClass(Of T)
  Public Whatever As T
End Class

Public Class MyDerivedClass
  Inherits MyBaseClass(Of String)

  Private _myProperty As String

  Public Property MyProperty As String
    Get
      Return _myProperty
    End Get
    Set(value As String)
      _myProperty = value
    End Set
  End Property
End Class

I attach the .tlb file as a reference in VBA (using Excel), and I run the following code:

Dim m As New VBtoVBA.MyDerivedClass
m.MyProperty = "foo"

And I get the error "Run-time error 430: Class does not support Automation or does not support expected interface".

On the other hand, I change the first lines to:

Public MustInherit Class MyBaseClass
  Public Whatever As String
End Class

Public Class MyDerivedClass
  Inherits MyBaseClass

The VBA script works. Hence I assume the issue is with generics (as documented in other sources as well). Dropping the generic feature of my library is not possible, though. The "best" workaround I can think of is to write a third class that includes MyDerivedClass as a field, and works as a non-generic interface to it:

Public Class MyDerivedClassString

  Private _innerObj As New MyDerivedClass

  Public Property MyProperty As String
    Get
      Return _innerObj.MyProperty
    End Get
    Set(value As String)
      _innerObj.MyProperty = value
    End Set
  End Property

  Public Property Whatever As String
    Get
      Return _innerObj.Whatever
    End Get
    Set(value As String)
      _innerObj.Whatever = value
    End Set
  End Property

End Class

This way I can work with it pretty much as I'd like to in VBA:

m.Whatever = "wha"
MsgBox (m.Whatever)

By the way I think that there might be another (better) way to achieve the same result, and i really hope so since m library is made up of dozens of classes.

Many thanks.

16
  • 1
    Were I you, I'd explicitly define a COM interface in the VBNet project, make MyDerivedClass implement it (also, give a GUID to the interface and another to MyDerivedClass), and see if it helps. Commented Apr 10, 2015 at 14:05
  • 3
    Neither COM nor VBA has any notion of generics. Your class will simply not get exported at all. Thus the error. Commented Apr 10, 2015 at 14:05
  • 1
    @Dave the workaround is to not expose generics. Commented Apr 10, 2015 at 14:11
  • 2
    @Med - that's true, but COM doesn't support implementation inheritance either. It needs to create interface types that match the class definitions, the base class' interface will be generic. Always better to declare the interface explicitly so the actual implementation of the class just doesn't matter. Commented Apr 10, 2015 at 14:25
  • 1
    As per my experience, writing COM library for MS Office applications is bit... hard-coded. Note that one interface can be implemented by few classess. Commented Apr 10, 2015 at 14:57

1 Answer 1

8

As i mentioned in comment writing library (dll) for MS Office applications is bit... hard-coded. This dll must exposes methods and properties to be able to use it in COM automation. To be able to achieve that, you need to write interface(s):

Namespace VBtoVBA
    Public Interface IMyDerivedClass
        Property MyProperty As String
    End Interface
End Namespace

then in DerivedClass

Public Class MyDerivedClass
    Inherits MyBaseClass(Of String)
    Implements IMyDerivedClass

    Private _myProperty As String

    Public Property MyProperty As String Implements IMyDerivedClass.MyProperty

Now, go to Project Properties window 1) choose Application tab - click on Assembly Information button and in the next window select Make assembly COM visible checkbox (apply setting using OK button),

Assembly information

2) choose Compile tab - select Register for COM interop checkbox

Register for COM

3) Save project and Build dll

4) Now, go to VBA Code editor in Office application -> References menu. In Reference window add reference to yourDllName.tlb

Now, you can use your dll in Office application ;)

I tested code:

Option Explicit

Sub DoSomething()
Dim m As VBtoVBA.MyDerivedClass

Set m = New VBtoVBA.MyDerivedClass

m.MyProperty = "Something"

MsgBox m.MyProperty


End Sub

and it works as well ;)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.