如何使VBA代码兼容Office 2010 - 64位版本和旧版Office

时间:2010-11-22 23:05:34

标签: vba ms-office 32bit-64bit

当我们迁移到office 2010-64位版本时,我发现了以下函数调用的问题。

Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

根据http://msdn.microsoft.com/en-us/library/ee691831.aspx链接提供的信息。我已经更改了以上调用,它在Office 2010 64位版本上运行良好。

Private Declare PtrSafe Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

问题是,我需要对旧办公室版本进行同样的调用,并且它会在旧版本上引发编译错误。

有没有人知道如何使这个电话适用于Office 2010和旧办公室版本。

4 个答案:

答案 0 :(得分:10)

正如MSDN文章所述,使用条件编译:它适用于Excel 97到Excel 2010 32位& 64位。

#If VBA7 Then
Private Declare PtrSafe Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#Else
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#End if

答案 1 :(得分:1)

我发现整个 VBA7 编译器常量在Internet上都与Office 64位兼容性有关,但与通常所说的相反,该编译器常量检测使用VBA7的Office安装,例如。从Office 2010开始,而不是64位Office。令人困惑的是,如果需要确定您是否正在使用64位版本的Office应用程序,则需要使用 Win64 常量!

尝试使用32位和64位版本的Office,您会明白我的意思:

Sub DemoCompilerConstants()

    #If VBA7 Then
        MsgBox "VBA7"
    #Else
        MsgBox "Not VBA7"
    #End If

    #If Win64 Then
        MsgBox "Win64"
    #Else
        MsgBox "NOT Win64"
    #End If

End Sub

感谢Steve Rindsberg,让我直接说说这个!史蒂夫还补充道:

  

Win64实际上会告诉您您的Office版本   应用是64位的。如果您必须支持Office的旧版本,   您可能希望将其与VBA7检查结合起来以进行特殊情况   无法理解较新编译器的Office应用版本   指令。但是,如果您的代码在32位版本的   Office应用程式,很可能是因为它打击了您的编译器   指令,发现是的,它有VBA7,然后尝试执行   64位API调用,因为它是32位Office,因此无法运行。

因此,这应该是结合VBA7和64位Office兼容性的正确方法:

#If VBA7 Then
  #If Win64 Then ' Declare using PtrSafe for Office 64 bit
    Declare PtrSafe Function ....
  #Else ' Declare for Office 32 bit
    Declare Function ....
  #End If
#Else ' Declare for Office 32 bit
  Declare Function ....
#End If

答案 2 :(得分:0)

如果您使用的是Office 2003,请使用:

#If VBA7 Then
Private Declare PtrSafe Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As
Long)
#Else
Private Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#End if

有效,但是当您保存工作簿并再次重新打开它时,仅保留了与您操作系统对应的代码。 #If然后#Else和#End if已经消失。

答案 3 :(得分:-1)

Jamie Garroch(这里解释了VBA7编译器常量如何无法告诉您代码是否在64位Office应用程序中运行)中提供了出色的信息/答案,VBA编译器的{{1 }}指令可以处理#if个运算符。

这意味着您无需重复您的32位函数声明。您可以简单地做到这一点:

    #If VBA7 And Win64 Then ...
        '64 Bit Declarations: for example ...
        Private Declare PtrSafe Sub API_CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long)
    #Else
        '32 Bit Declarations: for example ...
        Public Declare Sub API_CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, source As Any, ByVal bytes As Long)
    #End If