切换到 64 位 Excel 后如何修复 VBA "type mismatch" 错误
How to fix a VBA "type mismatch" error after switching to 64-bit Excel
我使用 运行 Excel 的 32 位版本时工作正常的代码。在我切换到 64 位版本后,宏崩溃了。我更新了 dll 调用以在所有地方使用 LongPtr
而不是 Long
.
有什么方法可以确定哪些参数和 return 类型需要为 VBA7 更改,哪些不需要,对于特定的 Declare Function
?
这是我更新的一些“声明函数”的示例(实际上还有几个)。
#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 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
处中断。我不知道现在是哪个变量导致了错误。我还假设一旦我修复了第一个错误,我也会有其他错误。
我是否需要将最后一个参数 (ByVal 0
) 的值作为显式类型变量传递?如果有怎么办?
I updated the dll calls to use LongPtr
everywhere instead of Long
.
你不应该那样做。
通过将 PtrSafe
添加到函数声明中,您 promise to the compiler 您已将 LongPtr
放在所有需要的地方,而不是其他任何地方。
LongPtr
是一个 pointer-sized 整数 。它必须用于与指针大小相同的事物。
要了解哪些 Windows API 类型应该描述为 LongPtr
,您必须查看原始函数签名,参考 https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types,跟踪使用的数据类型通过所有 typedef
直到基本类型,并使用 LongPtr
作为指向事物的指针。
对于您展示的功能,那将是
#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
:
#If VBA7 Then
Dim tempDC As LongPtr
Dim tempBMP As LongPtr
#Else
Dim tempDC As Long
Dim tempBMP As Long
#End If
如果您不必支持 Office 2007 and older,则可以放弃 #If VBA7
并仅使用 LongPtr
分支。
我使用 运行 Excel 的 32 位版本时工作正常的代码。在我切换到 64 位版本后,宏崩溃了。我更新了 dll 调用以在所有地方使用 LongPtr
而不是 Long
.
有什么方法可以确定哪些参数和 return 类型需要为 VBA7 更改,哪些不需要,对于特定的 Declare Function
?
这是我更新的一些“声明函数”的示例(实际上还有几个)。
#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 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
处中断。我不知道现在是哪个变量导致了错误。我还假设一旦我修复了第一个错误,我也会有其他错误。
我是否需要将最后一个参数 (ByVal 0
) 的值作为显式类型变量传递?如果有怎么办?
I updated the dll calls to use
LongPtr
everywhere instead ofLong
.
你不应该那样做。
通过将 PtrSafe
添加到函数声明中,您 promise to the compiler 您已将 LongPtr
放在所有需要的地方,而不是其他任何地方。
LongPtr
是一个 pointer-sized 整数 。它必须用于与指针大小相同的事物。
要了解哪些 Windows API 类型应该描述为 LongPtr
,您必须查看原始函数签名,参考 https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types,跟踪使用的数据类型通过所有 typedef
直到基本类型,并使用 LongPtr
作为指向事物的指针。
对于您展示的功能,那将是
#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
:
#If VBA7 Then
Dim tempDC As LongPtr
Dim tempBMP As LongPtr
#Else
Dim tempDC As Long
Dim tempBMP As Long
#End If
如果您不必支持 Office 2007 and older,则可以放弃 #If VBA7
并仅使用 LongPtr
分支。