我应该如何使我的VBA代码与64位Windows兼容?

Gar*_*ill 34 excel 64-bit vba

我有一个在Excel 2007中开发的VBA应用程序,它包含以下代码以允许ShellExecute从以下位置访问该函数Shell32.dll:

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Run Code Online (Sandbox Code Playgroud)

我原来说:

显然,该应用程序将无法在64位版本的Windows上进行编译(仍使用32位Office 2007).我认为这是因为 Declare声明需要更新.

我已经读过Office 2010引入了一个新的VBA运行时(VB7),并且它有一些新的关键字可以在Declare语句中使用,以允许它在64位Windows上正常工作.VB7还有新的预定义编译器常量,以支持条件编译,其中将使用旧的或新的声明,具体取决于应用程序是在32位还是64位Windows上运行.

但是,由于我遇到Office 2007,我需要一个替代解决方案.我有什么选择?(如果可能的话,我真的不想发布我的应用程序的2个单独版本).

但是,根据大卫在下面的回答,我错误地认为我的Declare陈述不起作用的情况.它无法运行的唯一情况是Windows 64位上的Office 2010 64位.因此,Office 2007不是问题.

Ala*_*ain 57

我已经在使用Office 2010的新64位计算机上使用我的内部工具的人遇到了这个问题.

我所要做的就是改变这样的代码行:

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
    (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Run Code Online (Sandbox Code Playgroud)

对此:

#If VBA7 Then
    Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
        (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
#Else
    Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
        (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
#End If
Run Code Online (Sandbox Code Playgroud)

当然,您将确保在两台机器上都可以使用您正在使用的库,但到目前为止,我所使用的任何内容都没有问题.

请注意,在旧的VB6中,PtrSafe甚至不是一个有效的命令,所以它会显示为红色,就好像你有一个编译错误,但它实际上不会给出错误,因为编译器会跳过第一部分if块.

代码外观

使用上述代码的应用程序在Office 2003,2007和2010 32和64位上完美编译和运行.

  • `#if Win64`只在奇怪的情况下才需要,你需要在32位和64位系统上加载两个不同的dll或使用不同签名的函数.为了简单地使传统电子表格在强制VB7的64位计算机上运行,​​没有必要.32位Office 2010有意与所有旧版VB6电子表格兼容,无需任何修改(根据文档). (4认同)
  • @AnonymousType这些说明来自关于VB7和PtrSafe声明的MSDN文档:http://msdn.microsoft.com/en-us/library/ee691831.aspx需要使用PtrSafe来自VB7的使用,而不是使用在64位系统上的Office.64个系统仅支持VB7只是巧合,所以这就是一石二鸟. (3认同)
  • 如果问题是 64 位 office,那么 VBA7 不是答案。您需要 win64 编译常量。VBA7 仍然适用于 Office 2010 32 位。 (2认同)
  • @Alain 我知道这是事后几年,但在 VBA7 语句中,Long 应该是 LongLong,或者最好是 LongPtr,以实现 32 位和 64 位版本之间的兼容性。(来自 https://msdn.microsoft.com/en-us/library/office/gg264421%28v=office.14%29.aspx) (2认同)

Dav*_*nan 6

Office 2007 只有 32 位,所以没有问题。您的问题仅在具有 32 位和 64 位版本的 Office 64 位上出现。

当您只有 Office 2007 时,您不能希望支持使用 64 位 Office 2010 的用户。解决方案是升级。

如果Declare您唯一拥有的是ShellExecute64 位 Office,那么您将无事可做,但是当您无法运行您发布的程序时,支持用户实际上并不可行!想想当他们报告错误时你会怎么做?


Pat*_*ier 5

我找到了这个代码(请注意,有些Long已更改为LongPtr):

Declare PtrSafe Function ShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" (ByVal hwnd As LongPtr, ByVal lpOperation As String, _
ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As _
String, ByVal nShowCmd As Long) As LongPtr
Run Code Online (Sandbox Code Playgroud)

来源:http : //www.cadsharp.com/docs/Win32API_PtrSafe.txt