Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing VBA compiler message for wrong method name

Tags:

Consider the following code:

Public Sub VBACompilerIsMad()      Dim Ap As Application          Dim Wb As Workbook     Dim Ws As Worksheet      Debug.Print Ap.XXX ' No compile error     Debug.Print Wb.XXX ' No compile error     Debug.Print Ws.XXX ' Compile error  End Sub 

When I compile this, I get a compiler error for referring to an inexisting member of Worksheet. However, if I comment out the last line, there is no compiler error, even though neither Application nor Workbook have a method or property XXX. It is as if I declared Ap and Wb as Object variables.

Why does the compiler treat Application / Workbook differently from Worksheet?

Are there any other classes like this, that the compiler seems to treat as if they were Object?

like image 749
Martin Roller Avatar asked Jan 29 '15 15:01

Martin Roller


People also ask

How to find compile error VBA?

Using Debug to Find Compile/Syntax Errors To compile a code, click on the Debug option in the toolbar and click on Compile VBAProject. When you compile a VBA project, it goes through the code and identifies errors (if any). In case it finds an error, it will show you a dialog box with the error.

How do I fix compile errors in VBA?

I have resolved same error by following these 4 steps : Open Excel file which is having issue, press Alt + F11 go into its Visual Basic Editor. From the Tools menu select References ( Note, if references option is disabled in tools menu try closing and reopening file and enable Macro before proceeding next steps)

What is a compile error VBA?

Compile errors refer to a wider group of VBA errors, which include syntax errors. Compile errors also identify problems with your code when considered as a whole. The syntax of each individual line may be correct, but when put together, the lines of your code don't make sense.

How to check error in VBA?

To find compilation errors, we use Debug->Compile VBA Project from the Visual Basic menu. When you select Debug->Compile, VBA displays the first error it comes across. When this error is fixed, you can run Compile again and VBA will then find the next error.


2 Answers

As I have been explained (kudos go respectively), this is a COM feature.

By default COM assumes an interface is extensible, that is, it allows adding members at run time. If that is not the desired behaviour, one can apply the [nonextensible] attribute to the interface definition, which declares the interface only accepts methods explicitly defined in the type library.

dispinterface _Application and dispinterface _Workbook do not have this flag set in the Excel type library, dispinterface _Worksheet does.

Similarly, ADO's dispinterface _Connection does not have [nonextensible], dispinterface _Command does.

To learn which are extensible, add a reference to TypeLib Info in the project's References and run:

Dim t As tli.TLIApplication Set t = New tli.TLIApplication  Dim ti As tli.TypeLibInfo Set ti = t.TypeLibInfoFromFile("excel.exe")  Dim i As tli.InterfaceInfo For Each i In ti.Interfaces     If (i.AttributeMask And tli.TYPEFLAG_FNONEXTENSIBLE) <> tli.TYPEFLAG_FNONEXTENSIBLE Then       Debug.Print i.Name   End If Next 

You will see that almost all interfaces are extensible here, so most of them get pushed out of the debug window and you will only see the last ones. Change the <> to = to print those that are not extensible, there are much less of them.

like image 117
GSerg Avatar answered Sep 18 '22 06:09

GSerg


A bit of a hypothesis:

You can call a stored procedure on an ADODB.Connection object like a native method (at the bottom). (The examples for this on several msdn sites look oddly messed up).
So there is some mechanism like 'anonymous/dynamic methods' in VBS/VBA. It may be a similar mechanism activated here for Application and Workbook classes - although I don't see where and how exactly.

A test supports the basic idea:
I have tested this with a reference to Microsoft ActiveX Data Objects 2.8 Library:

Public Sub testCompiler()     Dim cn As ADODB.Connection     Dim cmd As ADODB.Command      Debug.Print cn.XXX     Debug.Print cmd.XXX End Sub 

cn.XXX does not throw a compile error, cmd.XXX does.

like image 36
KekuSemau Avatar answered Sep 21 '22 06:09

KekuSemau