VBA 6.0和VBA 7.0之间有哪些区别?

50

我注意到Office 2010自带Visual Basic for Applications 7.0。然而,我似乎找不到关于所做更改的文档。是否有摘要来概述这些变化或任何描述差异的资源?

4个回答

46

在VBA6和VBA7之间,没有太多改变。VBA7是为了支持64位的Office和Windows版本而推出的(关于这些差异,请参见下文)。以下是关键更改:

  1. 64位支持,主要用于API调用。这既用于使您的代码与您的操作系统/Office版本配合使用,也用于与其他人的代码配合使用(例如使用Office 2003 / WinXP的用户)。

    • 如果您使用的是64位的Windows版本,但使用的是32位版本的Office,则可以像下面这样声明API调用。

      #If Win64 Then
          Declare PtrSafe Function GetTickCount64 Lib "kernel32"() As LongLong
      #Else
          Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
      #End If
    • 如果您使用的是64位的Windows版本,并且使用的是64位版本的Office,则可以像下面这样声明API调用。

      #If VBA7 Then
         Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
             ByVal lpClassName As String, _
             ByVal lpWindowName As String) As LongPtr
       #Else
         Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal _
             lpClassName As String, ByVal lpWindowName As String) As Long
      #End If
  2. 为了支持此功能,引入了以下内容:

    • 三个新的关键字(2个数据类型和1个修饰符):LongPtrLongLongPtrSafe

    • 一个新函数CLngLng()(例如Int64)

    • 上述新编译常量VBA7Win64


8
@Todd,我想指出,LongPtr是一个别名,当使用64位或32位的字时,它会指向正确的数据类型。因此,在64位office上,LongPtr会指向LongLong,在32位office上会指向Long。下面的语句将在32位和64位office上都能工作。 Declare PtrSafe Function GetTickCount Lib "kernel32" () As LongPtr - Syler
@Syler,你说得很好。我还没有测试过,但是你说的很有道理。 - Todd Main
1
虽然这个答案展示了使用新关键字的可能性,但当涉及到应该做什么时,它可能会误导人。为32-on-64和64-on-64拥有不同的API声明是不正确的,并且意味着不同的架构有不同的Excel文件。正确的方法是仅检查VBA7,并在所有需要指针大小参数的地方使用LongPtr - GSerg
3
特定代码示例中选择GetTickCount/GetTickCount64使得它变得更加混乱,因为它们是两个不同的函数,而不是同一个函数的两个变体,并且它们都存在于32位和64位架构上。@Syler的评论在精神上是正确的,但从技术上讲是错误的,因为GetTickCount的返回值始终是Long,无论Windows的位数如何,因此不应使用LongPtr进行声明。 - GSerg
1
第二个代码示例在代码方面绝对是正确的,但标题不正确:它不是针对64-on-64的,而是*正确的、通用的代码片段,适用于所有Office和Windows位数的组合。 - GSerg

11

8
虽然此链接可能回答了问题,但最好在这里包含答案的基本部分,并提供链接以供参考。仅包含链接的答案可能会因链接页面更改而失效。 - Marco13
2
当然,您是正确的,但请记住,这是SO早期阶段的答案,在这些规范真正被编码之前。我认为接受的答案和这个答案基本上涵盖了所有内容 :) - Lunatik
1
此评论是在审核期间自动插入的(仅包含链接的答案往往会进入低质量审核队列)。 - Marco13

7

VBA7兼容Office的64位版本。


0

还有其他的变化...我收到用户在现场报告说,2007年正常运行的代码现在不再起作用并显示错误。

例如,在VBA6(Excel 2007)中可以正常工作。

PRINT STRING$(80,"=")
mynewdata = MID$(mydata, 15,4)

它打印出由"="字符组成的一行作为可视的分隔线,然后查看 mydata,跳过15个字符并获取其中的4个,结果存储在mynewdata中。 它在VBA7(Excel 2010)中失败。

我找到了一个潜在的解决方法...

PRINT VBA.STRING$(80,"=")
mynewdata = VBA.MID$(mydata, 15,4)

或者

PRINT VBA.STRING(80,"=")
mynewdata = VBA.MID(mydata, 15,4)

一个完整的变更列表仍然会很有帮助...和/或文件转换器。

可能相关的差异记录在:https://riptutorial.com/vba/example/18930/vb-globalnamespace。 - Mark Fernandes
这个限制适用于所有版本的VBA。 - kismert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接