For...Next循环重复执行一组语句,直到循环次数达到指定次数为止。其格式如下:
For 〈变量〉=〈初值〉 To 〈终值〉 Step 〈步长〉
〈语句块〉
Next 〈变量〉
下面举例说明For循环的使用方法。
设计算机等级考试成绩存放在Deg_Score工作表上,其中笔试成绩存放在E列、上机成绩存放在F列,且这两个区域分别命名为Pening、Operating。现需要创建一个宏,将不及格的以红色显示、成绩优秀(笔试成绩和上机成绩都在85分以上)的以绿色显示。相应的VBA宏程序如下所示:
Sub DegreeScore( )
Dim i As Integer
For i = 1 To Range("Pening").Cells.Count
If Range("Penging").Cells(i) < 60 Then
Range("Pening").Cells(i).Interior.Color = vbRed
End If
If Range("Operating").Cells(i) < 60 Then
Range("Operating ").Cells(i).Interior.Color = vbRed
End If
If Range("Pening").Cells(i) > 85 And Range("Operating ").Cells(i) > 85 Then
Range("Pening").Cells(i).Interior.Color = vbGreen
Range("Operating ").Cells(i).Interior.Color = vbGreen
End If
Next i
End Sub
其中,Range("Pening").Cells.Count给出了区域内单元格的个数;Range("Pening").Cells(i)返回Pening区域内的第i个单元格;Range对象的Interior属性返回引用的新对象:Interior对象。Interior对象控制单元格内部的颜色和图案格式。此外,在Visual Basic中已经为常用颜色预先定义了名字,引用时直接引用颜色的名字即可。
〈语句块〉
Next 〈对象变量〉
其中,For Each语句的作用类似于Set语句,将对象引用赋值给变量。不过For Each语句是将同一对象集中的每个对象引用依次赋值给同一变量。For Each循环的功能是为对象集中的每个对象重复执行一组语句。
下面举例说明For Each循环的使用方法。
Excel提供了打印预览工作表的方法,然而,每次只能对活动工作表进行打印预览。假设现有一个包含若个部门预算工作表的工作簿,在打印前需要预览每一个预算工作表,那么可使用For Each循环编写如下宏实现:
Sub PrintPreviewSheets( )
Dim mySheet As Worksheet
For Each mySheet In Worksheets
mySheet.Select
mySheet.PageSetup.Orientation = xlLandscape
mySheet.PrintPreview
Next mySheet
End Sub
PrintPreviewSheets宏的执行过程是:依次将工作表集合中的每个对象(工作表)引用赋值给变量mySheet,再选定对象指针指向的对象(即激活工作表),然后将页打印方向设置为横向,最后打印预览该工作表。
同样,可使用For循环编写宏实现上述功能:
Sub PrintPreviewSheets( )
Dim mySheet As Worksheet
Dim i As Integer
For i = 1 To Worksheets.Count
Set mySheet = Worksheets(i)
mySheet.Selete
mySheet.PageSetup.Orientation = xlLandscape
mySheet.PrintPreview
Next i
End Sub
请注意区分:For语句是将一个值赋给变量,而For Each语句是将一个对象引用赋给变量。通常,使用For Each循环比使用For循环更方便、更快捷,但For循环的使用范围更广。例如,当需要利用计数器控制循环时,或要在两个同类的对象集(如两个区域)之间进行比较时,就只能使用For循环,而不能使用For Each循环。
For Each循环通过对象集来控制循环的执行与结束,For循环通过计数器的初值、终值、步长来控制循环执行的次数。然而在某些情况下,需要通过条件判断来控制循环的执行与结束。为此,Visual Basic提供了另一种更有效的循环控制结构:Do循环。
Visual Basic提供了多种灵活的Do循环形式,一方面可以用Until 〈条件〉或while 〈条件〉来控制循环,另一方面Until 〈条件〉和while 〈条件〉既可放在Do语句中,也可放在Loop语句中,使用十分方便。其中,最常用的Do循环格式如下:
Do While 〈条件表达式〉
〈语句块〉
Loop
该Do循环的功能是:只要条件为真,就重复执行语句块,直到条件为假时才结束循环,执行Loop语句的下一条语句。
下面举例说明Do While循环的使用方法。
假设需要对活动工作簿的Sheet1工作表先按第一列数据进行排序,然后删除包含重复数据的行,使用Do While循环编写如下VBA宏实现:
Sub DeleteRepeatData( )
Worksheets("Sheet1").Range("A1").Sort_
key1 :=Worksheets("Sheet1").Range("A1")
Set currentCell = Worksheets("Sheet1").Range("A1")
Do While Not IsEmpty(currentCell)
Set nextCell = currentCell.Offset(1, 0)
If nextCell.Value = currentCell.Value Then
currentCell.EntireRow.Delete
End If
Set currentCell = nextCell
Loop
End Sub
Do循环具有很强的适应性,但使用时必须保证在循环体内有产生循环结束的程序代码,以避免出现死循环。譬如,在本例中若没有Set currentCell = nextCell语句,就会出现死循环。
VBA提供了功能强大的分支结构和循环结构。如果能将循环控制结构与条件控制结构联合使用,则可以设计出灵活多变、功能强大的宏。
在VBA的整个程序结构中,自定义函数是非常重要且十分方便的工具。
自定义函数的结构与过程的结构非常相似,只是自定义函数的参数是必不可少的,且具有返回值。其基本结构如下所示:
Function 〈函数名〉(〈参数1〉,〈参数2〉,…)
〈语句块〉
End Function
下面举例说明用户如何建立自定义函数。
Excel和Visual Basic都有产生0与1之间随机数的函数。Excel的随机函数RAND( )可用于工作表,而Visual Basic的随机函数Rnd只能用于Visual Baisc宏。现建立一个可随时随地调用,不受上述限制的产生随机数的自定义函数Random。其宏程序如下:
Function Random(Optional Midpoint = 0.5, Optional Range = 0.5, Optional Round = False)
Application.Volatile True
Random = Rnd * (Range * 2) + (Midpoint - Range)
If Round Then
Random = CLng(Random)
End If
End Function
其中:
函数的参数Midpoint、Range、Round描述了随机数区间,依次给出了:区间中点、正负范围、是否对随机数进行四舍五入取整运算。
函数参数前的关键字Optional设定参数为可选项,参数后用等号给出参数的默认值。
Application.Volatile True语句使得该函数为易失函数。对于大多数函数,只有当与函数的参数相关联的单元格值改变时,才重新计算。而有些函数(如Excel中的RAND( )函数),只要工作表任何一个单元格的值发生变化或按F9键,便重新计算,具有这种性质的函数称为易失函数。
函数CLng将一个数舍入成整数,再转换为长整型。
例如,选定某一单元格,键入下列公式:
=Random(1000,500,True)
则在此单元格产生1000-500到1000+500,即500到1500之间的随机整数。