Microsoft KB Archive/165273

= BUG: XL97 Errors Using OLE Automation =

Article ID: 165273

Article Last Modified on 3/9/2005

-

APPLIES TO


 * Microsoft Visual C++ 2.0 Professional Edition
 * Microsoft Visual C++ 2.1
 * Microsoft Visual C++ 2.2
 * Microsoft Visual C++ 4.0 Standard Edition
 * Microsoft Visual C++ 4.0 Standard Edition
 * Microsoft Visual C++ 4.1 Subscription
 * Microsoft Visual C++ 4.2 Enterprise Edition
 * Microsoft Visual C++ 5.0 Enterprise Edition
 * Microsoft Visual C++ 4.2 Enterprise Edition
 * Microsoft Visual C++ 4.2 Professional Edition
 * Microsoft Visual C++ 5.0 Professional Edition
 * Microsoft Visual C++ 4.2 Professional Edition

-



This article was previously published under Q165273



SYMPTOMS
OLE Automation code that successfully controlled previous versions of Microsoft Excel may fail with Microsoft Excel 97. If the code was generated by a scripting language, you may get an error message similar to the following:

Method does not exist



CAUSE
This problem can be caused by an improperly implemented OLE Automation Controller. An OLE Automation Controller actually makes the calls to a server application's IDispatch interface to allow that server to be controlled by the client.

In this case, the problem relates to how the IDispatch::Invoke method is called. The Invoke method requires that you specify the context of the IDispatch call by passing one or more of the following flags via the wFlags parameter:
 * DISPATCH_METHOD
 * DISPATCH_PROPERTYGET
 * DISPATCH_PROPERTYPUT
 * DISPATCH_PROPERTYPUTREF

These flags indicate whether the function being called via IDispatch should be called as a property or a method.

Previous versions of Microsoft Excel implemented their collection accessor functions as methods. For example, consider the following line of Visual Basic For Applications, Excel edition code: Workbooks(1).Worksheets(1).Range("A1").Value = 10 Workbooks, Worksheets, and Range are implemented as methods in Microsoft Excel version 5.0 and 7.0. However, Microsoft Excel 97 implements these same calls as properties.

If OLE Automation Controllers break when they try to drive Excel 97, it is usually because they are passing DISPATCH_METHOD as the wFlags parameter of IDispatch::Invoke. Because these functions are no longer implemented as methods in Microsoft Excel 97, the Invoke method failS with DISP_E_MEMBERNOTFOUND. If you are using a scripting language on top of the controller, you generally get an error message similar to the one mentioned above.



RESOLUTION
To resolve this problem, modify the OLE Automation Controller code so that calls to IDispatch::Invoke include DISPATCH_PROPERTYGET as part of the wFlags parameter. Though you can pass DISPATCH_PROPERTYGET by itself where these property calls are being made, the best solution is to logically OR this flag with DISPATCH_METHOD (DISPATCH_PROPERTYGET | DISPATCH_METHOD). By doing this, you ensure that the function call succeeds regardless of whether it has been implemented as a property or a method.

It should be emphasized that this problem is not a problem in Microsoft Excel. The problem lies in the implementation of the OLE Automation Controller. The only solution to this problem is to fix the OLE Automation Controller code.

Customers who did not write the OLE Automation Controller (such as those who may be using a scripting language) should contact their vendor for support.

To confirm that this is a problem in the controller code, Visual Basic should be used to automate Microsoft Excel in the fashion attempted by the non-functioning controller. If the Visual Basic test is successful, the problem lies in the controller.



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.



MORE INFORMATION
Developers who have used the Class Wizard in Visual C++ to generate wrapper classes to automate Microsoft Excel may also encounter this problem if they generated the classes from an older type library. Class Wizard reads the type library and calls IDispatch::Invoke with whichever flag is appropriate. When used with an older type library, it sees that the collection accessors are implemented as methods, so it uses the DISPATCH_METHOD flag when it calls these functions. The solution is the same. Logically OR DISPATCH_METHOD with DISPATCH_PROPERTYGET for the wFlags parameter in the Dispatch helper function calls. This results in IDispatch::Invoke being properly called by the wrapper classes.

