概述:VBA中每一个程序都包含过程,录制的宏是一个过程,一个自定函数也是一个过程。掌握好的单个过程的编写与思路,就可以组合成大中型插件或者专业程序。
一、分类与调用方式
i. 分类
过程分为三类:子过程、函数过程和属性过程
1. 子过程
Sub 子过程()
End sub
2. 函数过程
Function 函数过程(rng asRange)
End Function
3. 属性过程
Property get 属性过程( ) As Variant
End property
ii. 调用方式
1. 执行 Alt+F8
如果在工作表 ThisWorkBook、标准模块窗口存在sub过程。就可以弹出宏的对话框,然后选择执行
2. 按钮执行
在工作表中建一个按钮,并将按钮与sub过程关联,从而实现按钮执行程序。
开发工具---插入--表单控件---按钮 然后指定上自己的宏就搞定了
3. 菜单调用
暂无介绍,后续讲解
4. 事件引发
对于部分需要自启动的程序,通常利用事件引发,不需要人工干预,例如:工作簿开启时就自动执行某程序,或者关掉窗体,鼠标移过窗体时执行某程序等。后续讲解实现。
5. 工作表中使用公式调用
插入模块—然后录入代码
Function 成绩(rng)
成绩 = IIf(rng>= 60, "及格", "不及格")
End Function
在C1的公式写上=成绩(B1)
然后在B1输入30 则就会显示不及格
iii. 插入过程方式
1. 非事件过程
首先插入一个模块,再插入过程,然后输入模块名设置公有的就可以建立过程的外壳了。
2. 事件类过程
VBA支持很多类事件,大部分事件的代码都需要参数。可以通过VBE提供的对象与过程窗口的下拉列表完成
双击sheet1 下拉列表框中选择worksheet代码窗口默认产生change事件代码。时间大部分要用下拉菜单来选择,不容易误差
实现鼠标移过事件
插入---用户窗体 右击查看代码 默认产生click事件 选择为mousmove事件 然后输入代码
iv. 过程命名规则
过程名可以与本过程中的私有变量同名,但却不能和共有变量同名
二、编写sub过程
Sub过程即利用sub语句声明的子过程,所有宏录制起产生的过程全是sub过程,无法通过录制宏产生function过程或者属性过程
语法:
Private | public | friend [static]sub name [(arglist)]
[startements]
[exit Sub]
[statements]
End sub
Sub语句各参数的详细功能
Public 可选的。表示所有模块的所有其他过程都可以访问这个sub过程。如果在包含Option pirvate的模块中使用,则这个过程在该工程外是不可使用的
Private 可选。表示智能在包含其声明的模块中的其他过程中可以访问该sub过程
Friend 可选。智能在类模块中使用,表示该sub过程在整个工程中都是可见的,但是对对象实例的控制着是不可见的
Static 可选的,表示调用时保留sub过程中局部变量的值。Static属性对sub外声明的变量不会产生影响,即使过程中使用了这些变量
Name 必须的。 Sub的过程名。
Arglist 可选的,代表在调用时要传递给sub过程的参数的变量列表,多个变量则用都好隔开
Statements 可选的。Sub过程中所指定的语句组
v. 模块级过程
只能在当前模块调用的过程。
声明sub过程前使用private
只有在当前模块中调用
Private Sub 过程1(name As String)
MsgBox name
End Sub
Private Sub 过程2()
Call 过程1("调用过程1")
End Sub
不出现在宏对话框中。 在alt+F8所打开的对话框中无法查看到过程的名称
vi. 工程级别过程
指在当前工程中任何地方都可以随意调用的过程,在sub语句潜质表示符public,非当前过程可以调用,可以出现在宏列表,如果没有修饰,则默认是public,任何模块或者窗体中都可以调用 支持参数
vii. Exit sub 与end 的作用和区别
是否释放公有变量
Exit sub 不释放变量,退出当前过程
End 释放变量
是否终止所有程序
Exit sub退出当前过程
End 退出当前所有程序。也就是事件已经结束
b) Sub过程的执行流程
i. 单步执行 按F8单步执行sub。跳过变量定义语句
ii. 使用冒号实现一行执行多个代码
Private Sub 一行执行多个代码()
If 60 = 60 Then MsgBox "及格": Exit Sub
End Sub
iii. 使用标签改变执行流程
规则:
可是是标点符号以外的符号组合
以冒号结尾
与大小写无关,必须位于一行的最左端
配合goto
Private Sub 新建总表()
For i = 1 To Sheets.Count
If Sheets(i).name = "总表" ThenGoTo err
Next i
Sheets.Add
ActiveSheet.name = "总表"
End
err:
MsgBox "已经存在总表"
End Sub
iv. Sub过程的嵌套调用方式
1. Call语句调用
[call] name [(argumentlist)] call过程名参数 call可以省略
2. Run方法调用
Application.Run 过程名 Application可以省略
v. 过程的递归
Private Sub 建立5张表()
If Sheets.Count > 5Then Exit Sub
Sheets.Add ,Sheets(Sheets.Count), 1
Call 建立5张表
End Sub
设置时钟:
Sub 时间()
[a1] = WorksheetFunction.Text(Now(), "hh:mm:ss")
Application.OnTime Now() + TimeValue("00:00:01"), "时间"
End Sub
Sub 终止()
Application.OnTime Now() +TimeValue("00:00:01"), "时间", , False
End Sub
c) 过程的案例
i. 选区统计
Sub 选区统计()
Dim msg As String
msg = msg & "单元格个数"& Selection.Count & Chr(10)
msg = msg & "数字个数"& WorksheetFunction.Count(Selection) & Chr(10)
msg = msg & "非空单元格"& WorksheetFunction.CountBlank(Selection) & Chr(10)
msg = msg & "选区之和"& WorksheetFunction.Sum(Selection)
MsgBox msg
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Call 选区统计
End Sub
ii. 将单元格数据转换成首字母大写:带有参数的sub过程
Sub 转换(target)
Selection(1) = StrConv(target, vbProperCase)
End Sub