vba代码对象编程方法详解.docx
《vba代码对象编程方法详解.docx》由会员分享,可在线阅读,更多相关《vba代码对象编程方法详解.docx(42页珍藏版)》请在冰豆网上搜索。
vba代码对象编程方法详解
VBA代码对象编程方法详解
一、前言
本文所说的VBA代码编程,即通过编程方法创建、删除或编辑VBA工程部件、模块或代码程序对象,还可以通过VBA代码创建新的代码,以此可以实现VBA的二次开发。
VBA代码编程,也就是所谓的VBA可扩展性。
要实现VBA扩展功能,或者说实现对VBA代码的编程,我们必须事先完成以下相关设置。
1.1引用VBA扩展类库(MicrosoftVisualBasicForApplicationsExtensibility5.3)
在ACCESS2003中扩展库文件为:
VBE6EXT.OLB,你可以在VBE(VisualBasicEditor即VB编辑器)窗口,点菜单[工具]—[引用],在[引用对话框]中钩,来手动引用该扩展类库,你也可以通过代码实现对其的引用。
DimrefAsReference'申明引用类对象
OnErrorResumeNext'避免因重复引用造成的错误提示
'通过扩展库标识号,主版本号,次版本号完成引用
Setref=References.AddFromGuid("{0002E157-0000-0000-C000-000000000046}",5,3)
1.2需要启用编程方式访问VBA项目(仅在EXCEL中需设定)
在Excel2003和更早版中,需设定允许对VBA项目的访问,否则将报错。
ACCESS则不需对该项进行设定。
点选菜单[工具](在Excel中,而不是在VBA编辑器中)—[宏]—[安全性],在[安全对话框]中,单击[可靠发行商]页,点选[信任对于“VisualBasic项目”的访问]项(见下图)
注册表键值:
HKLM\Software\Microsoft\Office\11.0\Excel\Security\AccessVBOM",1,"REG_DWORD"
键值为:
1,则钩选;0,则取消钩选
二、VBA的可扩展模型对象简介
●LibraryVBIDE(扩展库)
路径:
C:
\ProgramFiles\CommonFiles\MicrosoftShared\VBA\VBA6\VBE6EXT.OLB
描述:
MicrosoftVisualBasicforApplicationsExtensibility5.3
●VBE(VB编辑器)
指VB编辑器,为根对象,其包含所有其它可在VisualBasicforApplications中表示的对象和集合。
●VBProject(工程)
VB工程(或称项目)中包含了所有的代码模块和部件。
VB项目可包含若干个VB部件对象。
●VBComponent(部件)
代表包含在工程中的部件对象,如:
类模块或标准模块。
部件(VBComponent)对象的Type属性:
常数
值
描述
Vbext_ct_StdModule
1
标准模块
Vbext_ct_ClassModule
2
类模块
Vbext_ct_MSForm
3
Microsoft窗体(非ACCESS类窗体)
●CodePane(代码窗格)
用CodePane对象来操作CodePane中可视文本的位置或者代码窗格中显示的文本选择。
●CodeModule(代码模块)
代码模块是VB部件VBA源代码,可用CodeModule对象来修改(添加、删除、编辑)与部件相关联的代码
CodePane或CodeModule内程序类别(prockind)常数:
常数
值
描述
vbext_pk_Proc
0
指定所有过程除了Property过程。
vbext_pk_Let
1
指定一个赋值给属性的过程。
vbext_pk_Set
2
指定一个给对象设置引用的过程。
vbext_pk_Get
3
指定一个返回属性值的过程。
以上为VBA的可扩展模型部分对象(非全部对象),其它模型对象请参阅帮助。
三、工程对象(Project)
表示一个工程。
可用VBProject对象设置工程的属性、访问VBComponents集合以及访问References集合。
通常我们会用ActiveVBProject返回“工程”窗口中选定的工程,但在实际编程中,无论此工程是否被显式地选定,都只有一个工程是活动的。
3.1判断工程是否锁定
通过工程Protection属性,判断工程锁定状态。
工程Protection属性(只读),指示工程是否处于保护状态。
返回的值为一事先定义好的常量,表示工程的状态。
Protection属性常量:
常数
值
描述
Vbext_pp_none
0
常量代表指定的工程未被保护。
vbext_pp_locked
1
常量代表指定的工程是被锁住。
3.1.1判断工程是否锁定自定义函数
'函数功能:
判断工程是否锁定
PublicFunctionVBProjectlocked(OptionalVBProjAsVBProject=Nothing)AsBoolean
DimProjAsVBProject
'如未指定工程,则为当前工程
IfVBProjIsNothingThen
SetProj=VBE.ActiveVBProject
Else
SetProj=VBProj
EndIf
'判断工程是否锁定
IfProj.Protection=vbext_pp_lockedThen
VBProjectlocked=True
Else
VBProjectlocked=False
EndIf
EndFunction
3.1.2调用自定义函数,判断当前工程是锁定示例
'函数输出为真(True),否则当前工程锁定
IfVBProjectlocked=TrueThen
MsgBox"工程已锁定"
Else
MsgBox"工程未锁定"
EndIf
3.2获得工程名
'获得当前工程名
VBE.ActiveVBProject.Name
四、部件对象(VBComponent)
代表一个包含在工程中的部件,例如类模块或标准模块。
使用VBComponent对象访问与部件关联的代码模块CodeModule或改变部件的属性设置。
4.1添加工程部件
4.1.1向当前工程添加部件公用过程
'***********************************************************************
'公用过程:
添加模块或指定名模块
'ComponentType部件类型(可选参数),默认为标准模块
'VBCompName部件名(可选参数),默认不指定部件名
'***********************************************************************
PublicSubAddVBComponents(OptionalComponentTypeAsvbext_ComponentType=1,_
OptionalVBCompNameAsString="")
DimVBProjAsVBProject'申明工程(项目)对象
DimVBCompsAsVBComponents'申明部件集合
'设定为当前工程
SetVBProj=VBE.ActiveVBProject
设定为当前工程部件集合
SetVBComps=VBProj.VBComponents
'判断是否指定部件名,未指定则按默认名建立指定类型部件
IfVBCompName=""Then
VBComps.Add(ComponentType)
Else
VBComps.Add(ComponentType).Name=VBCompName
EndIf
EndSub
4.1.2调用自定义过程,添加标准模块
'例一:
以默认名添加标准模块
CallAddVBComponents
'例二:
以指定名“我的模块”添加标准模块
CallAddVBComponents(,"我的模块")
4.1.3调用自定义过程,添加类模块
'例一:
以默认名添加类模块
CallAddVBComponents
(2)
'例二:
以指定名“我的类模块”添加标准模块
CallAddVBComponents(2,"我的类模块")
4.1.4调用自定义过程,添加(MSForm)窗体
'例一:
以默认名添加MSForm窗体
CallAddVBComponents(3)
'例二:
以指定名“我的窗体”添加MSForm窗体
CallAddVBComponents(3,"我的窗体")
说明:
这里窗体是指“Microsoft窗体”,而非ACCESS通常意义所说的窗体,ACCESS窗体实际为ACCESS类对象,你可以通过CreateForm方法创建一个ACCESS对象窗体。
4.2移除工程中部件
4.2.1移除当前工程部件自定义过程
'************************************************************************
'公用过程:
移除指定部件或删除某类部件
'ComponentType部件类别(可选参数),默认为标准模块
'VBCompName部件名(可选参数),默认不指定部件名
'***********************************************************************
PublicSubRemoveVBComponents(OptionalVBCompTypeAsvbext_ComponentType,_
OptionalVBCompNameAsString="")
DimVBProjAsVBProject'申明工程对象
DimVBCompAsVBComponent'申明部件对象
DimVBCompsAsVBComponents'申明部件集合
'设定为当前工程
SetVBProj=VBE.ActiveVBProject
'设定为当前工程部件
SetVBComps=VBProj.VBComponents
'判断是否指定部件名,如未指定则删除所有指定类型部件
IfVBCompName<>""AndVBCompType=0Then
VBComps.RemoveVBComps(VBCompName)
Else
ForEachVBCompInVBComps
IfVBComp.Type=VBCompTypeThen
VBComps.RemoveVBComps(VBComp.Name)
EndIf
Next
EndIf
EndSub
4.2.2调用自定义过程,移除指定类型所有部件示例
'移除指定所有类模块
CallRemoveVBComponents(vbext_ct_ClassModule)
4.2.3调用自定义过程,移除指定名部件示例(无需指定部件类型)
'移除指定名部件,实例:
指定“我的窗体”
CallRemoveVBComponents(,"我的窗体")
4.3列举部件名及类型信息
4.3.1获得部件类型自定义函数
'-------------------------------------------------------------------------------
'函数功能:
根据所获取部件类型常量值,获得部件类别名
'-------------------------------------------------------------------------------
FunctionComponentTypeToString(ComponentTypeAsvbext_ComponentType)AsString
SelectCaseComponentType
Casevbext_ct_ClassModule
ComponentTypeToString="类模块"
Case100
ComponentTypeToString="其它"
Casevbext_ct_MSForm
ComponentTypeToString="微软窗体"
Casevbext_ct_StdModule
ComponentTypeToString="标准模块"
CaseElse
ComponentTypeToString="未知类:
"&CStr(ComponentType)
EndSelect
EndFunction
4.3.2获取工程中所有部件名及类型自定义函数
'----------------------------------------------------------------------------------------
'函数功能:
列出所有部件名及类型
'调用:
ComponentTypeToString函数,获取部件类型
'----------------------------------------------------------------------------------------
PublicFunctionAllVBComponentsAndType()AsString
DimVBCompAsVBComponent'申明工程部件
DimVBCompsAsVBComponents'申明部件集合
DimstrCompsAsString'输出结果
DimstrObjNameAsString'对象名
DimstrTypeAsString'类型名
SetVBComps=VBE.ActiveVBProject.VBComponents
'遍历部件集合,将部件名及类型值赋值给变量
ForEachVBCompInVBComps
strObjName=VBComp.Name
strType=ComponentTypeToString(VBComp.Type)
'如果为其它类型,判断是ACCESS窗体、报表或其它对象
IfstrType="其它"Then
IfInStr(strObjName,"Form")>0Then
strType="窗体"
ElseIfInStr(strObjName,"Report")>0Then
strType="报表"
Else
strType="其它"
EndIf
EndIf
'将获取的部件名及类型逐行输出
strComps=strComps&strObjName&Space(12)&strType&vbCrLf
Next
AllVBComponentsAndType=strComps'赋值输出
EndFunction
4.4判断部件是否存在
4.4.1判断部件是否存在自定义函数
'-----------------------------------------------------------------------
'函数功能:
判断指定模块是否存在,存在输出为True
'-----------------------------------------------------------------------
PublicFunctionVBComponentExists(ByValVBCompNameAsString)AsBoolean
DimVBProjAsVBProject
OnErrorResumeNext
SetVBProj=VBE.ActiveVBProject
'存在输出为True,否则为False
VBComponentExists=CBool(Len(VBProj.VBComponents(VBCompName).Name))
EndFunction
4.4.2判断指定模块是否存在调用示例
IfVBComponentExists("模块1")=FalseThen
MsgBox"不存在"
Else
MsgBox"存在"
EndIf
4.5导入部件文件添加部件
4.5.1导入部件自定义过程
'导入部件文件添加部件
'输入参数:
FileName(字符串变量)指示欲添加部件的路径及文件名
PublicSubImportFilesToVBComps(FileNameAsString)
DimVBProjAsVBProject
DimVBCompsAsVBComponents
OnErrorResumeNext
SetVBProj=VBE.ActiveVBProject
SetVBComps=VBProj.VBComponents
'导入指定部件文件,添加部件
VBComps.Import(FileName)
EndSub
4.5.2导入部件文件示例
'调用示例:
从指定C盘导入部件文件"模块1"添加到当前工程
CallImportFilesToVBComps("C:
\模块1")
说明:
导入文件部件如与部件重名,不会覆盖原部件,而是添加序号重新命名。
4.6导出部件为部件文件
4.6.1导出部自定义过程
'过程功能:
导出部件为部件文件
'输入参数:
FileName(字符串变量)用来指定部件输出为文件的文件名及导出路径
'CompsFile(Variant)可以是部件名或是部件索引,用以指定欲导出部件
PublicSubExportVBCompsToFiles(CompsFileAsVariant,FileNameAsString)
DimVBProjAsVBProject
DimVBCompsAsVBComponents
OnErrorResumeNext
SetVBProj=VBE.ActiveVBProject
SetVBComps=VBProj.VBComponents(CompsFile)
'导出部件为部件文件
VBComps.Import(FileName)
EndSub
4.6.2导出部件示例
'调用示例一:
指定部件(模块1)
CallExportVBCompsToFiles("模块1","C:
\模块1.bas")
'调用示例二:
通过部件索引导出部件,实例中:
索引[1]为[Form_窗体1]类对象
CallExportVBCompsToFiles(1,"C:
\Form_窗体1.cls")
说明:
你可以通过“部件名”或“索引”来指定需导出部件。
4.6.3根据部件类型获得输出部件文件后缀名
'根据部件类型,确定输出部件文件后缀名
PublicFunctionGetFileExtension(VBCompAsVBIDE.VBComponent)AsString
SelectCaseVBComp.Type
Casevbext_ct_ClassModule
GetFileExtension=".cls"
Casevbext_ct_Document
GetFileExtension=".cls"
Casevbext_ct_MSForm
GetFileExtension=".frm"
Casevbext_ct_StdModule
GetFileExtension=".bas"
CaseElse
GetFileExtension=".bas"
EndSelect
EndFunction
说明:
导出文件名要根据不同部件类型,指定后缀名,见下表:
部件对象
后缀名
描述
ACCESS类对象
cls
通常所说的“窗体”或“报表”对象等。
类模块
cls
含有类定义的模块。
标准模块
bas
只包含过程、类型以及数据的声明和定义的模块。
窗体
frm
指微软窗体,而非ACCESS类对象窗体。
五、代码窗格对象(CodePane)
代码窗口中包含的代码窗格。
代码窗口被用来输入和编辑代码。
代码窗口可含有多个代码窗格。
用CodePane对象来操作CodePane中代码或选取的代码或文本。
5.1显示代码窗格
5.1.1显示当前代码窗格
'打开并显示当前代码窗格
PublicSubShowProject()
VBE.ActiveCodePane.Show
EndSub
5.1.2显示指定部件代码模块窗格
'函数功能:
打开指定部件代码模块窗格
PublicSubShowComponent(ByValCompsNameOrIndexAsVariant)
DimVBProjAsVBProject'工程项目对象
DimVBCompAsVBComponent'组件对象
DimCodeModAsCodeModule'代码模块
DimVBCodePaneAsCodePane'窗格对象
'实例化对象
SetVBProj=VBE.ActiveVBProject
SetVBComp=VBProj.VBComponents(CompsNameOrIndex)
SetCodeMod=VBComp.CodeModule
SetVBCodePane=CodeMod.CodePane
VBCodePane.Show'显示代码窗格
EndSub
5.2获取窗格所选代码行列信息
5.2.1获取当前窗格中所选代码起止行列信息
'所选代码的起止行列信息定义数据类型
PublicTypeSelLineColInfo
SLineAsLong'起始行
SColAsLong'起始列
ELineAsLong'结束行
EColAsLong'结束列
EndType
'-----------------------------------------------------------------------
'函数功能:
获得所选代码开始行列及结束行列信息
PublicFunctionVBGetSelection()AsSelLineColInfo
DimSelInfoAsSelLi