Error 97, “Can't call Friend procedure on an object that isn't an instance of the defining class”, is about VBA's Friend scope. A Friend procedure is visible throughout its own project but hidden outside it, and VBA adds a strict condition: it may only be called through a variable declared as the exact class that defines it. Call the same procedure through a variable typed as a base class, an interface the class implements, or Object, and error 97 fires, even though the object really is an instance of the right class. It is a declaration bug, not an object bug.
Dim widget As Object Set widget = New CWidget widget.InternalReset ' error 97: called through Object Dim widget2 As CWidget Set widget2 = New CWidget widget2.InternalReset ' fine: declared as the defining class
Public and accept the wider visibility, or add a Public wrapper on the class that interface-typed callers can use.If the variable is declared as the defining class and error 97 persists, check that the object assigned is truly an instance of that class and not of a look-alike class from another project with the same name. Two CWidget classes in two referenced projects are different types, and Friend knows it even when the names match.
What is a Friend procedure? A procedure scoped between Private and Public: callable from anywhere inside its own project, invisible outside it. It is used in class modules to expose members to sibling code without publishing them to other projects.
Why is Friend stricter than Public about the variable type? Because Friend members are not part of the class's public interface or its vtable in the usual way. VBA resolves them through the exact class type, so the compiler and runtime require the variable to be declared as that class.