微软中文文档 64 位 Visual Basic for Applications 概述
本文内容
Microsoft Visual Basic for Applications (VBA) 是随 Microsoft Office 一起提供的 Visual
Basic 版本。 在 Microsoft Office 2010 中,VBA 包括使 VBA 代码能够在 32 位和 64 位环境中正常运行的语言功能。
备注
默认情况下,Office 2010、2013 和 2016 版将安装 32 位版本。 在安装过程中,必须显式选择安装 64 位版本。 从 Office
2019 和 Microsoft 365 开始,默认为 64 位版本。
如果未将在 Office 2010 版本(VBA 版本 6 和早期版本)之前编写的 VBA 代码修改为在 64 位版本的 Office 上运行,则在 64
位平台上运行此代码会导致出现错误。 导致这些错误的原因是,VBA 版本 6 和早期版本隐式面向 32 位平台且通常包含使用指针和句柄的 32 位数据类型调入
Windows API 的 **[Declare 语句](../../reference/user-interface-help/declare-
statement)** 。 由于 VBA 版本 6 和早期版本没有指针或句柄的特定数据类型,因此它将使用作为 32 位 4 字节数据类型的
Long 数据类型来引用指针和句柄。 64 位环境中的指针和句柄是 8 字节 64 位数量。 这些 64 位数量无法在 32 位数据类型中保留。
备注
仅当 VBA 代码在 64 位版本的 Microsoft Office 中运行需要修改此代码。
有关在 64 位 Office 中运行旧 VBA 代码的问题是,尝试将 64 位加载到 32 位数据类型中会截断 64 位数量。
这会导致内存溢出、代码中出现异常结果以及可能的应用程序失败。
为了解决此问题并使 VBA 代码能够在 32 位和 64 位环境中正常工作,已向 VBA 中添加几种语言功能。 此文档底部的表对新的 VBA
语言功能进行了汇总。 三个重要的新增功能是 LongPtr 类型别名、 LongLong 数据类型和 PtrSafe 关键字。
- LongPtr 。 VBA 现在包括变量类型别名 LongPtr 。 LongPtr 解析为的实际数据类型取决于正在运行的 Office 版本; LongPtr 在 32 位版本的 Office 中解析为 Long , LongPtr 在 64 位版本的 Office 中解析为 LongLong 。 将 LongPtr 用于指针和句柄。
- LongLong 。 LongLong 数据类型是仅在 64 位版本的 Office 中可用的带符号的 64 位整数。 对 64 位整数使用 LongLong 。 转换函数必须用于为更小整型显式分配 LongLong (包括 64 位平台上的 LongPtr )。 不允许“LongLong”到更小的整数的隐式转换。
- PtrSafe 。 PtrSafe 关键字断言 Declare 语句可在 64 位版本的 Office 中安全运行。
重要
现在,所有 Declare 语句在 64 位版本的 Office 中运行时,都必须包括 PtrSafe 关键字。 请务必了解,只将
PtrSafe 关键字添加到 Declare 语句只是表示 Declare 语句显式面向 64 位。 语句中需要存储 64
位的所有数据类型(包括返回值和参数)仍必须进行修改,以保留 64 位数量。
备注
建议的语法是,将 Declare 语句与 PtrSafe 关键字一起使用。 包括 PtrSafe 的 Declare
语句可在 32 位和 64 位平台上的 VBA7 开发环境中正常运行。
若要确保在 VBA7 及早期版本中实现向后兼容性,请使用以下构造:
#If VBA7 Then
Declare PtrSafe Sub...
#Else
Declare Sub...
#EndIf
请考虑以下 Declare 语句示例。 在 64 位版本的 Office 中运行未修改的 Declare 语句将导致出现一个错误,该错误指示
Declare 语句不包括 PtrSafe 限定符。 修改后的 VBA 示例包含 PtrSafe
限定符,但请注意,返回值(指向活动窗口的指针)将返回 Long 数据类型。 在 64 位 Office 中,这是一种错误情况,因为指针必须是 64
位。 PtrSafe 限定符告知编译器 Declare 语句面向的是 64 位,这样语句在执行时就不会出现错误。 不过,由于返回值尚未更新为
64 位数据类型,因此,截断返回值会导致返回不正确的值。
下面是未修改的旧版 VBA Declare 语句示例:
Declare Function GetActiveWindow Lib "user32" () As Long
下面的 VBA Declare 语句示例已修改为包括 PtrSafe 限定符但仍使用 32 位返回值:
Declare PtrSafe Function GetActiveWindow Lib "user32" () As Long
若要重做,必须将 Declare 语句修改为包括 PtrSafe 限定符,并且必须更新语句中需要保留 64
位数量的所有变量,以使这些变量使用 64 位数据类型。
下面是一个 VBA Declare 语句示例,它已修改为包括 PtrSafe 关键字,并已更新为使用适当的 64 位 (
LongPtr ) 数据类型:
Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
总之,为了让代码在 64 位版本的 Office 中运行,您需要找到所有现有 Declare 语句并将其修改为使用 PtrSafe 限定符。
还需要找到并修改这些 Declare 语句中所有引用句柄或指针的数据类型以使用新的 64 位兼容的 LongPtr 类型别名,以及需要保留
64 位整型和新的 LongLong 数据类型的类型。 此外,必须更新包含指针或句柄的所有用户定义类型 (UDT) 和 64 位整型,以使用 64
位数据类型,并确认所有变量赋值是正确的,以阻止出现类型不匹配错误。
编写适用于 32 位和 64 位 Office 的代码
若要编写可在 32 位版本和 64 位版本的 Office 之间移植的代码,只需对所有指针和句柄值使用新的 LongPtr 类型别名即可,而不是
Long 或 LongLong 。 LongPtr 类型别名将被解析为正确的 Long 或 LongLong
数据类型,具体取决于运行的是哪个 Office 版本。
请注意,如果需要执行不同的逻辑(例如,需要在大型 Excel 项目中操作 64 位值),则可以使用 Win64 条件编译常量,如以下部分所示。
编写在 Office 2010(32 位或 64 位)和早期版本的 Office 上运行的代码
若要编写可同时在新版本和旧版本的 Office 中运行的代码,可以将新的 VBA7 和 Win64 条件 [编译器常量](compiler-
constants)组合使用。 Vba7 条件编译器常量用于确定代码是否在版本 7 的 VB 编辑器(Office 2010 随附的 VBA
版本)中运行。 Win64 条件编译器常量用于确定正在运行哪个版本的 Office(32 位或 64 位)。
#if Vba7 then
' Code is running in the new VBA7 editor
#if Win64 then
' Code is running in 64-bit version of Microsoft Office
#else
' Code is running in 32-bit version of Microsoft Office
#end if
#else
' Code is running in VBA version 6 or earlier
#end if
#If Vba7 Then
Declare PtrSafe Sub...
#Else
Declare Sub...
#EndIf
VBA7 语言更新摘要
下表汇总了新 VBA 语言增添功能,并提供了每项增添功能的说明。
名称 | 类型 | 说明 |
---|---|---|
PtrSafe | 关键字 | 断言 Declare 语句是面向 64 位系统的。 在 64 位系统上是必需的。 |
LongPtr | 数据类型 | 映射到 32 位系统上的 Long 或 64 位系统上的 LongLong 的类型别名。 |
LongLong | 数据类型 | 仅适用于 64 位系统的 8 字节数字类型。 数字类型。 整数范围为 |
-9,223,372,036,854,775,808 至 9,223,372,036,854,775,807。
LongLong 仅在 64 位平台上是有效声明类型。 此外, LongLong 不能被隐式转换为较小的类型(例如,不能将
LongLong 分配给 Long )。 这是为了防止意外的指针截断。
允许显式强制,因此,在上一示例中,可以将 CLng 应用于 LongLong 并将结果分配给 Long (仅在 64
位平台上有效)。
^ | LongLong 类型声明字符 | 将文字值显式声明为 LongLong 。 它是声明大于最大 Long 值的
LongLong 文本所必需的(否则,它将隐式转换为 double )。
CLngPtr | 类型转换函数 | 将简单表达式转换为 LongPtr 。
CLngLng | 类型转换函数 | 将简单表达式转换为 LongLong
数据类型(仅在 64 位平台上有效)。
vbLongLong | VarType 常量 | LongLong 整数(仅在 64
位平台上有效)。
DefLngPtr | DefType 语句 | 将一系列变量的默认数据类型设置为
LongPtr 。
DefLngLng | DefType 语句 | 将一系列变量的默认数据类型设置为
LongLong 。