I\'ve been tracking down this issue for several days, so I thought I\'d post it here to help others with the same problem, as well as learn more about the cause. I\'ve simpl
VBA does not support class polymorphism.
I think you are misunderstanding the purpose of the keyword Implements
.
It's used when you want a class to implement an Interface - not another class ( well, at least not literally because an Interface in VBA is another class module object )
See this answer for better understanding of the Implements keyword in VBA
Also refer to this for info about VBA polymorphism
The issue is not the TypeOf
statement per se. The issue is that you have set up a circular dependency that VBA cannot resolve. As user2140173 mentioned VBA does not truly implement polymorphism.
The circular reference you have created is that the definition of your interface "Parent"
includes (requires existence of) your object "Child"
and the definition of your class "Child"
implements (requires existence of) "Parent"
. Therefore VBA cannot properly create the interface at compile time and the interface class becomes corrupted and inaccessible next time you have saved, closed and re-opened the workbook and VB Editor.
The OP could be misinterpreted as implicating the statement TypeOf .. Is
as being somehow to blame. However, the TypeOf statement is not special. Any statement at all in the interface class that references a class that itself IMPLEMENTS
the interface class will set up the circular dependency problem.
For example:
Person.cs
'Class Person
Option explicit
Public Sub SaySomething()
Dim B as Boy '<--- here we cause the problem!
End sub
Boy.cs
'Class Boy
Option explicit
Implements Person
Private Sub Person_SaySomething()
Debug.Print "Hello"
End sub
So i hope you can see that Boy.cs Implements Person.cs which contains a Boy.cs which Implements a Person.cs which contains a Boy.cs .... VBA goes crazy at this point :)
It's a little unfortunate that the VB Editor doesn't give a more helpful error message than the "Invalid data format" error or the "Error accessing file. Network connection may have been lost." which leaves the User baffled!
The solution is to remove these statement(s) from the source code of the interface class. If this proves difficult to do because you have a lot of business logic actually written in the interface class then a useful approach is to move the business logic out to a separate class. Simply doing this on its own can resolve the compile problem with the Interface and get your code running again. In my own experience, for this very reason I deliberately try to remove any business logic from the interface class to ensure this kind of error cannot occur, and the interface classes become extremely simple - just a list of method signatures. If there is common business logic that I don't want to have to duplicate in each of the classes that will IMPLEMENT my interface then I create an additional class to hold this common business logic and ensure that the interface requires this class to exist. For example:
iMusicalInstrument.cs
'iMusicalInstrument interface
Option Explicit
Property Get Common() as csMusicalInstrumentCommon
End Property
csMusicalInstrumentCommon.cs
'MusicalInstrumentCommon class
Option Explicit
' add any methods you want to be available to all implementers of the interface.
Property Get GUID() as string '<-- just an example, could be any method
GUID = 'function to create a GUID
End Property
csTrumpet.cs
' csTrumpet class
Option Explicit
Implements iMusicalInstrument
Private mCommon As csMusicalInstrumentCommon
Private Sub Class_Initialize()
Set mCommon = New csMusicalInstrumentCommon
End Sub
Private Sub Class_Terminate()
Set mCommon = Nothing
End Sub
Private Property Get iMusicalInstrument_Common() As csMusicalInstrumentCommon
Set iMusicalInstrument_Common = mCommon
End Property
Usage
Public Sub Test()
Dim Trumpet As New csTrumpet
Dim iTrumpet As iMusicalInstrument
Set iTrumpet = Trumpet
Debug.Print iTrumpet.Common.GUID
End Sub
:)