第4章 程序控制
当计算机获得数据后,接下来的任务就是处理这些数据,处理数据离不开对数据的判断选择和代码的重复执行过程。本章介绍了VBA代码中常见的代码控制语句,包括了分支结构和循环结构。在代码执行过程中要能够人机交互,本章介绍了Msgbox、Inputbox函数的用法以及内置对话框的用法,通过这些知识用户就能够和程序做简单的互动。
4.1 分支结构
在本章以前的各章中,语句的执行顺序总是由上到下逐语句的执行,这相当于汉语学习过程中的简单句。仅仅只有简单句来进行编程是不够的,通常还需要使用分支结构。分支结构就是条件判断结构,类似汉语语法中的“如果……就……”。
4.1.1 单一分支结构
单一分支结构就是只包含一个判断条件的分支结构。在VBA中用得最多的单一分支结构语句就是“If……Then”语句,其书写方法可以有单行结构,也可以有多行结构。
1. 判断表达式
If关键字后跟的内容是判断表达式。当判断表达式的值为True的时候,那么就会执行Then语句后的内容,当判断表达式的值为False的时候,则不执行Then后的内容。
判断表达式是指用关系运算符或者逻辑运算符进行运算的表达式。例如
● If a>60 then …… '表示只有变量a的值大于60才会执行Then语句后的内容。
● If a>60 or a<90 then……'表示变量a的值大于60或者小于90都会执行Then语句后的内容。
● If a>60 And xb="男" then ……'表示只有变量a的值大于60并且xb变量的值为男才会执行Then语句后的内容。
2. 单行结构
将Then后要执行的代码写在和If在同一行内就是单行结构。其书写方式如下所示。
If表达式Then执行某种操作
例如当员工的工资超过2000元的时候才会被要求缴纳个人所得税,假设工资用变量gz来表示,下述代码就包含了这个判断过程。
If gz > 2000 Then Debug.Print "应缴纳个人所得税"
3. 多行结构
如果要执行的操作步骤较多,那么执行的操作可以放置在多行内书写。Then关键字后要执行的代码和If不在同一行内就是多行结构,一般来说多行结构比单行结构更容易理解和修改。其书写方式如下所示。
If表达式Then
执行某操作1
执行某操作2
……
End IF
在多行结构中,If和End If总是成对出现的。
例4-01:假设在D2单元格内放置了员工的工资,当该员工的工资超过2000元的时候,在E2单元格内显示应纳税所得额,(也就是工资超过2000元的部分称为应纳税所得额)。并在F2单元格内显示“需要纳税”。
所使用的代码如下所示:
#001: Sub多行结构演示() #002: Dim gz As Single #003: gz = Sheet1.Range("d2") #004: If gz > 2000 Then #005: Sheet1.Range("e2") = gz -2000 #006: Sheet1.Range("f2") = "需要纳税" #007: End If #008: End Sub
第2行代码定义了一个变量gz。第3行代码中“Sheet1.Range("d2")”就表示Sheet1工作表的D2单元格,这种引用工作表单元格的方法将在以后章节中介绍。gz变量的取值就来自于该单元格。第4行代码将gz变量的值和2000进行判断,如果gz的值超过了2000就会接着执行第5行和第6行代码。第5行代码表示将Sheet1工作表中的E2单元格更改的值更改为“gz-2000”,工资扣除2000后的金额就是应纳税所得。第6行代码表示将Sheet1工作表的F2单元格中的值更改为“需要纳税”。
如果Sheet1工作表的D2单元格的值小于或者等于2000,那么程序将什么也不做。
技巧
在书写上述代码的时候,表示单元格的“d2”不用写成“D2”,VBA代码不区分大小写。输入“End If”时候,可以当做一个单词输入为“endif”,换行后程序会自动将其更改为“End If”,但是有类似结构的End With不能这样书写。
4.1.2 多分支结构
实际应用中,需要判断的条件表达式通常都不止一个。例如判断某个学生成绩是否及格的时候就需要将成绩和60分比较,如果成绩比60分小,那么就属于“不及格”等次,如果成绩比60分大,就属于“及格”等次,这实际上就涉及到两个判断条件。需要再增加判断分支。多分支结构可以分为简单的多分支结构和复杂的多分支结构。
1. 简单的多分支结构
简单的多分支结构只涉及到一个条件的判断,其语法结构为:
If 表达式 Then 执行操作1 Else 执行操作2 End If
这种结构的含义就是“如果表达式的结果为True,那么就执行操作1,否则就执行操作2”。“Else”的含义相当于“否则”的意思,表示除了已经设定的条件外另外的那种可能。在这种结构中,程序首先判断条件是否成立,如果判断条件的运算结果为True,那么就执行操作1中表示的代码,如果判断的条件不成立,那么就会跳过执行操作1的代码而直接进入执行操作2的过程中。
例4-02:某学生的成绩记录在工作表的D2单元格内,如果该成绩小于60分就在E2单元格内标出成绩评价“不及格”,否则就在E2单元格内标出成绩评价“及格”。
#001: Sub简单多行结构演示() #002: Dim cj As Single #003: cj = Sheet1.Range("d2").Value #004: If cj < 60 Then #005: Sheet1.Range("e2").Value = "不及格" #006: Else #007: Sheet1.Range("e2").Value = "及格" #008: End If #009: End Sub
第2行代码声明了一个名为cj的变量名,该变量用来存储D2单元格中的数值,第4行代码对变量cj的值进行判断,如果cj小于60条件成立,那么就执行第5行代码,第5行代码的含义就是在E2单元格中更改为“不及格”;如果cj小于60这个条件不成立,那么将跳过第5行代码,直接就执行第7行代码。第7行代码就是将E2单元格的值更改为“及格”。假设在D2单元格内输入的值为71,那么最终运行的结构就会在E2单元格内显示“及格”字样。
2. 复杂的多分支结构
在编程中可能会遇到更加麻烦的情况,在上例中,用户仅仅对成绩进行了判断及格还是不及格,但是很多时候除了这种判断外,还需要对60分以上的成绩再次进行分类,同样会分为良好、优秀等其他等次。
对于这种情况,显然还必须增加判断分支,复杂的多分支结构的表示方法如下所示:
If 表达式1 Then 执行表达式1为真时的操作 ElseIF 表达式2为真 Then 执行表达式2为真时的操作 ElseIF …… …… Else 除了上述条件外的其他情况时候的操作 End If
在上述结构中,关键字ElseIf的含义相当于“否则如果”,表示要进行下一个条件判断。Else关键字的含义相当于“否则”的意思,表示除了已经设定的条件外剩下的最后那种可能。
例4-03:假设在D2单元格内放置了员工的工资,当该员工的工资超过2000元的时候,在E2单元格内显示应纳税所得额,并在F2单元格内显示需要纳税的金额。假设企业的最高月工资不会超过40000元,根据上述条件,使用代码计算个人所得税。
个人所得税采用的纳税税率及纳税办法如表4-1所示。只要将应纳税所得额乘以税率减去速算扣除数就是应纳个人所得税的金额。
表4-1 个人所得税税率表
用代码来表示计算方法如下所示。
#001: Sub复杂多分支结构演示() #002: Dim sde As Single #003: Dim sds As Single #004: sde = Sheet1.Range("d2") -2000 #005: If sde > 20000 Then #006: sds = sde * 0.25-1375 #007: ElseIf sde > 5000 Then #008: sds = sde * 0.2-375 #009: ElseIf sde > 2000 Then #010: sds = sde * 0.15-125 #011: ElseIf sde > 500 Then #012: sds = sde * 0.1-25 #013: ElseIf sde > 0 Then #014: sds = sde * 0.05 #015: Else #016: sds = 0 #017: End If #018: Sheet1.Range("e2") = sds #019: End Sub
在上述代码中第2行和第3行代码分别声明了两个变量sde和sds,分别表示应纳税所得额和个人应缴的所得税。第4行代码就是计算了应纳税所得额。从第5行代码开始进入分支结构。第5行代码含义是将应纳税所得额和20000这个标准比较,如果符合该标准则将应纳税所得额乘以0.25减去速算扣除数1375;如果不符合第5行的条件,将进入下一个条件判断,也就是第7行ElseIf后所跟的条件。将应纳税所得额再去和5000比较,如果符合指定的条件将执行第8行代码。第9到第14行代码的含义都是如此。
第15行代码指明了最后一种情况,当判断条件进入最后一种情况时,不需要写明具体的判断条件是什么,而可以直接用“Else”来表示最后一种条件。第16行代码将计算的结构放到了E2单元格中。
说明
“Sheet1.Range("d2")”和“Sheet1.Range("d2").Value”的含义是相同的,Value部分可以省略不输。
4.1.3 Select Case语句
Select Case语句也用于多个判断分支的结构。和If结构相比,Select Case语句更加容易阅读。Select Case的结构如下所示。
Select Case测试表达式 Case 表达式1 执行操作1 Case 表达式2 执行操作2 …… Case Else 执行操作3 End Select
测试表达式可以是数值、字符串表达式或者逻辑表达式,但是和If结构不同的是,该表达式只能是单一的判断条件,而不能同时包含两个或者两个以上的条件。测试表达式要和表达式1或者表达式2等进行比较,如果满足条件,就执行相应的操作。,指令执行完毕后就退出Select Case判断过程。
“Case Else”同样是一种简略的写法,也就是除了已经写出的条件后,最后一种可能的判断条件。
例4-04:假设在D2单元格内放置了员工的工资,当该员工的工资超过2000元的时候,在E2单元格内显示应纳税所得额,并在F2单元格内显示需要纳税的金额。假设企业的最高月工资不会超过40000元,根据上述条件,使用代码计算个人所得税。用Select Case结构来编写代码完成上述任务。
#001: Sub selectcase演示() #002: Dim sde As Single #003: Dim sds As Single #004: sde = Sheet1.Range("d2") -2000 #005: Select Case sde #006: Case Is > 20000 #007: sds = sde * 0.25-1375 #008: Case Is > 5000 #009: sds = sde * 0.2-375 #010: Case Is > 2000 #011: sds = sde * 0.15-125 #012: Case Is > 500 #013: sds = sde * 0.1-25 #014: Case Is > 0 #015: sds = sde * 0.05 #016: Case Else #017: sds = 0 #018: End Select #019: Sheet1.Range("e2") = sds #020: End Sub
从第5行代码对应纳税所得额进行判断,Select Case后就是判断的内容。第6行代码给出了具体判断的条件,判断的条件是“Case Is > 20000”,如果条件成立,那么就用第7行代码所示的公式计算所得税;如果条件不成立,那么就接着判断下一种可能将应纳税所得额和5000进行比较,依此类推。
一直到第16行代码进入最后一种可能,也就是应纳所所得额小于0的情况。当进入最后一种可能性判断的时候,不需要将条件书写出来,而直接用“Case Else”来表示。
说明
说明:在输入条件的时候,“Case Is >20000”实际上只要输入“Case > 20000”,程序会自动改为“Case Is > 20000”。
如果要执行的步骤只有一步,那么可以将Case和执行的指令放置在同一行内,Case和要执行的指令之间用冒号“:”隔开,例如可以将上述代码中第6行和第7行合并为1行代码,用下述方式表述:Case Is > 20000: sds = sde * 0.25-1375
对于判断条件为连续的值,可以用“Case数值1 to数值2”的方式来表示判断条件。
例4-05:利用VBA中的Weekday函数和Now函数来判断系统日期的星期数,如果是星期一到星期五,那么就用消息框显示“今天我们工作”,否则就用消息框显示“今天我们休息”。使用Select Case结构进行代码编写。
Weekday和Now都是VBA中计算星期和日期的函数,使用Weekday(Now)就能计算出当前系统日期的星期数。有关这些函数的应用将在以后章节中予以介绍。
#001: Sub工作日判断演示() #002: Dim a As Integer #003: a = Weekday(Now) #004: Select Case a #005: Case 2 To 6 #006: MsgBox "今天我们工作!" #007: Case Else #008: MsgBox "今天我们休息!" #009: End Select #010: End Sub
第3行代码用Weekday和Now两个函数组合计算出系统日期表示的星期数,并将最终的结构赋值给变量a。在默认情况下,星期日为1,星期一为2,依此类推。第4行代码变量a的值进行判断,第5行代码表示,如果值在2到6的范围内,也就是说处于星期一到星期五,那么就执行第6行代码所示的指令,用消息框显示“今天我们工作!”。剩余的情况,用“Case Else”代替了具体的条件描述,如果满足剩余的这种情况,那么可以就用消息框显示“今天我们休息!”
说明
除了可以用“Case 2 To 6”这种表示方式外,还可以直接将这些数字列举出来,例如第5行代码就可以表示为“Case 2, 3, 4, 5, 6”。
4.1.4 IIF函数
简单的判断除了可以使用If结构和Select Case结构外,还可以使用IIF函数来代替If……Then语句。其使用方法和工作表中的If函数结构类似。其语法结构是:
IIF(条件表达式,表达式结果为True时返回的值或者表达式,表达式结构为False时值返回的值或者表达式)
例4-06:某学生的成绩记录在工作表的D2单元格内,如果该成绩小于60分就在E2单元格内标出成绩评价“不及格”,否则就在E2单元格内标出成绩评价“及格”。使用IIF函数来编写代码。
#001: Sub iif函数演示() #002: Dim cj As Single #003: Dim py As String #004: cj = Sheet1.Range("d2") #005: py = IIf(cj < 60, "不及格", "及格") #006: Sheet1.Range("e2") = py #007: End Sub
第2行和第3行代码声明了两个变量,分别用来表示成绩和相关的成绩等次评价。第4行代码中,将D2单元格的值赋值给变量cj,第5行代码用IIF函数对cj的值和60进行判断,如果判断的结果为True,那么变量py的值就是“不及格”,否则就py的值就是“及格”。第6行代码表示将py的值写入到E2单元格内。