For larger VBA projects (40,000+ lines of code) I cannot properly use interfaces because the Application (I mainly use Excel) will crash quite often. Apparently, this is bec
I don't have a 40K-liner project to test it, but it is known that the VBE debugger's edit-and-continue feature can corrupt the internal storage streams, resulting in "ghost breakpoints".
The VBE itself will corrupt a VBA project, given enough time and enough debugger sessions (and the right amount of pixie dust) - with or without interfaces involved.
I've been coding against interfaces in VBA ever since I've realized that VBA had that capability, and the only problem I've found that was directly caused by Implements
statements, was that if you make a document module (e.g. Sheet1
, or ThisWorkbook
), implement an interface, then you're 100% going to corrupt your project and crash Excel. But with normal user classes? Nope, never had a problem with those.
I would definitely consider edit-and-continue the primary suspect for any stream corruption happening in a VBA project - if the internal ITypeInfo
gets corrupted when the type Implements
an interface, then that would be because of the bug with edit-and-continue, and the Implements
statement "causing it" is really just a symptom.
Project size is also an important factor: 40K LoC is indeed a very large VBA project, and large VBA projects have a tendency to more easily get corrupted too. This can usually be mitigated by regularly removing+exporting all code files and re-importing them back into the project (which forces a "clean rebuild" of the internal storage, I'm guessing) - if your very large project is under source control, then this should be happening regularly.
The VBE does not want you to write OOP. It's actively fighting it: it wants you to cram as much code as possible into as few modules as possible, and since its navigation tooling objectively sucks, you don't get a "find all implementations" command to quickly locate the concrete implementations for your interfaces, so yes the VBE's "go to definition" takes you to an empty method stub - guess what, "go to definition" in Microsoft Visual Studio 2019 does exactly the same (it does give you "go to implementation" too though).
Writing OOP in VBA without Rubberduck to assist with navigation (and everything else) isn't something I would recommend, but then irony has it that Rubberduck doesn't perform very well with very large legacy code bases with lots of late binding (implicit or not).
If project size is related to the problem, then using conditional compilation is actually making things worse, by making the project even larger, and then making Rubberduck fail to "see" pretty much half of the code (late bound member calls can't be resolved, so we lose track of what's being used where), ...which essentially cripples it.
I don't have a solution, only a hunch that edit-and-continue is very likely behind this, since it rewrites chunks of p-code on the fly, and that is already known to be causing problems. If my hunch is correct, then regularly exporting & reimporting all code files should help keep the corruption at bay (and then it makes it easy to put the project under source control, should anything ever become irreparably broken). Avoid code-behind in document modules as much as possible when you do this, and whatever you do NEVER make a worksheet/document module Implements
any interface. Rubberduck has tooling to quickly & easily export/import multiple code files at once to/from a given folder.
I too jumped into using interfaces (years ago) because I thought they were proper COM (and they are) but I too hit problems. So, I stopped using them.
Apart from anything else, if you double click on a method with normal code you jump to the code implementation but with interfaces you jump to an empty method (which is unsatisfactory).
If you really have a class, Foo, that expresses different behaviours worthy enough to break into a separate interface IBar then why not break IBar into an actual separate class Bar and then set an instance of Bar to be a public property of Foo?
That's just a suggestion. I know of no other VBA fix and it is extremely unlikely Microsoft will fix this now.
You could always migrate your code to VisualBasic.Net if you want to preserve you class/interface design.
I'd be delighted if someone actually solves this.