设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

123下一页
返回列表 发新帖
查看: 13265|回复: 21
打印 上一主题 下一主题

VBA代码编程方法详解

[复制链接]
跳转到指定楼层
1#
发表于 2010-10-31 14:57:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 tanhong 于 2010-10-31 19:40 编辑

一、前言
  本文所说的VBA代码编程,即通过编程方法创建、删除或编辑VBA工程部件、模块或代码程序对象,还可以通过VBA代码创建新的代码,以此可以实现VBA的二次开发。
  VBA代码编程,也就是所谓的VBA可扩展性。要实现VBA扩展功能,或者说实现对VBA代码的编程,我们必须事先完成以下相关设置。

1.1
引用VBA扩展类库(Microsoft Visual Basic For Applications Extensibility 5.3
  在ACCESS 2003中扩展库文件为:VBE6EXT.OLB,你可以在VBEVisual Basic EditorVB编辑器)窗口,点菜单 [工具] [引用],在 [引用对话框] 中钩,来手动引用该扩展类库,你也可以通过代码实现对其的引用。

  1. Dim ref As Reference
  2. '申明引用类对象
  3. On Error Resume Next '避免因重复引用造成的错误提示
  4. '通过扩展库标识号,主版本号,次版本号完成引用
  5. Set ref = References.AddFromGuid ("{0002E157-0000-0000-C000-000000000046}", 5, 3)
复制代码


1.2
需要启用编程方式访问VBA项目(仅在EXCEL中需设定)
  在Excel 2003和更早版中,需设定允许对VBA项目的访问,否则将报错。ACCESS则不需对该项进行设定。
点选菜单 [工具](在Excel中,而不是在VBA编辑器中)—[][安全性],在 [安全对话框]中,单击 [可靠发行商] 页,点选 [信任对于“Visual Basic项目”的访问] 项(见下图)
注册表键值:
HKLM\Software\Microsoft\Office\11.0\Excel\Security\AccessVBOM", 1, "REG_DWORD"
键值为:1,则钩选;0,则取消钩选
二、VBA的可扩展模型对象简介
l Library VBIDE(扩展库)
路径:C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB
描述:Microsoft Visual Basic for Applications Extensibility 5.3

l
VBEVB编辑器)
VB编辑器,为根对象,其包含所有其它可在 Visual Basic for Applications中表示的对象和集合。

l
VBProject(工程)
VB工程(或称项目)中包含了所有的代码模块和部件。VB项目可包含若干个VB部件对象。

l
VBComponent(部件)
代表包含在工程中的部件对象,如:类模块标准模块部件(VBComponent 对象的 Type属性:
常数描述
Vbext_ct_StdModule1标准模块
Vbext_ct_ClassModule2类模块
Vbext_ct_MSForm3Microsoft 窗体(非ACCESS类窗体)

l
CodePane(代码窗格)
CodePane对象来操作 CodePane中可视文本的位置或者代码窗格中显示的文本选择。

l
CodeModule(代码模块)
代码模块是VB部件VBA源代码,可用 CodeModule对象来修改(添加、删除、编辑)与部件相关联的代码CodePane CodeModule内程序类别 prockind)常数:
常数描述
vbext_pk_Proc0指定所有过程除了Property 过程。
vbext_pk_Let1指定一个赋值给属性的过程。
vbext_pk_Set2指定一个给对象设置引用的过程。
vbext_pk_Get3指定一个返回属性值的过程。
以上为VBA的可扩展模型部分对象(非全部对象),其它模型对象请参阅帮助。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享分享 分享淘帖 订阅订阅
2#
 楼主| 发表于 2010-10-31 14:59:54 | 只看该作者
本帖最后由 tanhong 于 2010-10-31 15:02 编辑

三、工程对象(Project)
  表示一个工程。可用 VBProject对象设置工程的属性、访问 VBComponents集合以及访问 References集合。通常我们会用ActiveVBProject返回“工程”窗口中选定的工程,但在实际编程中,无论此工程是否被显式地选定,都只有一个工程是活动的。

3.1判断工程是否锁定
  通过工程Protection属性,判断工程锁定状态。工程Protection属性(只读),指示工程是否处于保护状态。返回的值为一事先定义好的常量,表示工程的状态。
Protection属性常量:
常数
描述
Vbext_pp_none
0
常量代表指定的工程未被保护。
vbext_pp_locked
1
常量代表指定的工程是被锁住。


3.1.1
判断工程是否锁定自定义函数


  1. '函数功能:判断工程是否锁定
  2. Public Function VBProjectlocked (Optional VBProj As VBProject = Nothing) As Boolean
  3.    Dim Proj   As VBProject
  4.    
  5. '如未指定工程,则为当前工程
  6.    If VBProj Is Nothing Then
  7.       Set Proj = VBE.ActiveVBProject
  8.    Else
  9.       Set Proj = VBProj
  10.    End If
  11.    
  12. '判断工程是否锁定
  13.    If Proj.Protection = vbext_pp_locked Then
  14.       VBProjectlocked = True
  15.    Else
  16.       VBProjectlocked = False
  17.    End If
  18. End Function
复制代码


3.1.2调用自定义函数,判断当前工程是锁定示例

  1.   '函数输出为真(True),否则当前工程锁定
  2. If VBProjectlocked = True Then
  3.       MsgBox "工程已锁定"
  4.    Else
  5.       MsgBox "工程未锁定"
  6.    End If
复制代码

3.2 获得工程名
  1. '获得当前工程名
  2. VBE.ActiveVBProject.Name
复制代码


四、部件对象(VBComponent)
  代表一个包含在工程中的部件,例如类模块或标准模块。使用 VBComponent对象访问与部件关联的代码模块CodeModule或改变部件的属性设置。

4.1 添加工程部件
4.1.1向当前工程添加部件公用过程

  1. '***************************************************
  2. '公用过程:添加模块或指定名模块
  3. ' ComponentType部件类型(可选参数),默认为标准模块
  4. ' VBCompName部件名(可选参数),默认不指定部件名
  5. '***************************************************
  6. Public Sub AddVBComponents (Optional ComponentType As vbext_ComponentType=1, _
  7.                           Optional VBCompName As String = "")
  8.    Dim VBProj      As VBProject       '申明工程(项目)对象
  9.    Dim VBComps    As VBComponents  '申明部件集合
  10.    '设定为当前工程
  11.    Set VBProj = VBE.ActiveVBProject
  12. 设定为当前工程部件集合
  13.    Set VBComps = VBProj.VBComponents
  14.   
  15. '判断是否指定部件名,未指定则按默认名建立指定类型部件
  16.    If VBCompName = "" Then
  17.       VBComps.Add (ComponentType)
  18.    Else
  19.       VBComps.Add (ComponentType).Name = VBCompName
  20.    End If
  21. End Sub
复制代码


4.1.2调用自定义过程,添加标准模块
  1. '例一:以默认名添加标准模块
  2. Call AddVBComponents
  3. '例二:以指定名“我的模块”添加标准模块
  4. Call AddVBComponents(, "我的模块")
复制代码


4.1.3调用自定义过程,添加类模块
  1. '例一:以默认名添加类模块
  2. Call AddVBComponents(2)

  3. '例二:以指定名“我的类模块”添加标准模块
  4. Call AddVBComponents(2, "我的类模块")
复制代码


4.1.4 调用自定义过程,添加(MSForm)窗体
  1. '例一:以默认名添加MSForm窗体
  2. Call AddVBComponents(3)

  3. '例二:以指定名“我的窗体”添加MSForm窗体
  4. Call AddVBComponents(3, "我的窗体")
复制代码


说明:这里窗体是指“Microsoft窗体”,而非ACCESS通常意义所说的窗体,ACCESS窗体实际为ACCESS类对象,你可以通过CreateForm方法创建一个ACCESS对象窗体。
3#
 楼主| 发表于 2010-10-31 15:03:30 | 只看该作者
4.2 移除工程中部件
4.2.1 移除当前工程部件自定义过程

  1. '***********************************************
  2. '公用过程:移除指定部件或删除某类部件
  3. 'ComponentType部件类别(可选参数),默认为标准模块
  4. 'VBCompName部件名(可选参数),默认不指定部件名
  5. '************************************************
  6. Public Sub RemoveVBComponents (Optional VBCompType As vbext_ComponentType, _
  7.                               Optional VBCompName As String = "")
  8.    Dim VBProj     As VBProject      '申明工程对象
  9.    Dim VBComp   As VBComponent   '申明部件对象
  10.    Dim VBComps  As VBComponents  '申明部件集合
  11.    '设定为当前工程
  12.    Set VBProj = VBE.ActiveVBProject
  13. '设定为当前工程部件
  14.    Set VBComps = VBProj.VBComponents
  15.    '判断是否指定部件名,如未指定则删除所有指定类型部件
  16.    If VBCompName <> "" And VBCompType = 0 Then
  17.       VBComps.Remove VBComps (VBCompName)
  18.    Else
  19.       For Each VBComp In VBComps
  20.          If VBComp.Type = VBCompType Then
  21.             VBComps.Remove VBComps (VBComp.Name)
  22.          End If
  23.       Next
  24.    End If
  25. End Sub
复制代码

4.2.2 调用自定义过程,移除指定类型所有部件示例
  1. '移除指定所有类模块
  2. Call RemoveVBComponents(vbext_ct_ClassModule)
复制代码


4.2.3  调用自定义过程,移除指定名部件示例(无需指定部件类型)
  1. '移除指定名部件,实例:指定“我的窗体”
  2. Call RemoveVBComponents(, "我的窗体")
复制代码


4.3 列举部件名及类型信息
4.3.1 获得部件类型自定义函数

  1. '------------------------------------------------------------
  2. '函数功能:根据所获取部件类型常量值,获得部件类别名
  3. '------------------------------------------------------------
  4. Function ComponentTypeToString (ComponentType As vbext_ComponentType) As String
  5.    Select Case ComponentType
  6.       Case vbext_ct_ClassModule
  7.          ComponentTypeToString = "类模块"
  8.       Case 100
  9.          ComponentTypeToString = "其它"
  10.       Case vbext_ct_MSForm
  11.          ComponentTypeToString = "微软窗体"
  12.       Case vbext_ct_StdModule
  13.          ComponentTypeToString = "标准模块"
  14.       Case Else
  15.          ComponentTypeToString = "未知类: " & CStr(ComponentType)
  16.    End Select
  17. End Function
复制代码


4.3.2 获取工程中所有部件名及类型自定义函数

  1. '-------------------------------------------------------------------
  2. '函数功能:列出所有部件名及类型
  3. '调    用:ComponentTypeToString 函数,获取部件类型
  4. '------------------------------------------------------------------
  5. Public Function AllVBComponentsAndType () As String
  6.    Dim VBComp    As VBComponent     '申明工程部件
  7.    Dim VBComps   As VBComponents     '申明部件集合
  8.    Dim strComps    As String             '输出结果
  9.    Dim strObjName  As String             '对象名
  10.    Dim strType      As String             '类型名
  11.    
  12.    Set VBComps = VBE.ActiveVBProject.VBComponents
  13.    '遍历部件集合,将部件名及类型值赋值给变量
  14.    For Each VBComp In VBComps
  15.       strObjName = VBComp.Name
  16.       strType = ComponentTypeToString(VBComp.Type)
  17.       '如果为其它类型,判断是ACCESS窗体、报表或其它对象
  18.       If strType = "其它" Then
  19.          If InStr(strObjName, "Form") > 0 Then
  20.             strType = "窗体"
  21.          ElseIf InStr(strObjName, "Report") > 0 Then
  22.             strType = "报表"
  23.          Else
  24.             strType = "其它"
  25.          End If
  26.       End If
  27.       '将获取的部件名及类型逐行输出
  28.       strComps = strComps & strObjName & Space (12) & strType & vbCrLf
  29.    Next
  30.    AllVBComponentsAndType = strComps   '赋值输出
  31. End Function
复制代码
4#
 楼主| 发表于 2010-10-31 15:04:18 | 只看该作者
4.4 判断部件是否存在
4.4.1判断部件是否存在自定义函数

  1. '-----------------------------------------------------------------------
  2. '函数功能:判断指定模块是否存在,存在输出为True
  3. '-----------------------------------------------------------------------
  4. Public Function VBComponentExists (ByVal VBCompName As String) As Boolean
  5.    Dim VBProj  As VBProject
  6.    On Error Resume Next
  7.    Set VBProj = VBE.ActiveVBProject
  8.    '存在输出为True,否则为False
  9.    VBComponentExists = CBool(Len(VBProj.VBComponents(VBCompName).Name))
  10. End Function
复制代码


4.4.2判断指定模块是否存在调用示例

  1.    If VBComponentExists("模块1") = False Then
  2.       MsgBox "不存在"
  3.    Else
  4.       MsgBox "存在"
  5.    End If
复制代码


4.5
导入部件文件添加部件
4.5.1导入部件自定义过程

  1. '导入部件文件添加部件
  2. '输入参数:FileName(字符串变量) 指示欲添加部件的路径及文件名
  3. Public Sub ImportFilesToVBComps (FileName As String)
  4.    Dim VBProj     As VBProject
  5.    Dim VBComps   As VBComponents
  6.    
  7.    On Error Resume Next
  8.    
  9.    Set VBProj = VBE.ActiveVBProject
  10.    Set VBComps = VBProj.VBComponents
  11.    '导入指定部件文件,添加部件
  12.    VBComps.Import (FileName)
  13. End Sub
复制代码

4.5.2导入部件文件示例
  1. '调用示例:从指定C盘导入部件文件"模块1"添加到当前工程
  2. Call ImportFilesToVBComps("C:\模块1")
复制代码

说明:导入文件部件如与部件重名,不会覆盖原部件,而是添加序号重新命名。

4.6 导出部件为部件文件
4.6.1导出部自定义过程

  1. '过程功能:导出部件为部件文件
  2. '输入参数:FileName(字符串变量) 用来指定部件输出为文件的文件名及导出路径
  3. '           CompsFile(Variant) 可以是部件名或是部件索引,用以指定欲导出部件
  4. Public Sub ExportVBCompsToFiles (CompsFile As Variant, FileName As String)
  5.    Dim VBProj    As VBProject
  6.    Dim VBComps  As VBComponents
  7.    
  8.    On Error Resume Next
  9.    
  10.    Set VBProj = VBE.ActiveVBProject
  11.    Set VBComps = VBProj.VBComponents (CompsFile)
  12.    '导出部件为部件文件
  13.    VBComps.Import (FileName)
  14. End Sub
复制代码

4.6.2 导出部件示例
  1. '调用示例一:指定部件(模块1)
  2. Call ExportVBCompsToFiles("模块1","C:\模块1.bas")

  3. '调用示例二:通过部件索引导出部件,实例中:索引[1]为[Form_窗体1]类对象
  4. Call ExportVBCompsToFiles(1,"C:\ Form_窗体1.cls")
复制代码

说明:你可以通过“部件名”或“索引”来指定需导出部件。

4.6.3 根据部件类型获得输出部件文件后缀名

  1. '根据部件类型,确定输出部件文件后缀名
  2. Public Function GetFileExtension (VBComp As VBIDE.VBComponent) As String
  3.      Select Case VBComp.Type
  4.         Case vbext_ct_ClassModule
  5.             GetFileExtension = ".cls"
  6.         Case vbext_ct_Document
  7.             GetFileExtension = ".cls"
  8.         Case vbext_ct_MSForm
  9.             GetFileExtension = ".frm"
  10.         Case vbext_ct_StdModule
  11.             GetFileExtension = ".bas"
  12.         Case Else
  13.             GetFileExtension = ".bas"
  14.     End Select
  15. End Function
复制代码


说明:导出文件名要根据不同部件类型,指定后缀名,见下表:
部件对象
后缀名
描述
ACCESS类对象
cls
通常所说的“窗体”或“报表”对象等。
类模块
cls
含有类定义的模块。
标准模块
bas
只包含过程、类型以及数据的声明和定义的模块。
窗体
frm
指微软窗体,而非ACCESS类对象窗体。
5#
 楼主| 发表于 2010-10-31 15:04:45 | 只看该作者
五、代码窗格对象(CodePane)
  代码窗口中包含的代码窗格。代码窗口被用来输入和编辑代码。代码窗口可含有多个代码窗格。
CodePane对象来操作 CodePane中代码或选取的代码或文本。

5.1 显示代码窗格
5.1.1显示当前代码窗格
  1. '打开并显示当前代码窗格
  2. Public Sub ShowProject ()
  3.  VBE.ActiveCodePane.Show
  4. End Sub
复制代码


5.1.2显示指定部件代码模块窗格

  1. '函数功能:打开指定部件代码模块窗格
  2. Public Sub ShowComponent (ByVal CompsNameOrIndex As Variant)
  3.    Dim VBProj       As VBProject        '工程项目对象
  4.    Dim VBComp      As VBComponent    '组件对象
  5.    Dim CodeMod     As CodeModule      '代码模块
  6.    Dim VBCodePane   As CodePane        '窗格对象
  7.    
  8.    '实例化对象
  9.    Set VBProj = VBE.ActiveVBProject
  10.    Set VBComp = VBProj.VBComponents (CompsNameOrIndex)
  11.    Set CodeMod = VBComp.CodeModule
  12.    Set VBCodePane = CodeMod.CodePane
  13.    
  14.    VBCodePane.Show    '显示代码窗格
  15. End Sub
复制代码



5.2 获取窗格所选代码行列信息
5.2.1获取当前窗格中所选代码起止行列信息

  1. '所选代码的起止行列信息定义数据类型
  2. Public Type SelLineColInfo
  3.    SLine  As Long        '起始行
  4.    SCol   As Long        '起始列
  5.    ELine  As Long        '结束行
  6.    ECol   As Long        '结束列
  7. End Type

  8. '-----------------------------------------------------------------------
  9. '函数功能:获得所选代码开始行列及结束行列信息
  10. Public Function VBGetSelection () As SelLineColInfo
  11.    Dim SelInfo  As SelLineColInfo  '数据类型
  12.    
  13.    VBE.ActiveCodePane.GetSelection SelInfo.SLine, SelInfo.SCol, _
  14.                                 SelInfo.ELine, SelInfo.ECol
  15.    '获取的行列信息输出
  16.    VBGetSelection = SelInfo
  17. End Function


  18. '***************************************************
  19. '调用示例:在窗格中任选一处代码行列,再运行以下代码
  20. Dim SelInfo As SelLineColInfo '申明自定数据类型
  21. '起止行列信息赋值给变量   
  22. SelInfo = VBGetSelection
  23. '输出显示   
  24. MsgBox "起始行:" & SelInfo.SLine & vbLf & _
  25.        "起始列:" & SelInfo.SCol & vbLf & _
  26.        "结束行:" & SelInfo.ELine & vbLf & _
  27.        "结束列:" & SelInfo.ECol
复制代码
6#
 楼主| 发表于 2010-10-31 15:05:14 | 只看该作者
六、代码模块对象(CodeModule

  在诸如窗体,类或文档等部件之后表示程序代码。可用 CodeModule对象来修改(添加、删除、编辑)与部件相关联的代码。
  每个部件都与一个 CodeModule对象相关联。但是,一个 CodeModule对象可以与多个代码窗格CodePane相关联。

6.1 获得指定行代码
6.1.1 获得指定模块中指定一行或多行代码

  1. '函数功能:指定模块指定行代码
  2. '输入参数:CompsNameOrIndex 部件名或索引
  3. '          CodeLine(长整)代码所在行
  4. '          CountLines(长整)可选参数,选取代码行数,默认为1行
  5. Public Function LineCodeString (ByVal CompsNameOrIndex, _
  6.                       ByVal CodeLine As Long, _
  7.                       Optional CountLines As Long = 1) As String
  8.    Dim VBProj      As VBProject
  9.    Dim VBComp     As VBComponent
  10.    Dim CodeMod    As CodeModule
  11.    
  12.    Set VBProj = VBE.ActiveVBProject
  13.    Set VBComp = VBProj.VBComponents (CompsNameOrIndex)
  14.    Set CodeMod = VBComp.CodeModule
  15.    
  16.    LineCodeString = CodeMod.Lines (CodeLine, CountLines)
  17. End Function

  18. '***********************************************
  19. '调用示例一:获得“模块1”,第五行代码
  20. Debug.Print LineCodeString("模块1",5)

  21. '***********************************************
  22. '调用示例二:获得“模块1”,第一行至第六行代码
  23. Debug.Print LineCodeString("模块1",1 ,6)
复制代码


6.2 列举模块中所有过程及类型
6.2.1获得过程种类自定义函数

  1. ' 函数功能:获得过程种类名
  2. ' 输入参数:ProcKind(过程类型常数)
  3. Public Function ProcKindString(ByVal ProcKind As vbext_ProcKind) As String
  4.    Select Case ProcKind
  5.       Case vbext_pk_Get
  6.          ProcKindString = "roperty Get"
  7.       Case vbext_pk_Let
  8.          ProcKindString = "roperty Let"
  9.       Case vbext_pk_Set
  10.          ProcKindString = "roperty Set"
  11.       Case vbext_pk_Proc
  12.          ProcKindString = "Sub Or Function"
  13.       Case Else
  14.          ProcKindString = "Unknown Type: " & CStr(ProcKind)
  15.    End Select
  16. End Function
复制代码


6.2.2 获得指定部件中过程名及类型

  1. '---------------------------------------------------------------------
  2. '函数功能:列出指定模块中所有过程
  3. '输入参数:CompsNameOrIndex 部件名或索引
  4. '调    用:自定义ProcKindString函数
  5. '---------------------------------------------------------------------
  6. Public Function ListProcedures (CompsNameOrIndex As Variant) As String
  7.    Dim VBProj     As VBProject            '工程
  8.    Dim VBComp    As VBComponent        '部件
  9.    Dim CodeMod    As CodeModule         '代码模块
  10.    Dim ProcKind    As vbext_ProcKind       '过程类型
  11.    Dim LineNum    As Long                '代码行
  12.    Dim sProcKind   As String                '过程类型名
  13.    Dim ProcName   As String                '过程名
  14.    
  15.    '实例化当前活动的工程
  16.    Set VBProj = VBE.ActiveVBProject
  17.    '实例化工程对象集合
  18.    Set VBComp = VBProj.VBComponents(CompsNameOrIndex)
  19.    '实例化代码模块
  20.    Set CodeMod = VBComp.CodeModule
  21.    
  22.    With CodeMod
  23.       '获得代码所在起始行,等于申明行加一
  24.       LineNum = .CountOfDeclarationLines + 1
  25.       '获得指定行所在过程名
  26.       ProcName = .ProcOfLine(LineNum, ProcKind)
  27.       '申明后第一行开始循环至代码结束,将获取过程名及类型名输出
  28.       Do Until LineNum >= .CountOfLines
  29.          sProcKind = sProcKind & ProcName & Space(3) & _
  30. ProcKindString(ProcKind) & vbLf
  31.          '代码行数累加, 将根据所在行获得过程名
  32.          LineNum = LineNum + .ProcCountLines(ProcName, ProcKind)
  33.          ProcName = .ProcOfLine(LineNum, ProcKind)
  34.       Loop
  35.    End With
  36.    
  37.    ListProcedures = sProcKind
  38. End Function

  39. '***********************************************
  40. '调用示例:获取"Form_窗体1"中所有过程名及类型
  41. Debug.Print ListProcedures ("Form_窗体1")
复制代码
7#
 楼主| 发表于 2010-10-31 15:05:42 | 只看该作者
6.3 判断过程是否存在
6.3.1 判断指定过程是否存在自定义函数

  1. '函数功能:判断指定过程是否存在,存在输出为真
  2. Public Function VBProcExists(ByVal VBProcName As String, _
  3.                          Optional VBCompNameOrIndex As Variant) As Boolean
  4.    Dim VBProj           As VBProject
  5.    Dim VBCodeModule    As CodeModule
  6.    Dim ProcKind         As vbext_ProcKind        '过程类型
  7.    Dim LineNum         As Long                 '代码行
  8.    Dim ProcName        As String                 '获得过程名
  9.    
  10.    Set VBProj = VBE.ActiveVBProject
  11.    '如不指定部件及为当前窗格代码模块
  12.    If VBCompNameOrIndex = "" Then
  13.       Set VBCodeModule = VBE.ActiveCodePane.CodeModule
  14.    Else
  15.       Set VBCodeModule = VBProj.VBComponents(VBCompNameOrIndex).CodeModule
  16.    End If
  17.    
  18.    With VBCodeModule
  19.       '获得代码所在起始行,等于申明行加一
  20.       LineNum = .CountOfDeclarationLines + 1
  21.       '获得指定行所在过程名
  22.       ProcName = .ProcOfLine (LineNum, ProcKind)
  23.       '申明后第一行开始循环至代码结束,将获取过程名及类型名输出
  24.       Do Until LineNum >= .CountOfLines
  25.          '代码行数累加,将根据所在行获得过程名
  26.          LineNum = LineNum + .ProcCountLines (ProcName, ProcKind)
  27.          ProcName = .ProcOfLine (LineNum, ProcKind)
  28.          '进行二进制比对,比对结果等一,则存在
  29.          If StrComp (VBProcName, ProcName) = 1 Then
  30.             VBProcExists = True
  31.             Exit Do
  32.          End If
  33.       Loop
  34.    End With
  35. End Function
复制代码

6.3.2 调用自定义函数示例
  1. '示例一:指定过程名,但不指定部件
  2. Debug.Print VBProcExists("过程名")

  3. '示例二:指定过程名"ShowProcedureInfo",并指定部件名
  4. Debug.Print VBProcExists("过程名","部件名")

  5. '示例三:指定过程名,并通过索引指定部件
  6. Debug.Print VBProcExists("过程名",3)
复制代码



6.4 获得指定行所在过程名
6.4.1 获得指定行过程名自定义函数

  1. '---------------------------------------------------------------------
  2. '函数功能:获得指定行过程名
  3. '---------------------------------------------------------------------
  4. Public Function GetLineProcName (ByVal LineNum As Long) As String
  5.    Dim CodeMod    As CodeModule          '申明代码模块
  6.    Dim VBpane     As VBIDE.CodePane      '代码模块所在窗格   
  7.    Dim NumLines   As Long                 '代码行数
  8.    Dim ProcName   As String                 '过程名
  9.    Dim ProcKind    As vbext_ProcKind        '过程类型
  10.    
  11.    '实例化为当前代码窗口
  12.    Set VBpane = VBE.ActiveCodePane
  13.    '实例化为当前窗格代码模块
  14.    Set CodeMod = VBpane.CodeModule
  15.    
  16.    With CodeMod
  17.       '获得代码起始行行数
  18.       NumLines = .CountOfDeclarationLines + 1
  19.       '判断是否为申明代码行
  20.       If LineNum > NumLines Then
  21.          ProcName = .ProcOfLine (LineNum, ProcKind)
  22.       Else
  23.          GetLineProcName = -1   '如为申明代码行,则输出为负1
  24.          Exit Function
  25.       End If
  26.    End With
  27.    '过程名输出
  28.    GetLineProcName = ProcName
  29. End Function
复制代码

6.4.2
调用指定行过程名函数示例

  1. '获得指当前代码窗口行号第26行代码所在过程名
  2. Call GetLineProcName(26)
复制代码


8#
 楼主| 发表于 2010-10-31 15:06:07 | 只看该作者
6.5 获取过程代码行数信息
6.5.1指定过程总代码行数

  1. '函数功能:获得指定过程总的代码行数(含过程中的所有空行及注释)
  2. Public Function TotalCodeLinesInProc(CompsNameOrIndex, _
  3.                   strProcName As String, _
  4.                   Optional ProcKind As vbext_ProcKind = 0) As Long
  5.    Dim VBProj       As VBProject        '工程对象
  6.    Dim VBComp     As VBComponent     '部件对象
  7.    Dim CodeMod     As CodeModule      '代码模块
  8.    
  9.    '设定为当前工程
  10.    Set VBProj = VBE.ActiveVBProject
  11.    '设定为指定部件
  12.    Set VBComp = VBProj.VBComponents(CompsNameOrIndex)
  13.    '设定为指定部件代码模块
  14.    Set CodeMod = VBComp.CodeModule
  15.    '过程计数输出
  16.    TotalCodeLinesInProc = CodeMod.ProcCountLines(strProcName, ProcKind)
  17. End Function

  18. '******************************************************************
  19. '调用示例:获得部件"bas_ProcInfo"模块中,"ShowProcedureInfo"过程总行数
  20. Debug.Print TotalCodeLinesInProc("bas_ProcInfo", "ShowProcedureInfo")
复制代码


6.5.2 指定过程代码起始行数

  1. '函数功能:获得指定过程代码起始行(从过程之上的空行和注释计算)
  2. Public Function StartLineInProc (CompsNameOrIndex, _
  3.                   strProcName As String, _
  4.                   Optional ProcKind As vbext_ProcKind = 0) As Long
  5.    Dim VBProj     As VBProject
  6.    Dim VBComp    As VBComponent
  7.    Dim CodeMod   As CodeModule
  8.    
  9.    Set VBProj = VBE.ActiveVBProject
  10.    Set VBComp = VBProj.VBComponents (CompsNameOrIndex)
  11.    Set CodeMod = VBComp.CodeModule
  12.    
  13.    StartLineInProc = CodeMod.ProcStartLine(strProcName, ProcKind)
  14. End Function

  15. '******************************************************************
  16. '调用示例:获得部件"bas_ProcInfo"模块中,"ShowProcedureInfo"过程起始行号
  17. Debug.Print StartLineInProc ("bas_ProcInfo", "ShowProcedureInfo")
复制代码


6.5.3 指定过程实际代码起始行数

  1. '函数功能:获得过程第一行代码行(从过程的实际代码行计算,不含过程之上空行和注释)
  2. Public Function CodeBodyLineInProc (CompsNameOrIndex, _
  3.                   strProcName As String, _
  4.                   Optional ProcKind As vbext_ProcKind = 0) As Long
  5.    Dim VBProj      As VBProject
  6.    Dim VBComp    As VBComponent
  7.    Dim CodeMod    As CodeModule
  8.    
  9.    Set VBProj = VBE.ActiveVBProject
  10.    Set VBComp = VBProj.VBComponents(CompsNameOrIndex)
  11.    Set CodeMod = VBComp.CodeModule
  12.    
  13.    CodeBodyLineInProc = CodeMod.ProcBodyLine(strProcName, ProcKind)
  14. End Function

  15. '******************************************************************
  16. '调用示例:获得部件"bas_ProcInfo"模块中,"ShowProcedureInfo"过程实际起始行号
  17. Debug.Print CodeBodyLineInProc ("bas_ProcInfo", "ShowProcedureInfo")
复制代码

6.5.4 指定过程实际代码行数

  1. '函数功能:获得指定过程实际代码行数(不包含空行和注释行)
  2. Public Function CodeLinesInProc(ByVal CompsNameOrIndex, _
  3.                   ByVal strProcName As String, _
  4.                   Optional ProcKind As vbext_ProcKind = 0) As Long
  5.    Dim VBProj    As VBProject
  6.    Dim VBComp   As VBComponent
  7.    Dim CodeMod  As CodeModule
  8.    
  9.    Dim ProcStart   As Long         '代码起始行
  10.    Dim ProcTotal   As Long         '代码总行数
  11.    Dim I          As Integer        '循环变量
  12.    Dim strCode    As String         '代码
  13.    Dim LineCount  As Long         '行计数变量
  14.    实例化对象
  15.    Set VBProj = VBE.ActiveVBProject
  16.    Set VBComp = VBProj.VBComponents(CompsNameOrIndex)
  17.    Set CodeMod = VBComp.CodeModule
  18.    '获取开始行号和总行数
  19.    ProcStart = CodeMod.ProcStartLine (strProcName, ProcKind)
  20.    ProcTotal = CodeMod.ProcCountLines(strProcName, ProcKind) + ProcStart
  21.    
  22.    For I = ProcStart To ProcTotal
  23.       '将代码赋值给字符串变量
  24.       strCode = CodeMod.Lines(I, 1)
  25.       '跳过空行和注释行
  26.       If Trim (strCode) = vbNullString Or Left (Trim (strCode), 1) = Chr (39) Then
  27.       Else
  28.    LineCount = LineCount + 1
  29.       End If
  30.    Next I
  31.    '实际行数输出
  32.    CodeLinesInProc = LineCount
  33. End Function

  34. '******************************************************************
  35. '调用示例:获得部件"bas_ProcInfo"模块中,"ShowProcedureInfo"过程实际行数
  36. Debug.Print CodeLinesInProc ("bas_ProcInfo", "ShowProcedureInfo")
复制代码
9#
 楼主| 发表于 2010-10-31 15:06:33 | 只看该作者
6.6 获取部件或模块中代码行信息
6.6.1 获取部件或模块中申明部分行数

  1. '函数功能:获得指定部件或模块中申明部分总代码行数(含注释行及空行)
  2. Public Function TotalDeclLinesInVBComp (CompsNameOrIndex) As Long
  3.    Dim VBProj      As VBProject         '申明工程项目对象
  4.    Dim VBComp    As VBComponent      '申明项目组件对象
  5.    Dim CodeMod    As CodeModule       '申明组件代码
  6.    
  7.    '实例化对象
  8.    Set VBProj = VBE.ActiveVBProject
  9.    Set VBComp = VBProj.VBComponents(CompsNameOrIndex)
  10.    Set CodeMod = VBComp.CodeModule
  11.    
  12.    '获得申明代码行数并输出
  13.    TotalDeclLinesInVBComp = CodeMod.CountOfDeclarationLines
  14. End Function

  15. '******************************************************************
  16. '调用示例:获得部件"bas_ProcInfo"模块中申明部分总代码行数
  17. Debug.Print TotalDeclLinesInVBComp ("bas_ProcInfo")
复制代码


6.6.2 获得指定模块中总代码行数

  1. '函数功能:获得指定模块中总代码行数(含申明代码行、注释行及空行)
  2. Public Function TotalCodeLinesInVBComp (CompsNameOrIndex) As Long
  3.    Dim VBProj     As VBProject
  4.    Dim VBComp   As VBComponent
  5.    Dim CodeMod   As CodeModule
  6.    
  7. '实例化对象
  8.    Set VBProj = VBE.ActiveVBProject
  9.    Set VBComp = VBProj.VBComponents(CompsNameOrIndex)
  10.    Set CodeMod = VBComp.CodeModule
  11.   
  12. '获得部件或模块中代码总行数并输出
  13.    TotalCodeLinesInVBComp = CodeMod.CountOfLines
  14. End Function

  15. '******************************************************************
  16. '调用示例:获得部件"bas_ProcInfo"模块中总代码行数
  17. Debug.Print TotalCodeLinesInVBComp ("bas_ProcInfo")

复制代码



6.6.3 获得指定部件或模块中实际代码行数

  1. '函数功能:获得指定部件或模块代码数。包括申明及代码,但不含注释代码行及空白行
  2. Public Function CodeLinesInVBComp (CompsNameOrIndex) As Long
  3.    Dim VBProj     As VBProject
  4.    Dim VBComp   As VBComponent
  5.    Dim CodeMod   As CodeModule
  6.    Dim I          As Long
  7.    Dim strCode    As String
  8.    Dim LineCount  As Long
  9.    
  10.    '实例化对象
  11.    Set VBProj = VBE.ActiveVBProject
  12.    Set VBComp = VBProj.VBComponents(CompsNameOrIndex)
  13.    Set CodeMod = VBComp.CodeModule
  14.    
  15.    With CodeMod
  16.       '循环每行代码
  17.       For I = 1 To .CountOfLines
  18.          '将代码赋值给字符串变量
  19.          strCode = .Lines(I, 1)
  20.          If Trim (strCode) = vbNullString Or Left (Trim (strCode), 1) = Chr (39) Then
  21.            '跳过空行注释行
  22.          Else
  23.             LineCount = LineCount + 1
  24.          End If
  25.       Next I
  26.    End With
  27.    '获取实际代码计数输出
  28.    CodeLinesInVBComp = LineCount
  29. End Function

  30. '******************************************************************
  31. '调用示例:获得部件"bas_ProcInfo"模块中实际代码行数
  32. Debug.Print CodeLinesInVBComp ("bas_ProcInfo")
复制代码


6.7 获取工程代码行数信息
6.7.1工程总代码行数

  1. '函数功能:工程总代码行数(含空及注释)
  2. '调    用:TotalCodeLinesInVBComp
  3. Public Function TotalCodeLinesInProject () As Long
  4.    Dim VBProj      As VBProject
  5.    Dim VBComp    As VBComponent
  6.    Dim LineCount   As Long
  7.    
  8.    Set VBProj = VBE.ActiveVBProject
  9.    
  10.    '判断工程是否锁定,则退出函数,
  11.    If VBProj.Protection = vbext_pp_locked Then
  12.       TotalCodeLinesInProject = -1
  13.       Exit Function
  14.    End If
  15.    
  16.    '遍历当前工程中所有部件
  17.    For Each VBComp In VBProj.VBComponents
  18.       LineCount = LineCount + TotalCodeLinesInVBComp(VBComp.Name)
  19.    Next VBComp

  20.    TotalCodeLinesInProject = LineCount
  21. End Function
复制代码

6.7.2工程实际代码行数

  1. '函数功能:工程实际代码行数(不含空及注释)
  2. '调    用:CodeLinesInVBComp
  3. Public Function CodeLinesInProject() As Long
  4.    Dim VBProj      As VBProject
  5.    Dim VBComp     As VBComponent
  6.    Dim LineCount    As Long
  7.    
  8.    Set VBProj = VBE.ActiveVBProject
  9.    
  10.    '遍历当前工程中所有部件对象
  11.    For Each VBComp In VBProj.VBComponents
  12.       LineCount = LineCount + CodeLinesInVBComp(VBComp.Name)
  13.    Next VBComp
  14.    
  15.    CodeLinesInProject = LineCount
  16. End Function
复制代码
10#
 楼主| 发表于 2010-10-31 15:07:02 | 只看该作者
6.8 代码模块中添加代码操作
6.8.1 向指定部件添加一行代码

  1. '过程功能:向指定部件或模块添加代码
  2. '输入参数:strNewCode(字符串)添加的代码字符串
  3. '          VBCompNameOrIndex(Variant)可选参数,部件名或索引
  4. Sub AddNewCodeInComps (ByVal strNewCode As String, _
  5.                       Optional VBCompNameOrIndex As Variant)
  6.    Dim VBProj          As VBProject
  7.    Dim VBCodeModule   As CodeModule
  8.    
  9.    Set VBProj = VBE.ActiveVBProject
  10.    
  11.    '如不指定部件或模块,及为当前窗格部件代码模块
  12.    If VBCompNameOrIndex = "" Then
  13.       Set VBCodeModule = VBE.ActiveCodePane.CodeModule
  14.    Else
  15.       Set VBCodeModule = VBProj.VBComponents(VBCompNameOrIndex).CodeModule
  16.    End If
  17.    '向模块中添加新代码
  18.    VBCodeModule.AddFromString strNewCode
  19. End Sub


  20. '*********************************************************
  21. '调用示例:向指定部件“模块1”,添加代码
  22. Dim strNewCode  As String
  23. strNewCode = "Sub Test ()" & vbLf & _
  24.            Space(4) & "Msgbox " & Chr(34) & "这是添加的代码!" & Chr(34) & vbLf & _
  25.           "End Sub"
  26. Call AddNewCodeInComps(strNewCode, "模块1")
复制代码
6.9 代码模块中插入代码操作
6.9.1 在某个部件指定行插入一行或多行代码过程

  1. '过程功能:在代码模块的某个指定行,插入一行或多行的代码
  2. '输入参数:strNewCode(字符串)添加的代码字符串
  3. '          CodeLines(长整型)代码行
  4. '          VBCompNameOrIndex(Variant)部件名或索引
  5. Sub InsertCodeInComps (ByVal strNewCode As String, _
  6.                   Optional CodeLines As Long = 1, _
  7.                   Optional VBCompNameOrIndex As Variant)
  8.    Dim VBProj           As VBProject
  9.    Dim VBCodeModule    As CodeModule
  10.    
  11.    Set VBProj = VBE.ActiveVBProject
  12.    
  13.    '如不指定部件代码模块,及为当前窗格部件代码模块
  14.    If VBCompNameOrIndex = "" Then
  15.       Set VBCodeModule = VBE.ActiveCodePane.CodeModule
  16.    Else
  17.       Set VBCodeModule = VBProj.VBComponents(VBCompNameOrIndex).CodeModule
  18.    End If
  19.   
  20. '向模块中指定行插入或添加新代码
  21.    VBCodeModule.InsertLines CodeLines, strNewCode
  22. End Sub


  23. '*********************************************************
  24. '调用示例:向指定部件“模块1”,第一第二行分别插入指定代码
  25. Dim strNewCode1, strNewCode2  As String
  26. strNewCode1 =" Option Compare Database"
  27. strNewCode2 ="Option Explicit"

  28. Call InsertCodeInComps (strNewCode1, , "模块1")
  29. Call InsertCodeInComps (strNewCode2, 2, "模块1")
  30.   
复制代码


6.10 代码模块中替换代码操作
6.10.1 替换指定行原代码

  1. '过程功能:用新代码替换指定行原代码
  2. '输入参数:strNewCode(字符串)欲替换写入的新代码字符串
  3. '          CodeLines(长整型)欲替换的代码行
  4. '          VBCompNameOrIndex(Variant)部件名或索引
  5. Sub ReplaceLineCodeInComps (ByVal strNewCode As String, _
  6.                   Optional CodeLines As Long = 1, _
  7.                   Optional VBCompNameOrIndex As Variant)
  8.    Dim VBProj           As VBProject
  9.    Dim VBCodeModule    As CodeModule
  10.    
  11.    Set VBProj = VBE.ActiveVBProject
  12.    
  13.    '如不指定部件或模块,及为当前窗格部件代码模块
  14.    If VBCompNameOrIndex = "" Then
  15.       Set VBCodeModule = VBE.ActiveCodePane.CodeModule
  16.    Else
  17.       Set VBCodeModule = VBProj.VBComponents (VBCompNameOrIndex).CodeModule
  18.    End If
  19.    '替换模块中指定行为新代码
  20.    VBCodeModule.ReplaceLine CodeLines, strNewCode
  21. End Sub


  22. '*********************************************************
  23. '调用示例:向指定部件“模块1”,替换原第五行代码为新代码
  24. Dim strNewCode  As String
  25. strNewCode = Space(4) & "Msgbox " & Chr(34) & "这是替换的代码!"
  26.                  
  27. Call ReplaceLineCodeInComps(strNewCode, 5, "模块1")
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-4-25 02:03 , Processed in 0.118019 second(s), 35 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表