64 位 Visual Basic for Applications 概述.docx
- 文档编号:8195417
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:31
- 大小:24.53KB
64 位 Visual Basic for Applications 概述.docx
《64 位 Visual Basic for Applications 概述.docx》由会员分享,可在线阅读,更多相关《64 位 Visual Basic for Applications 概述.docx(31页珍藏版)》请在冰豆网上搜索。
64位VisualBasicforApplications概述
64位VisualBasicforApplications概述
MicrosoftVisualBasicforApplications(VBA)是MicrosoftOffice附带的VisualBasic版本。
在MicrosoftOffice2010中,VBA包括可使VBA代码同时在32位和64位环境中正确运行的语言功能。
注意:
默认情况下,Office2010安装32位版本。
在安装过程中,您必须明确选择安装64位版本。
对于在Office2010版本之前(VBA版本6和更早版本)编写的VBA代码,需要修改为在64位Office版本中运行,否则在64位平台上运行时会导致错误。
这是因为,VBA版本6和更早版本完全以32位平台为目标,而且通常包含Declare语句,这些语句调用的WindowsAPI使用32位数据类型的指针和句柄。
因为VBA版本6和更早版本没有用于指针或句柄的特定数据类型,所以,它使用Long数据类型(一种32位4字节的数据类型)来引用指针和句柄。
64位环境中的指针和句柄为8字节64位数。
这些64位数不能包含在32位数据类型中。
注意:
只有在64位版本的MicrosoftOffice中运行VBA代码时,才需要修改VBA代码。
在64位Office中运行旧VBA代码的问题在于,将64位加载到32位数据类型中会截断64位数。
这会导致内存溢出、代码中出现意外结果,并且可能导致应用程序故障。
为解决此问题,以使VBA代码能同时在32位和64位环境中正确运行,新版VBA中增加了几项语言功能。
此文档底部的表总结了这些新的VBA语言功能。
有三个重要的新增功能,分别是:
LongPtr类型别名、LongLong数据类型和PtrSafe关键字。
∙LongPtr-现在,VBA包括一种可变类型别名:
LongPtr。
LongPtr实际解析为哪种数据类型取决于它在哪种Office版本中运行:
在32位版本的Office中LongPtr解析为Long,在64位版本的Office中LongPtr解析为LongLong。
LongPtr用于指针和句柄。
∙LongLong-LongLong数据类型为有符号的64位整数,仅在64位版本的Office中可用。
LongLong用于64位整数。
必须使用转换函数将LongLong(包括64位平台上的LongPtr)显式赋予较小的整型。
不允许将LongLong隐式转换为较小的整数。
∙PtrSafe-PtrSafe关键字声明Declare语句可以在64位版本的Office中安全运行。
现在,在64位版本的Office中运行时,所有Declare语句必须都包括PtrSafe关键字。
必须理解,仅仅将PtrSafe关键字添加到Declare语句中只是表示Declare语句显式针对64位,而语句中需要存储64位(包括返回值和参数)的所有数据类型仍须经过修改才能保存64位数。
注意:
带有PtrSafe关键字的Declare语句为建议的语法。
包括PtrSafe的Declare语句可同时在32位和64位平台上的VBA7开发环境中正确工作。
为确保在VBA7中以及更早版本中的向后兼容性,请使用下面的构造:
#IfVba7Then
DeclarePtrSafeSub...
#Else
DeclareSub...
#EndIf
请考虑下列Declare语句示例。
在64位版本的Office中运行未经修改的Declare语句会导致一个错误,该错误指出Declare语句未包括PtrSafe限定符。
修改后的VBA示例中包含PtrSafe限定符,但请注意,返回值(指向活动窗口的一个指针)返回Long数据类型。
在64位Office上,这是错误的,因为指针应为64位。
PtrSafe限定符告知编译器Declare语句针对64位,因此该语句可以正常执行。
但是返回值没有更新为64位数据类型,因此被截断,从而返回错误的值。
未修改的旧VBADeclare语句示例:
DeclareFunctionGetActiveWindowLib"user32"()AsLong
修改后的VBADeclare语句示例,其中包括PtrSafe限定符,但仍使用32位返回值:
DeclarePtrSafeFunctionGetActiveWindowLib"user32"()AsLong
再次重申,您除了必须修改Declare语句来包括PtrSafe限定符外,还必须更新语句中所有需要保存64位数的变量,以便这些变量使用64位数据类型。
修改后的VBADeclare语句示例,其中包括PtrSafe关键字,并且更新为使用正确的64位(LongPtr)数据类型:
DeclarePtrSafeFunctionGetActiveWindowLib"user32"()AsLongPtr
总而言之,对于要在64位版本的Office中运行的代码,您需要找到并修改所有现有Declare语句以使用PtrSafe限定符。
同时,还需要找到并修改这些Declare语句内所有引用句柄或指针的数据类型以使用新的64位兼容的LongPtr类型别名,并且需要使用新的LongLong数据类型保存64位整数的类型。
此外,还必须更新任何包含指针或句柄以及64位整数的用户定义类型(UDT),使之使用64位数据类型,同时,必须验证所有变量赋值是否正确,以防止发生类型不匹配错误。
编写可同时在32位和64位Office上运行的代码
若要编写可同时在32位和64位版本的Office上运行的代码,只需对所有指针和句柄值使用新的LongPtr类型别名来代替Long或LongLong即可。
LongPtr类型别名将解析为正确的Long或LongLong数据类型,具体取决于运行的是哪种Office版本。
请注意,如果您需要执行不同的逻辑(例如,您需要在大型MicrosoftExcel项目中使用64位值),可以使用Win64条件编译常量,如下面一节所示。
编写可同时在MicrosoftOffice2010(32位或64位)以及以前版本的Office上运行的代码
若要编写可同时在新版本和旧版本的Office中运行的代码,可以使用新的VBA7与Win64条件编译器常量的组合。
Vba7条件编译器常量用来判断代码是否在VB编辑器版本7(Office2010附带的VBA版本)中运行。
Win64条件编译常量用于判断正在运行哪种Office版本(32位还是64位)。
#ifVba7then
'代码正在新VBA7编辑器中运行
#ifWin64then
'代码正在64位版本的MicrosoftOffice中运行
#else
'代码正在32位版本的MicrosoftOffice中运行
#endif
#else
'代码正在VBA版本6或更早版本中运行
#endif
#IfVba7Then
DeclarePtrSafeSub...
#Else
DeclareSub...
#EndIf
VBA7语言更新总结
下表总结了新增的VBA语言功能,并给出每个新增功能的解释:
名称
类型
描述
PtrSafe
关键字
声明Declare语句针对64位系统。
在64位上是必需的。
LongPtr
数据类型
该类型别名映射为32位系统上的Long,或64位系统上的LongLong。
LongLong
数据类型
8字节的数据类型,只在64位系统上可用。
数字类型。
-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常量
VarType常量。
DefLngPtr
DefType语句
将一系列变量的默认数据类型设置为LongPtr。
DefLngLng
DefType语句
将一系列变量的默认数据类型设置为LongLong。
#IfWin64Then
PrivateDeclarePtrSafeFunctionExtractIconLib"shell32.dll"Alias"ExtractIconA"(ByValhInstAsLongPtr,ByVallpszExeFileNameAsString,ByValnIconIndexAsLong)AsLongPtr
DeclarePtrSafeFunctionSendMessageLib"user32"Alias"SendMessageA"(ByValhwndAsLongPtr,ByValwMsgAsLong,ByValwParamAsLongPtr,lParamAsAny)AsLongPtr
DeclarePtrSafeFunctionFindWindowLib"user32"Alias"FindWindowA"(ByVallpClassNameAsString,ByVallpWindowNameAsString)AsLongPtr
#Else
PrivateDeclareFunctionExtractIconLib"shell32.dll"Alias"ExtractIconA"(ByValhInstAsLong,ByVallpszExeFileNameAsString,ByValnIconIndexAsLong)AsLong
PrivateDeclareFunctionSendMessageLib"user32"Alias"SendMessageA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsInteger,ByVallParamAsLong)AsLong
PrivateDeclareFunctionFindWindowLib"user32"Alias"FindWindowA"(ByVallpClassNameAsString,ByVallpWindowNameAsString)AsLong
#EndIf
DeclarationsbyAPIfunction
Functionname
Declarations(32bitfollowedby64bit)
CreateProcess
Westartoffwithacomplicatedonebecauseithasalotofarguments.Afullyfunctionalexampleisincludedbelowtheexampledeclarationlines.
Courtesy:
Theexamplecodewastakenfromthispage
DeclareFunctionCreateProcessLib"kernel32"_
Alias"CreateProcessA"(ByVallpApplicationNameAsString,_
ByVallpCommandLineAsString,_
lpProcessAttributesAsSECURITY_ATTRIBUTES,_
lpThreadAttributesAsSECURITY_ATTRIBUTES,_
ByValbInheritHandlesAsLong,_
ByValdwCreationFlagsAsLong,_
lpEnvironmentAsAny,_
ByVallpCurrentDriectoryAsString,_
lpStartupInfoAsSTARTUPINFO,_
lpProcessInformationAsPROCESS_INFORMATION)AsLong
DeclarePtrSafeFunctionCreateProcessLib"kernel32"_
Alias"CreateProcessA"(ByVallpApplicationNameAsString,_
ByVallpCommandLineAsString,_
lpProcessAttributesAsSECURITY_ATTRIBUTES,_
lpThreadAttributesAsSECURITY_ATTRIBUTES,_
ByValbInheritHandlesAsLong,_
ByValdwCreationFlagsAsLong,_
lpEnvironmentAsAny,_
ByVallpCurrentDriectoryAsString,_
lpStartupInfoAsSTARTUPINFO,_
lpProcessInformationAsPROCESS_INFORMATION)AsLongPtr
'Fullexampleshownbelow,includingthenecessarystructures
#IfVBA7Then
DeclarePtrSafeFunctionCreateProcessLib"kernel32"_
Alias"CreateProcessA"(ByVallpApplicationNameAsString,_
ByVallpCommandLineAsString,_
lpProcessAttributesAsSECURITY_ATTRIBUTES,_
lpThreadAttributesAsSECURITY_ATTRIBUTES,_
ByValbInheritHandlesAsLong,_
ByValdwCreationFlagsAsLong,_
lpEnvironmentAsAny,_
ByVallpCurrentDriectoryAsString,_
lpStartupInfoAsSTARTUPINFO,_
lpProcessInformationAsPROCESS_INFORMATION)AsLongPtr
ConstINFINITE=&HFFFF
ConstSTARTF_USESHOWWINDOW=&H1
PrivateEnumenSW
SW_HIDE=0
SW_NORMAL=1
SW_MAXIMIZE=3
SW_MINIMIZE=6
EndEnum
PrivateTypePROCESS_INFORMATION
hProcessAsLongPtr
hThreadAsLongPtr
dwProcessIdAsLong
dwThreadIdAsLong
EndType
PrivateTypeSTARTUPINFO
cbAsLong
lpReservedAsString
lpDesktopAsString
lpTitleAsString
dwXAsLong
dwYAsLong
dwXSizeAsLong
dwYSizeAsLong
dwXCountCharsAsLong
dwYCountCharsAsLong
dwFillAttributeAsLong
dwFlagsAsLong
wShowWindowAsInteger
cbReserved2AsInteger
lpReserved2AsByte
hStdInputAsLongPtr
hStdOutputAsLongPtr
hStdErrorAsLongPtr
EndType
PrivateTypeSECURITY_ATTRIBUTES
nLengthAsLong
lpSecurityDescriptorAsLongPtr
bInheritHandleAsLong
EndType
PrivateEnumenPriority_Class
NORMAL_PRIORITY_CLASS=&H20
IDLE_PRIORITY_CLASS=&H40
HIGH_PRIORITY_CLASS=&H80
EndEnum
#Else
DeclareFunctionCreateProcessLib"kernel32"_
Alias"CreateProcessA"(ByVallpApplicationNameAsString,_
ByVallpCommandLineAsString,_
lpProcessAttributesAsSECURITY_ATTRIBUTES,_
lpThreadAttributesAsSECURITY_ATTRIBUTES,_
ByValbInheritHandlesAsLong,_
ByValdwCreationFlagsAsLong,_
lpEnvironmentAsAny,_
ByVallpCurrentDriectoryAsString,_
lpStartupInfoAsSTARTUPINFO,_
lpProcessInformationAsPROCESS_INFORMATION)AsLong
ConstINFINITE=&HFFFF
ConstSTARTF_USESHOWWINDOW=&H1
PrivateEnumenSW
SW_HIDE=0
SW_NORMAL=1
SW_MAXIMIZE=3
SW_MINIMIZE=6
EndEnum
PrivateTypePROCESS_INFORMATION
hProcessAsLong
hThreadAsLong
dwProcessIdAsLong
dwThreadIdAsLong
EndType
PrivateTypeSTARTUPINFO
cbAsLong
lpReservedAsString
lpDesktopAsString
lpTitleAsString
dwXAsLong
dwYAsLong
dwXSizeAsLong
dwYSizeAsLong
dwXCountCharsAsLong
dwYCountCharsAsLong
dwFillAttributeAsLong
dwFlagsAsLong
wShowWindowAsInteger
cbReserved2AsInteger
lpReserved2AsByte
hStdInputAsLong
hStdOutputAsLong
hStdErrorAsLong
EndType
PrivateTypeSECURITY_ATTRIBUTES
nLengthAsLong
lpSecurityDescriptorAsLong
bInheritHandleAsLong
EndType
PrivateEnumenPriority_Class
NORMAL_PRIORITY_CLASS=&H20
IDLE_PRIORITY_CLASS=&H40
HIGH_PRIORITY_CLASS=&H80
EndEnum
#EndIf
PrivateFunctionSuperShell(ByValAppAsString,ByValWorkDirAsString,dwMillisecondsAsLong,_
ByValstart_sizeAsenSW,ByValPriority_ClassAsenPriority_Class)AsBoolean
DimpclassAsLong
DimsinfoAsSTARTUPINFO
DimpinfoAsPROCESS_INFORMATION
'Notused,butneeded
Dimsec1AsSECURITY_ATTRIBUTES
Dimsec2AsSECURITY_ATTRIBUTES
'Setthestructuresize
sec1.nLength=Len(sec1)
sec2.nLength=Len(sec2)
sinfo.cb=Len(sinfo)
'Settheflags
sinfo.dwFlags=STARTF_USESHOWWINDOW
'Setthewindow'sstartupposition
sinfo.wShowWindow=start_size
'Setthepriorityclass
pclass=Priority_Class
'Starttheprogram
IfCreateProcess(vbNullString,App,sec1,sec2,False,pclass,_
0&,WorkDir,sinfo,pinfo)Then
'Wait
'
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 64 Visual Basic for Applications 概述