API/COM/系统相关
Access Excel VBA程序同时兼容32位和64位的解决办法
2017-05-28 06:43:00

作者:tmtony

来源:Access中国

全世界有很多微软的VB和VBA爱好者,这是一个相当大的人群,即使微软一直在强化Dotnet开发工具,如C#,vb.net,但因为VBA使用者太多了,如Access VBA,Excel VBA,AutoCAD VBA等等,而且还有很多VBA的重度患者,所以即使微软多想改变Office,但Office VBA还是一如既往地保存了下来。但自从微软有64位系统之后,很多以前32位的相关VBA程序就遇到兼容性的问题。

现在可能通过 使用Declare PtrSafe来代替原来的Declear以解决这个问题。如原来32位的:

Private Declare Function acedSetColorDialog Lib _

   "acad.exe" (color As Long, ByVal bAllowMetaColor _

   As Boolean, ByVal nCurLayerColor As Long) As Boolean

在64位系统中,需要写成:

Private Declare PtrSafe Function acedSetColorDialog Lib _

   "acad.exe" (color As Long, ByVal bAllowMetaColor _

   As Boolean, ByVal nCurLayerColor As Long) As Boolean

但能否放上去程序同时兼容32位和64位 Access Excel或 Office呢

可以通过预编译语句来实现 #If #Else #End If 就是预编译语句,只在编译过程中起作用,程序执行时不起作用

如下面的2个示例

同时兼容32位和64位 Access Excel VBA示例1

#If VBA7 Then

    Private Declare PtrSafe Function EnumFontFamilies Lib "gdi32" Alias "EnumFontFamiliesA" (ByVal hdc As Long, ByVal lpszFamily As String, ByVal lpEnumFontFamProc As LongPtr, LParam As Any) As Long

    

    Private Declare PtrSafe Function GetFocus Lib "user32" () As Long

    Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As Long) As Long

    Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long) As Long

#Else

    Private Declare Function EnumFontFamilies Lib "gdi32" Alias "EnumFontFamiliesA" (ByVal hdc As Long, ByVal lpszFamily As String, ByVal lpEnumFontFamProc As Long, LParam As Any) As Long

    

    Private Declare Function GetFocus Lib "user32" () As Long

    Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long

    Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long) As Long

#End If

同时兼容32位和64位 Access Excel VBA示例2

#If VBA7 Then

    'Return the argument to workaround limitations of AddressOf operator

    Private Function GetAddress(nAddress As LongPtr) As LongPtr

        GetAddress = nAddress

    End Function

#Else

    'Return the argument to workaround limitations of AddressOf operator

    Private Function GetAddress(nAddress As Long) As Long

        GetAddress = nAddress

    End Function

#End If

相关注意:

1) 可以看到,代码里使用了一个系统变量“VBA7”,通过这个变量可以辨别VBA系统是否为VBA7,并通过这个判断来加载不同的语句。

另外还可以使用另一个变量是“WIN64”,这个变量可以辨别系统是否为WIN64位系统,并通过它来加载不同的语句。

2)为什么这里用了VBA7而不是用WIN64变量呢,那是因为在2014版以前,虽然是Win64系统,但实际上VBA还是32位系统,Declear声明并不需要加上PtrSaft,所以通过VBA7来着判断会更为准确。

3)大家如果把代码写到VBE编辑器里,会发现有个不完美的地方是,VBA7中对于没有加入PtrSaft的Declear的代码都标注为有误并显示红色,不过还好,显示归显示,运行还是给运行的,因为通过前面的判断语句,那句错误的语句并不会运行到,所以运行时不会出错

通过以上的方法可以完美解决Access Excel Autocad 等VBA程序同时兼容32位和64位的解决办法

另如果是程序中使用了ADO连接ACCESS数据库,由于VBA7是真64位,那些32位的数据库连接方式都彻底失效,所以也要使用64位的连接驱动。

可以参考这篇文章:

64位windows系统如何使用64位的ADO连接Accesss accdb数据库(ACE.OLEDB)

http://www.access-cn.com/info/3661-cn.html