excel - 切换到 64 位 Excel 后如何修复 VBA "type mismatch"错误

标签 excel vba 32bit-64bit

当我运行 32 位版本的 Excel 时,我使用的代码运行良好。在我切换到 64 位版本后,宏坏了。我更新了 dll 调用以使用 LongPtr无处不在,而不是 Long .
有什么方法可以确定哪些参数和返回类型需要为 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是一个指针大小的整数。它必须用于与指针大小相同的事物。
要了解哪些 Windows API 类型应描述为 LongPtr ,一定要看原函数签名,咨询https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types ,通过所有typedef跟踪使用的数据类型s 到基本类型,并使用 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 s 并且只使用 LongPtr分支。

关于excel - 切换到 64 位 Excel 后如何修复 VBA "type mismatch"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63797581/

相关文章:

excel - 从 Excel VBA 运行 Powerpoint sub

excel - 如何在 Excel VBA 中创建 MS Access 运行时对象

java - 当安装了 64/32 位 JVM 版本时,JNLP 应用程序如何选择 JVM 的(正确的位数)版本?

java - Java CRC32 实现在 32 位和 64 位上是否有所不同

Excel VBA - .在工作簿之间查找方法

vba - 为什么这段多行代码中存在VBA语法错误?

从命名范围到默认值的 VBA 数据验证

excel - 如何打开用 Dir 找到的文件?

excel - 查找包含 4 个特定值的所有行?

python - 32 位/64 位系统上的二进制文件?