Can't Run Macro That Calls 16-bit DLL in 32-bit MS Excel (131525)
The information in this article applies to:
- Microsoft Excel 97 for Windows
- Microsoft Excel for Windows 95
This article was previously published under Q131525 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
Run-time error '453':
Function not defined in specified DLL
Version 97
Run-time error '48':
File not found: <filename>
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
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
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 professionals 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) professionals 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
Modification Type: | Minor | Last Reviewed: | 10/11/2006 |
---|
Keywords: | kbcode kbdtacode kberrmsg kbProgramming KB131525 |
---|
|