ACC97: Cannot Call Class Module Methods from MS Access Objects

Last reviewed: June 24, 1997
Article ID: Q170532
The information in this article applies to:
  • Microsoft Access 97

SYMPTOMS

Advanced: Requires expert coding, interoperability, and multiuser skills.

When you call a class module method directly from a query, form, report, or macro, you receive an error message.

This article assumes that you are familiar with Visual Basic for Applications and with creating Microsoft Access applications using the programming tools provided with Microsoft Access. For more information about Visual Basic for Applications, please refer to the "Building Applications with Microsoft Access 97" manual.

CAUSE

In order to call a class module procedure, the calling object must initialize an instance of the class. Microsoft Access objects, such as queries, forms, reports, and macros, cannot automatically initialize new instances of a user-defined class. Only a Visual Basic for Applications procedure can initialize a new instance of a user-defined class.

RESOLUTION

There are two possible workarounds.

Method 1

Store the procedure in a standard module if you plan to call it from a query, form, report, or macro. If the procedure is in a standard module, you do not need to create a new instance of a user-defined class every time you call it. This is the recommended method.

Method 2

Create a procedure in a standard module that initializes an instance of the class. The procedure in the standard module then calls the procedure stored in the class module and passes it any necessary arguments. This is typically known as a "wrapper" procedure.

Using a wrapper procedure in this manner is not recommended because additional overhead is created when the object is initialized. In some instances, this can cause more overhead to be created than expected. For instance, calling a wrapper procedure from a query causes additional overhead to be created for each record that the query contains. To make the query more efficient and use less resources, move the code in the class module to a standard module so that the additional overhead can be eliminated.

The following example demonstrates how to create a class module method named MultiplyByTen and a wrapper procedure named CallMultiplyByTen, that makes the class method available to other Microsoft Access objects. It then demonstrates how to call the wrapper procedure from a query.

  1. Open the sample database Northwind.mdb.

  2. On the Insert menu, click Class module.

  3. Type the following line in the Declarations section if it is not already there:

    Option Explicit

  4. Type the following procedure:

    Function MultiplyByTen(clsVar As Variant) As Variant

              MultiplyByTen = clsVar * 10
           End Function
    
    

  5. Close and save the class module as MultiplyClass.

  6. Create a standard module and type the following line in the Declarations section if it is not already there:

    Option Explicit

  7. Type the following procedure:

    Function CallMultiplyByTen(stdVar As Variant) As Variant

              Dim clsMultiply As New MultiplyClass
              CallMultiplyByTen = clsMultiply.MultiplyByTen(stdVar)
           End Function
    
    

  8. To test this function, type the following line in the Debug window, and then press ENTER.

    ?CallMultiplyByTen(5)

    Note that the procedure returns the number 50 to the Debug window.

  9. Close and save the module as Module1.

  10. Create a new query based on the Orders table with the following fields:

    Query: Query1 ----------------------------------------- Type: Select Query

    Field: OrderID

              Table: Orders
           Field: Freight
              Table: Orders
           Field: EXPR1: CallMultiplyByTen([Freight])
    
    

  11. Run the query. Note that the class module method returns a value for each record.

MORE INFORMATION

Steps to Reproduce Behavior

Create a class module method:

  1. Open the sample database Northwind.mdb.

  2. On the Insert menu, click Class module.

  3. Type the following line in the Declarations section if it is not already there:

          Option Explicit
    

  4. Type the following procedure:

          Function MultiplyByTen(clsVar As Variant) As Variant
    
             MultiplyByTen = clsVar * 10
          End Function
    
    

  5. Close and save the class module as MultiplyClass.

Call the class module method from a query:

  1. Create a new query based on the Orders table:

          Query: ClassTestQuery
          -------------------------------------
          Type: Select Query
    

          Field: Freight
    
             Table: Orders
          Field: Expr1:MultiplyByTen([Freight])
    
    

  2. Run the query. Note that you receive the following error message:

          Undefined function 'MultiplyByTen' in expression.
    

Call the class module method from a form:

  1. Create a new form based on the Orders table:

          Form: ClassTestForm
          -------------------------------------
          ControlSource: Orders Table
    

          Text box:
          Name: Freight
          Caption: Freight
          ControlSource: Freight
          Text box:
          Name: Text1
          Caption: Text1
          ControlSource: =MultiplyByTen([Freight])
    

  2. Switch the form to Form view. Note that the error "#Name?" appears in Text1.

Call the class module method from a report:

  1. Create a new report based on the Orders table:

          Report: ClassTestReport
          ---------------------------------------
          ControlSource: Orders Table
    

          Text box:
          Name: Freight
          Caption: Freight
          ControlSource: Freight
          Text box:
          Name: Text1
          Caption: Text1
          ControlSource: =MultiplyByTen([Freight])
    

  2. Preview the report. An "Enter Parameter Value" dialog box appears and prompts you to enter the value of MultiplyByTen. Click OK.

    Note that Text1 contains "#Error."

Call the class module method from a macro:

  1. Create a new macro:

          Macro Name            Action
          ----------------------------
          ClassTestMacro        MsgBox
    
          ClassTestMacro Action
          -----------------------------
          MsgBox
             Message: =MultiplyByTen(5)
             Beep: Yes
             Type: None
    
    

  2. Save the macro and run it. Note that you receive the following error message:

          The expression you entered has a function name that Microsoft
          Access can't find.
    

    You may also receive the following error message when you call a class module method directly from a macro:

          Microsoft Access can't find the name <class name> you entered in
          the expression.
    

REFERENCES

For more information about class modules, search the Help Index for "class modules, overview."

For more information about programming with class modules, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q160007
   TITLE     : ACC97: Introduction to Stand-Alone Class Module Programming
 

	
	


Keywords : kbcode kbprg PgmCM PgmHowTo
Version : 97
Platform : WINDOWS
Hardware : x86
Issue type : kbprb
Resolution Type : kbworkaround


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: June 24, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.