Can't Run Macro That Calls 16-bit DLL in 32-bit MS Excel

Last reviewed: September 3, 1997
Article ID: Q131525
The information in this article applies to:
  • Microsoft Excel for Windows NT, version 5.0
  • Microsoft Excel for Windows 95, version 7.0
  • Microsoft Excel 97 for Windows

SYMPTOMS

When you upgrade to one of the Microsoft Excel versions listed at the beginning of this article from Microsoft Excel version 5.0 for Windows (a 16-bit application), you may have trouble running macros that you created in the previous version of Microsoft Excel. This includes macros written in the Microsoft Excel macro language (XLM), as well as macros written in the Visual Basic for Applications language.

For example, you may receive one of the following error messages:

   Version 5.0 for Windows NT and Version 7.0
   ------------------------------------------

   Run-time error '48':
   Error in loading DLL

   -or-

   Run-time error '453':
   Function not defined in specified DLL

   Version 97
   ----------

   Run-time error '48':
   File not found: <filename>

   - or -

   Run-time error '453':
   Can't find DLL entry point <function> in <filename>

CAUSE

This problem occurs when you run a macro in a 32-bit version of Microsoft Excel that calls a 16-bit Windows application programming interface (API) or 16-bit Windows dynamic-link library (DLL). For example, if you create a Visual Basic macro in Microsoft Excel version 5.0 for Windows that calls a 16-bit DLL, the macro may return an error message or may not run at all in Microsoft Excel for Windows 95.

If a macro that you created in Microsoft Excel version 5.0 for Windows calls a 16-bit API DLL, you must modify the macro before you can run it in a 32-bit version of Microsoft Excel.

These modifications are necessary because 16-bit API calls and 16-bit DLL calls are not executed correctly from a macro that you run in a 32- bit program.

Note that this is not a problem when you run a macro in Microsoft Excel version 5.0 for Windows (16-bit) under Windows NT or Windows 95, even if the macro calls a 16-bit DLL or API. This is only a problem when you run a macro that calls a 16-bit DLL or API from a 32-bit version of Microsoft Excel.

This is not a limitation of Microsoft Excel. A 32-bit compiled program or code called from a 32-bit program cannot make direct 16-bit API or DLL calls. Additionally, a 16-bit compiled program or code called from a 16-bit program cannot make direct 32-bit API or DLL calls. This limitation in calls between 16-bit and 32-bit layers occurs in both Windows 95 and Windows NT because of the advanced flat-memory-model management systems that these operating environments use; this limitation also occurs because of the way these operating environments load DLLs.

Example

If you run the following macro in 32-bit version of Microsoft Excel, you receive one of the following error messages:

   Run-time error '48':
   Error in loading DLL

   -or-

   Run-time error '48':
   File not found: <filename>

Declare Function WritePrivateProfileString Lib "KERNEL" _
  (ByVal lpApplicationName As String, ByVal lpKeyName As String, _
  ByVal lpString As String, ByVal lplFileName As String) As Integer

Sub ErrorIf32Bit()

   Dim charsWritten As Integer

   ' Use 16-bit version of API function.
   ' The following two lines should be entered as one line.

   charsWritten = WritePrivateProfileString("sectionName", _
      "keyName", "value16", ThisWorkbook.Path & "\myfile.ini")

End Sub

This error message occurs because the code in your macro calls a 16-bit DLL that cannot be loaded in a 32-bit version of Microsoft Excel. If you modify the DECLARE statement in the above example to call "KERNEL32" instead of "KERNEL," you will receive one of the following error messages when you run the example in a 32-bit version of Microsoft Excel:

   Run-time error '453':
   Function not defined in specified DLL

   -or-

   Run-time error '453':
   Can't find DLL entry point <function> in <filename>

This error message may occur in other cases when you modify a 16-bit macro to run in a 32-bit version of Microsoft Excel, because some API functions may be located in different libraries.

RESOLUTION

NOTE: It may be possible to work around this situation by creating a macro that makes calls to the Windows application programming interface (API). This type of programming is supported by the Windows Software Development Kit (SDK) and the Visual Basic, Professional Edition, support groups. The level of support you can receive from these groups depends on the individual support policies of the group. (Microsoft Support Engineers may not be able to assist in specific construction of macros that use API programming.) If you have limited programming experience, you may want to consult one of the Microsoft Solution Providers. Solution Providers offer a wide range of fee-based services, including creating custom macros. For more information about Microsoft Solution Providers, call Microsoft Customer Information Service at (800) 426-9400.

To modify macros you created in Microsoft Excel version 5.0 for Windows, you must modify your code to make Win32 API calls when you run the macro in a 32-bit version of Microsoft Excel. If this is not possible (for example, if you don't have access to the source code of the DLL), you must modify the macro to "thunk" through an intermediate DLL to make the 16-bit API call.

You can also modify your macro so that it is operating-system independent (that is, so the macro will run in both 16-bit and 32-bit versions of Microsoft Excel and Windows). Note however that this modification is more difficult than modifying your macro so that it will run specifically in a 16-bit or 32-bit version of Microsoft Excel.

NOTE: You do not need to modify code that uses OLE Automation or dynamic data exchange (DDE). All OLE and DDE code will continue to work regardless of whether the programs involved are 16-bit or 32-bit. OLE and DDE insulate automation calls, so all combinations of containers (clients) and servers (16/16, 16/32, 32/16, and 32/32) will work under Windows 95 and Windows NT.

Visual Basic Example

Microsoft provides examples of Visual Basic for Applications procedures for illustration only, without warranty either expressed or implied, including, but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. The Visual Basic procedures in this article are provided 'as is' and Microsoft does not guarantee that they can be used in all situations. While Microsoft Product Support Services (PSS) Engineers can help explain the functionality of a particular macro, they will not modify these examples to provide added functionality, nor will they help you construct macros to meet your specific needs. If you have limited programming experience, you may want to consult one of the Microsoft Solution Providers. Solution Providers offer a wide range of fee-based services, including creating custom macros. For more information about Microsoft Solution Providers, call Microsoft Customer Information Service at (800) 426-9400.

In the following example, the macro checks to see if 32-bit Windows is present and uses the appropriate API call for 16-Bit or 32-Bit Windows, whichever is detected. Note that this example does not check for the version of Microsoft Excel. The macro assumes that you are either running a 16-bit version of Microsoft Excel under a 16-bit version of Windows, or a 32-bit version of Microsoft Excel under a 32-bit version of Windows.

NOTE: The first two lines (the DECLARE statements) should be placed at the top of a module sheet, outside of any other subs or functions in the module.

Declare Function WritePrivateProfileString Lib "KERNEL32" Alias _
     "WritePrivateProfileStringA" (ByVal lpApplicationName As String, _
     ByVal lpKeyName As String, ByVal lpString As String, _
     ByVal lplFileName As String) As Long

Declare Function WritePrivateProfileString16 Lib "KERNEL" Alias _
     "WritePrivateProfileString" (ByVal lpApplicationName As String, _
     ByVal lpKeyName As String, ByVal lpString As String, _
     ByVal lplFileName As String) As Integer

Sub MultiOSExample()

   ' Because the different versions of this function return different data
   ' types, this example uses a Variant to receive the return value.

   Dim charsWritten As Variant

   ' Check to see if the string "32-bit" is contained in the name of the
   ' current operating system.

   If InStr(Application.OperatingSystem, "32-bit") Then

      ' If 32-bit is found, use 32-bit version of API function.
      ' The following two lines should be entered as one line.
      charsWritten = WritePrivateProfileString("sectionName", _
          "keyName", "value32", ThisWorkbook.Path & "\myfile.ini")

   Else

      ' If 32-bit is not found, use 16-bit version of API function.
      ' The following two lines should be entered as one line.
      charsWritten = WritePrivateProfileString16("sectionName", _
          "keyName", "value16", ThisWorkbook.Path & "\myfile.ini")

   End If

End Sub

MORE INFORMATION

Microsoft Excel for Windows NT Xlreadme.hlp

For more information about running 16-bit DLLs or XLLs in Microsoft Excel for Windows NT, do the following:

  1. Run the Microsoft Excel Readme Help Contents, Xlreadme.hlp.

  2. Click the "Differences between Microsoft Excel for Windows NT and Microsoft Excel for Windows 3.1" help topic.

  3. Locate the "Differences for developers of DLLs or XLLs" section in this topic.

Information About Porting Your 16-Bit

Office-Based Solutions to 32-Bit Office

Chapter 12 of the Office Resource Kit (beginning on page 360), titled "Support and Troubleshooting," describes how to port your 16-bit Microsoft Office solutions to 32-bit Office. This chapter discusses 16- to-32-bit API issues you may need to handle. To access this information in the Office Resource Kit, run the Ork.exe file located in the Orkchapt folder on the Office Resource Kit compact disc.

Chapter 12 in the Office Resource Kit contains the following sections for additional information:

  • Which API Should Your Solution Code Call?
  • Calling the Win32 API
  • Writing a Single Code Base for 16-Bit and 32-Bit Office Applications
  • Determining Whether a 32-Bit Application Is Running
  • Recompiling DLLs
  • Thunking
  • Advanced Programming Topics: Translating C API Declarations to Visual Basic or Visual Basic for Applications

For additional information about the Office Resource Kit, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q140619
   TITLE     : OFF7: Contents of the MS Office for Windows 95 Resource Kit

For additional information about a similar problem in Microsoft Word, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q120767
   TITLE     : Porting 16-Bit WordBasic Macros to 32-Bit WordBasic
               Macros


Additional query words: 16 bit 32 bit 16bit 32bit
Keywords : kbcode kbprg PgmApi PgmHowTo kberrmsg
Version : 5.0 7.0 97
Platform : WINDOWS
Issue type : kberrmsg
Solution Type : kbcode


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: September 3, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.