如何修复 VBA“类型不匹配"切换到 64 位 Excel 后出错 [英] How to fix a VBA "type mismatch" error after switching to 64-bit Excel

查看:41
本文介绍了如何修复 VBA“类型不匹配"切换到 64 位 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/en-us/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 typedefs 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 并仅使用 LongPtr 分支.

If you don't have to support Office 2007 and older, you can ditch the #If VBA7s and only use the LongPtr branch.

这篇关于如何修复 VBA“类型不匹配"切换到 64 位 Excel 后出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆