Excel Home VBA培训班小结第四课时Sub过程与程序流程控制语句讲师:ggsmart(叶枫)学员:denkey1内容大纲:一、Sub过程二、程序流程控制语句在前面的课程中,学习了VBA的开发环境,并通过录制宏功能认识到宏这种最简单的VBA程序的学习,对宏有了较为清楚的认识。
录制宏是一个很方便也很有用的功能,特别是简单重复的操作,使用录制宏和执行宏能极大提高工作效率。
尽管如此,使用录制宏功能得到的VBA代码,仍有很多的局限性,比如:不能进行人机交互,不能进行判断、循环等,宏只是简单录制下来执行的每一个步骤语句。
显然,这远不能满足我们的需要。
那么,自己动手编写可以随意控制的程序以满足更高的需求,就是这一节课教给我的东西。
一、Sub过程1、过程过程就是一个小程序,是一组相关操作命令的组合,即一个过程就是一组完成所需操作的VBA代码的组合。
VBA中每一个程序都包含过程,且VBA的主体结构就是过程。
VBA的过程主要包括Sub过程和Function过程两种,两种过程的区别在于:Sub过程不可以返回程序运行的值,Function过程可以返回程序的运行值,即前者不可以返回值,后者可以返回值。
本次课主要学习的是Sub过程。
2、声明Sub过程录制的宏就是一个简单的Sub过程,使用录制宏功能只能生成Sub过程的代码。
在示例1中通过录制宏功能,得到如下代码:通过观察比较以上的两个宏代码,可以发现Sub过程的特点:(1)以“Sub过程名()”开头,以“End Sub”结尾;(2)Sub过程一般保存在“模块”里;(3)不返回运行结果。
声明Sub过程的语法形式为:[Public | Private | Friend] [Static]Sub过程名称([参数1,参数2……]) [语句块][Exit Sub][语句块]End Sub其中,[]中括号括起来的部分表示可选的参数,如[Public | Private | Friend]、[Static]等,这些关键字与作用的范围有关,只能选择一个,含义分别为:(1)Public表示声明的过程是一个公共的过程,即该工作簿中的其它模块中的过程也可以访问声明的这个过程;(2)Private表示声明的过程是一个私有的过程,只有在同一个模块中的其它过程才可以访问声明的这个过程。
(3)Friend用在类模块里。
(4)Static是静态的意思,表示声明的过程中的局部变量将被保存,在下次调用的时候仍保存原来的值。
蓝色部分的Sub过程名称()、End Sub是必须的,分别标明过程的开始和结束。
括号里的[参数1,参数2……]是一系列的变量,以逗号分隔将传递的参数值,如果过程没有任何参数,可以省略,如以上录制的两个宏都是没有参数的Sub过程。
[Exit Sub]表示在过程结束之前强制退出。
3、试着编写一个Sub过程新打开的VBE编辑器,在工程资源管理中的空白处单击右键,选择“插入→模块”,便新建了一个模块。
可以在同一个模块里编写多个过程,也可以保存在不同的模块中。
双击“模块1”,便可在右边的代码窗口编写Sub过程。
在模块中创建一个名为“mysub”的Sub过程如下:同时,将光标定位至代码中,点击鼠标右键,选择Smart Indent→Indent Procedure,调整代码的缩进,如图:调整后,如下:将光标定位至此代码中,点击工具栏中的“运行子过程/用户窗体”按钮,或按快捷键F5,运行此过程,弹出一个对话框,如下图:此过程中并未设定Public或Private等显示关键字,则按照缺省的情况为Public过程,即默认为公共的过程。
如果不打算公开某个过程,则要在Sub前面加Private关键字,定义为私有过程。
在刚才建立的模块中建立一个名为“siyou”的私有过程并运行如下:4、从过程执行另一个过程上面的两个过程都只有一行代码,诚然VBA并没有限定代码的行数,可以在一个过程里编写成千上万条代码,但随着代码行数的增加,错误也可能会增加。
因此,将很长的代码分拆到多个过程里,通过创建一些小型过程代替单个的大型过程,是一种很好的编程习惯。
从过程执行另一个过程共有三种方法。
(1)输入过程名称以及参数,参数用逗号隔开;过程名[,参数1,参数2,…]在刚才的模块中建立一个名为“test”的过程,调用执行“mysub”过程,代码如下:将光标定位至代码中执行此过程,便弹出刚才的第一个对话框。
或者将光标定位至上述代码中的mysub之后,点击菜单栏中“工具→宏”,选择执行名为test的宏。
注意到,上面的宏对话框中并没有名为siyou的过程,这是因为此工程是一个私有的过程。
虽然不显示,但仍然可以调用。
(2)在过程名称以及参数前使用Call关键字,参数用括号括起来,并用逗号隔开;Call过程名[(参数1,参数2,…)](3)利用Application对象的Run方法。
Application. Run表示过程名的字符串(或字符串变量)[,参数1,参数2,…]Application. Run “mysub”直接调用过程名,也可以定义一个字符串变量,并将过程名赋值,如Application. Run a。
以上为从过程执行另一个过程的三种方法,都是在同一个模块中调用,如果在其它模块中是否都能调用呢?经尝试后,发现定义为Private的过程在不同的模块中是无法调用的。
二、程序流程控制语句——判断与循环语句是过程的核心,VBA语句按执行顺序可以分为顺序结构语句、判断分支语句和循环语句。
顾名思义,顺序结构语句就是从上到下由程序的第一行执行到最后一行,如赋值和过程调用语句等,录制的宏代码也属于此类语句;判断分支语句也叫结构选择语句,是根据条件,跳过部分语句执行另一部分的语句;循环语句就是重复执行某一段语句。
本次课学习的是判断分支语句和循环语句,判断分支语句主要有If语句和Select Case语句,循环语句主要有For语句和Do 语句。
1、If语句If语句根据条件变量的不同来执行,语句形式为:If逻辑表达式Then语句块1[Else语句块2]End If可以理解为“如果…那么…[否则…]”,其中[Else]是可选部分,程序执行时,先运行“逻辑表达式”,如果为真,则执行语句块1,如果为假,则执行Else部分的语句块2,同时If语句也可以嵌套使用。
分开表述如下:(1)If-Then语句结构为:If逻辑表达式Then语句块End If可以理解为“如果…那么…”,如果逻辑表达式的结果为True,则执行语句块里的所有语句,否则执行End If后面的语句。
其中语句块可以是一句指令或多条指令,也可以调用一个或多个过程,当然也可以为空,即没有语句。
当语句块比较简单的时候,可以省略“End If”,如If逻辑表达式Then语句块此语句的执行流程可用下图表示:(2)If-Then-Else语句结构为:If逻辑表达式Then语句块1Else语句块2End If可以理解为“如果…那么…否则…”,如果逻辑表达式的结果为True,则执行语句块1里的所有语句,否则执行语句2里的所有语句。
(3)If-Then-ElseIf语句结构为:If逻辑表达式1 Then语句块1ElseIf逻辑表达式2 Then语句块2ElseIf逻辑表达式3 Then语句块3…Else语句块nEnd If可以理解为“如果…那么…否则如果…那么…否则…”,可以有多句“否则如果…”,若逻辑表达式1的结果为True,则执行语句块1,截至继续执行End If后面的语句;若逻辑表达式1的结果为False,则检查逻辑表达式2的结果,若为True则执行语句块2,接着继续执行End If后面的语句……,一直到所有结果的条件都不满足时,才执行Else后面的语句块n。
2、Select Case语句Select Case语句同If语句一样,也是条件判断的语句,其功能也可以用If语句来完成。
但是,当程序的条件太多,用If语句来判断就存在一些不足了,比如程序是否美观、是否便于阅读、程序的执行效率等。
Select Case语句在执行的效率上,比If语句要快得多,同时更加简洁明了,也更加适合设计多种选择。
而通常情况下只把If 语句用在二元判定上。
Select Case语句的结构为:Select Case测试表达式Case表达式列表1语句块1Case表达式列表2语句块2Case表达式列表3语句块3…Case表达式列表n语句块n[Case Else语句块n+1]End Select对以上结构的说明:(1)测试表达式必须为数值表达式或字符串表达式;(2)表达式列表可以是用逗号分开的表达式,也可以使用To 或Is关键字,如:Case 1, 2, 3, 4Case 1 To 4Case Is < = 4(3)Case语句后面可以使用多重表达式,各表达式的数据类型可以不相同,之间是“逻辑或”的关系,如:Case 1 To 4, “a”在执行程序的时候,不管满足于哪一个条件,都会执行相关的语句块。
首先,根据测试表达式的值进行判断,如果与表达式列表1相匹配,则执行语句块1,跳过其它Case的语句,执行End Select后面的语句;如果测试表达式的值与表达式列表1不匹配,则判断其与表达式列表2是否匹配,如若匹配,则执行语句块2,并跳过其它的语句,执行End Select后面的语句……,依次类推,如果测试表达式的值与表达式列表1—n都不匹配,则执行语句块n+1,如果没有[Case Else 语句块n+1],则直接执行End Select后面的语句。
因为Select Case语句只要执行了一个匹配的语句就会退出判断,为最大限度的提高有效性,在编写程序时应该把最有可能发生的情况写在最前面。
3、For-Next循环语句结构为:For循环变量=初值To终值[Step步长]循环体[Exit For]循环体Next[循环变量]其中[Step步长]为步长值,可以为正数,也可以为负数,但不能为0,当步长值为正数时,初值要小于终值,当步长值为负数时,终值要大于终值,当步长值省略时默认为1。
循环语句的执行次数取决于循环变量的初值、终值和步长。
[Exit For]为强制终止循环的语句,执行后将退出循环,执行Next 后面的语句。
另外,可在Next的上面一行加入语句Debug. Print i在立即窗口中查看循环变量值的变化,便于理解变量的执行过程。
循环变量是一个变量,可以在循环体中对其进行修改。
For-Next 语句的执行流程可用下图表示:4、For Each-Next循环语句结构为:For Each元素变量In对象集合语句块[Exit For]语句块Next[元素变量]和For-Next循环语句的句式基本相同,只是第一句的元素变量是用来遍历集合或数组中的所有元素的变量,它从集合或数组中的第一个元素开始,直到最后一个元素,执行语句块,然后退出循环后再执行Next后面的语句,同时可以在循环语句中加入一个或多个[Exit For]来终止循环。