如何解决VBA“类型不匹配"问题切换到64位Excel后出现错误 [英] How to fix a VBA "type mismatch" error after switching to 64-bit Excel
问题描述
运行32位版本的Excel时,我使用的代码运行正常.切换到64位版本后,宏中断了.我更新了dll调用,以便在各处使用 LongPtr
而不是 Long
.
有什么方法可以确定对于特定的 Declare Function
而言,对于VBA7哪些参数和返回类型需要更改,哪些不需要更改?
I was using code that was working fine when I was running the 32-bit version of Excel. After I was switched to the 64-Bit version, the macro broke. I updated the dll calls to use LongPtr
everywhere instead of Long
.
Is there any way to determine which arguments and return types need to be changed for VBA7, and which don't, for a specific Declare Function
?
这里是一些声明函数"的示例.我已经更新了(实际上还有更多).
Here is an example of some of the "Declare Functions" that I have updated (there were actually several more too).
#If VBA7 Then
Private Declare PtrSafe Function CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, lpInitData As LongPtr) As LongPtr
Private Declare PtrSafe Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As LongPtr, ByVal nWidth As LongPtr, ByVal nHeight As LongPtr) As LongPtr
Private Declare PtrSafe Function DeleteDC Lib "gdi32.dll" (ByVal hdc As LongPtr) As LongPtr
Private Const LOGPIXELSY As Long = 90
#Else
Private Declare CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, lpInitData As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Const LOGPIXELSY As Long = 90
#End If
此代码改编自以下问题的答案: vb宏字符串宽度
This code was adapted from an answer to this question: vb macro string width
相关代码段复制如下:
Private Function GetLabelSize(text As String, font As StdFont) As SIZE
Dim tempDC As Long
Dim tempBMP As Long
Dim f As Long
Dim lf As LOGFONT
Dim textSize As SIZE
tempDC = CreateDC("DISPLAY", vbNullString, vbNullString, ByVal 0)
tempBMP = CreateCompatibleBitmap(tempDC, 1, 1)
我收到一个运行时错误,提示编译错误:类型不匹配".对 CreateDC
的函数调用突出显示,调试器在函数 GetLabelSize
上中断.我不知道哪个变量现在导致错误.我还假设一旦解决了第一个错误,我也会遇到其他错误.
I get a runtime error that just says "Compile Error: Type Mismatch." The function call to CreateDC
is highlighted, and the debugger breaks on the function GetLabelSize
. I have no idea which variable is now causing the error. I'm also assuming that once I fix this first error, I'll have other errors too.
我是否需要将最后一个参数( ByVal 0
)的值作为显式类型的变量传递?如果可以,怎么办?
Do I need to pass the value of that last argument (ByVal 0
) as an explicitly typed variable? If so how?
推荐答案
我更新了dll调用,以便在各处使用
LongPtr
而不是Long
.
您不应该那样做.
通过在函数声明中添加 PtrSafe
,您对编译器的承诺将 LongPtr
放置在需要放置的所有位置,而没有其他地方.
By adding PtrSafe
to a function declaration, you promise to the compiler that you have put LongPtr
in all places where it needs to be, and nowhere else.
LongPtr
是一个指针大小的整数.它必须用于与指针大小相同的事物.
LongPtr
is a pointer-sized integer. It must be used for things that have the same size as a pointer.
要了解哪些Windows API类型应描述为 LongPtr
,您必须查看原始函数签名,请查阅 https://docs.microsoft.com/zh-cn/windows/win32/winprog/windows-data-types ,跟踪所有 typedef
到基本类型使用的数据类型,并对那些指向事物的指针使用 LongPtr
.
To learn which Windows API types should be described as LongPtr
, you must look at the original function signature, consult https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types, track the used data types through all the typedef
s down to the basic types, and use LongPtr
for those that are pointers to things.
对于您所显示的功能,应该是
For the functions that you have shown, that would be
#If VBA7 Then
Private Declare PtrSafe Function CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, ByVal lpInitData As LongPtr) As LongPtr
Private Declare PtrSafe Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As LongPtr, ByVal nWidth As Long, ByVal nHeight As Long) As LongPtr
Private Declare PtrSafe Function DeleteDC Lib "gdi32.dll" (ByVal hdc As LongPtr) As Long
#Else
Private Declare Function CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, ByVal lpInitData As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
#End If
在声明变量以保存 LongPtr
结果时,还需要使用 #If VBA7
:
When you declare variables to hold your LongPtr
results, you need to use #If VBA7
too:
#If VBA7 Then
Dim tempDC As LongPtr
Dim tempBMP As LongPtr
#Else
Dim tempDC As Long
Dim tempBMP As Long
#End If
如果您不必支持 Office 2007及更低版本,您可以放弃 #If VBA7
s,而仅使用 LongPtr
分支.
If you don't have to support Office 2007 and older, you can ditch the #If VBA7
s and only use the LongPtr
branch.
这篇关于如何解决VBA“类型不匹配"问题切换到64位Excel后出现错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!