3.2 案例07:认识If函数
打开本书资料文件中的“案例07:认识If函数.xls”,得到图3-3所示的工作表。本案例要求对该工作表进行以下操作:
- 如果“性别”为男,则在“称呼”列中填入“先生”,否则填入“女士”;
- 如果“专业类”为理工,则在“专业代号”列中填入“LG”,如果“专业类”为文科,则填入“WK”,如果“专业类”为财经,则填入“CJ”;
- 删除“姓名”为空的行。

图3-3 案例07的工作表
3.2.1 案例解析
案例07要求进行大量的逻辑判断,因此需要使用VBA的If函数。在VBA中,If函数用于进行条件判断,其语法如下:
If 条件 Then
结果
End If
当If函数中的“条件”为真时,则执行“结果”。如代码清单3-7所示,当A1单元格的值为1时,则在B1单元格中写入数值2。
代码清单3-7
If Range("A1") = 1 Then
Range("B1") = 2
End If
还可以在If函数中加入关键字Else,表示当“条件”不为真时,执行语法中的“结果2”:
If 条件 Then
结果1
Else
结果2
End If
对于案例07中的第一个要求,可以使用If函数对E列的单元格进行判断,若单元格的值为“男”,则在“称呼”列(F列)中写入“先生”,否则在“称呼”列中写入“女士”。以E2单元格为例,相关代码如代码清单3-8所示。
代码清单3-8
If Range("E2") = "男" Then
Range("F2") = "先生"
Else
Range("F2") = "女士"
End If
然后,将代码清单3-8嵌入For循环,就能完成对工作表中整个“称呼”列进行的操作,代码如代码清单3-9所示。
代码清单3-9
For i = 2 To 26 '工作表共有26行数据
If Range("E" & i) = "男" Then
Range("F" & i) = "先生"
Else
Range("F" & i) = "女士"
End If
Next
If函数还可以使用关键字ElseIf对3种及3种以上的情况进行判断,语法为:
If 条件1 Then
结果1
ElseIf 条件2 Then
结果2
ElseIf 条件3 Then
结果3
……
Else
结果n
End If
当条件1为真时,执行结果1;若条件1不为真,则判断条件2是否为真,为真则执行结果2;若条件2不为真,则判断条件3是否为真,为真则执行结果3……当所有条件都不为真时,执行结果n。
在案例07的工作表中,“专业代号”列有3种值,分别对应3种“专业类”。使用For循环与If函数对“专业类”进行判断和处理,代码见代码清单3-10。
代码清单3-10
For i = 2 To 26
If Range("B" & i) = "理工" Then
Range("C" & i) = "LG"
ElseIf Range("B" & i) = "文科" Then
Range("C" & i) = "WK"
Else
Range("C" & i) = "CJ"
End If
Next
创建一个“判断”过程,在过程中,将代码清单3-9和代码清单3-10合并至同一个For循环,并使用英文单引号对代码进行注释,得到代码清单3-11。
代码清单3-11
Sub 判断()
Dim i As Integer
For i = 2 To 26
'根据性别判断称呼
If Range("E" & i) = "男" Then
Range("F" & i) = "先生"
Else
Range("F" & i) = "女士"
End If
'根据专业类判断专业代码
If Range("B" & i) = "理工" Then
Range("C" & i) = "LG"
ElseIf Range("B" & i) = "文科" Then
Range("C" & i) = "WK"
Else
Range("C" & i) = "CJ"
End If
Next
End Sub
执行“判断”过程,结果如图3-4所示,案例07的前两个目标已完成。

图3-4 执行“判断”过程后的结果
接下来处理案例07的第三个要求:删除姓名为空的行。
在VBA中,双引号中不加任何字符、数字或符号表示空。代码清单3-12表示当A1单元格为空时,在A2单元格中写入数值1。
代码清单3-12
If Range("A1") = "" Then
Range("A2") = 1
End If
删除整行的代码需要通过录制宏获取。以删除D4单元格(“姓名”列第一个为空的单元格)所在的行为例,首先,使用绝对引用,开始录制宏,然后,选中D4单元格,单击鼠标右键并选择“删除”,在弹出的对话框中,选择“整行”,如图3-5所示,最后,单击“确定”按钮,停止录制。

图3-5 选中D4单元格并删除整行
录制所得的代码如代码清单3-13所示,其中第2行代码表示选中D4单元格,第3行代码表示删除所选单元格所在的行。
代码清单3-13
Sub 宏1()
Range("D4").Select
Selection.EntireRow.Delete
End Sub
将录制所得的代码嵌入For循环,见代码清单3-14。
代码清单3-14
For i = 2 To 26
If Range("D" & i) = "" Then '判断“姓名”列是否为空,为空则整行删除
Range("D" & i).Select
Selection.EntireRow.Delete
End If
Next
但是,在执行代码清单3-14中的For循环后,工作表中依然存在“姓名”列为空的行,如图3-6所示。

图3-6 执行代码清单3-14中的For循环后依然存在“姓名”列为空的行
这是因为在Excel中进行删除整行操作时,会导致删除的行以下的所有数据全部上移一行,如在录制代码清单3-13所示的代码时,删除第4行后,原来的第5行就上移成为第4行,原来的第6行上移成为第5行,以此类推。
这种现象导致利用For循环和If函数对“姓名”列进行循环判断并删除“姓名”列为空的行时,有可能出现漏判断的情况。例如,For循环执行至第4行时,If函数判断发现“姓名”单元格为空,则删除此行,此时,第4行以下的数据全部上移一行。For循环继续执行到第5行,而此时的第5行是工作表中原来的第6行,原来的第5行此时已经上移并成为第4行,这就意味着工作表中原来的第5行“逃过”了If函数对“姓名”列的判断。如果原来第5行的“姓名”单元格为空,那么代码的最终执行结果会出错。
因此,在编写判断并删除整行的VBA代码时,应考虑从下向上进行判断,即使删除一行数据导致下面的数据上移,也不会影响继续判断上面的数据。
修改代码清单3-14中的For循环,将计数变量i的取值范围设置为26至2,并将步长设置为−1,这样可实现从下向上对工作表进行判断,代码见代码清单3-15。
代码清单3-15
For i = 26 To 2 Step –1 '从下向上进行判断
If Range("D" & i) = "" Then '判断“姓名”列是否为空,为空则删除整行
Range("D" & i).Select
Selection.EntireRow.Delete
End If
Next
3.2.2 案例代码
将代码清单3-15合并至代码清单3-11。为了保证正确删除所有“姓名”列为空的行,合并之后的过程代码中的For循环也应从下向上进行判断。合并后的代码如代码清单3-16所示。
提醒一下,在执行VBA代码前,应当对原始数据进行备份,因为VBA代码执行的操作无法撤回!
代码清单3-16
Sub 判断()
Dim i As Integer
For i = 26 To 2 Step -1
'根据性别判断称呼
If Range("E" & i) = "男" Then
Range("F" & i) = "先生"
Else
Range("F" & i) = "女士"
End If
'根据专业类判断专业代码
If Range("B" & i) = "理工" Then
Range("C" & i) = "LG"
ElseIf Range("B" & i) = "文科" Then
Range("C" & i) = "WK"
Else
Range("C" & i) = "CJ"
End If
'删除姓名为空的行
If Range("D" & i) = "" Then
Range("D" & i).Select
Selection.EntireRow.Delete
End If
Next
End Sub
在工作表中执行“判断”宏,所得结果如图3-7所示。

图3-7 “判断”宏的执行结果
3.2.3 案例小结
本案例介绍了If函数的使用方法,同时强调在使用For循环和If函数判断并删除工作表的整行时,应当留意数据上移的情况。
If函数和For循环是VBA中常用的两个过程控制语句,在很多场合可配合使用,以梳理解决问题的逻辑思路。在VBA的众多知识点中,If函数必须熟练掌握。