38

This is really bothering me and hindering my development/debugging. Whenever I declare a variable type of the interface I'm implementing, the Locals Window doesn't show it's property values. Instead it just reads

Object doesn't support this property or method

Which is silly, because it absolutely does. In fact it has to in order to fulfill its contract with the Interface.

If I declare the variable as the concrete implementation of the interface, the window works as expected. However, that completely defeats the purpose of coding to the abstraction to begin with.

How can I get the locals window to properly display the class' property values?

Minimal, Complete, and Verifiable Example:

Create an IClass class to use as an interface.

Option Explicit

Public Property Get Name() As String
End Property

Create a Class1 that implements the interface.

Option Explicit

Implements IClass

Public Property Get Name() As String
    Name = "Class1"
End Property

Private Property Get IClass_Name() As String
    IClass_Name = Name
End Property

And lastly, some test code in a regular .bas module to illustrate the issue.

Option Explicit

Public Sub test()
    Dim x As Class1
    Dim y As IClass

    Set x = New Class1
    Debug.Print x.Name

    Set y = New Class1
    Debug.Print y.Name

    Stop
End Sub

enter image description here

RubberDuck
  • 11,933
  • 4
  • 50
  • 95
  • The funky part is that it still knows to expect a `String`... looks like a bug in the locals window! – Mathieu Guindon Mar 19 '15 at 14:02
  • 16
    Probably the simplest solution is to just reverse-engineer the entire VBA IDE, find the Microsoft bug, tweak a bit of assembly-level code, and then...bingo, a working Locals window. – mwolfe02 Mar 19 '15 at 21:12
  • 15
    In fact, I have discovered a truly marvelous implementation of this, which this comment is too narrow to contain. – mwolfe02 Mar 19 '15 at 21:17
  • 4
    @mwolfe02 props for the Fermat reference :D – Blackhawk May 12 '15 at 21:44
  • Is the locals window actually entering the property? What if you add a let and Set? Can you call DebugBreal or my ProcMonDebugOutput to see if proeprties get entered? – Justin Dearing Jul 23 '15 at 16:00
  • I don't know what those are @JustinDearing. The repro is up there if you want to try your hand at it. I've long since given up on this one and no longer work with VBA on a regular basis. – RubberDuck Jul 23 '15 at 16:10
  • 2
    Very interesting issue... Well, this seems to be bug. I'd suggest to create custom *.dll with class which implements interface in VB.NET (Visual Studio). You can simply use it on other machines, but you need to register this dll in GAC. This is my favorite way to use custom classes within VBA. – Maciej Los Jul 29 '15 at 06:21
  • 1
    I'd be interested in seeing a more thorough answer @MaciejLos. If not for me, for the next poor sap. I'm starting to think of [this xkcd](https://xkcd.com/979/) comic when I see this post. – RubberDuck Jul 29 '15 at 12:00
  • Funny comic :smile: If you really interested how to write and use custom com dll within VBA, i can show you a way how to achieve that. Am i start writing the answer? – Maciej Los Jul 30 '15 at 06:04
  • 2
    My past answer: http://stackoverflow.com/questions/29563448/generics-and-com-visible-net-libraries/29565409#29565409 – Maciej Los Jul 30 '15 at 06:14
  • That's a nice workaround if you're able to create a COM visible assembly to use. – RubberDuck Aug 02 '15 at 16:54
  • When would you declare a variable as an interface, then initialize it as an implemented class object? – ClintK Mar 11 '22 at 21:02
  • @MaciejLos Yes nice work around howerever if the interface references any VBA objects theey also require creating interfaces for those in the type library. I'm suprised this VBA bug with the debug watch has persisted this long. – M. Johnstone Jul 30 '23 at 23:31

1 Answers1

-1

I could be wrong, but I think this may be something to do with the way classes are instantiated in VBA.

For example:

Dim oClass1 as Class1
Set oClass1 = new Class1

Is different than

Dim oClass1 as New Class1

In the second case I believe the constructor doesn't get called until the property is accessed.

If you try this, it is sees the property in the Watch window. Notice the New for the IClass - just for Demonstration - I know its not the way to do that :)

Public Sub test1()

    Dim x As Class1
    Dim y As IClass

    Set y = New IClass
    Set x = New Class1
    Debug.Print x.Name
    Debug.Print y.Name
    Stop

End Sub

I suspect its something to do with that and the watch window requires this ... maybe...

PaulG
  • 1,051
  • 7
  • 9
  • Unfortunately, I no longer have access to an Office install to test this. – RubberDuck Feb 02 '17 at 16:34
  • 7
    Newing up the interface defeats the purpose - of course it's going to work, you're looking at a class instance that happens to be named with an `I` prefix - that doesn't make it an interface. The point is that this VBE bug makes debugging code **written against an interface** harder to debug using the locals toolwindow. – Mathieu Guindon Feb 02 '17 at 16:52
  • I know that, thats why I said 'I know its not the way to do that'. My Point was trying to demonstrate the instantiation differences between the two invokations and that the watch Windows internal implementation was probably using that. :) – PaulG Feb 03 '17 at 08:41