你必须按下Ctrl+Break键(译者:现在,有些电脑使用别的组合键来中断程序。例如我的手提电脑
就是Fn+Break)才能终止该无限循环,当VB显示信息“代码执行被中断”时,点击结束以退出过程。
另外一种方便的循环Do…Until,也可以让你重复一条或多条语句,直到条件为真。换句话说,
Do…Until语句是只要当某个条件为假的时候重复一块代码。这是它的语法:
Do Until 条件
语句1
语句2
语句N
Loop
使用上面的语法,你可以将前面的过程ApplyBold重新写成下面的方式:
Sub ApplyBold2()
Do Until IsEmpty(ActiveCell)
ActiveCell。Font。Bold = True
ActiveCell。Offset(1; 0)。Select
Loop
End Sub
该过程的第一条语句意思是执行下列语句,直到遇到第一个空单元格。结果上,如果当前单元格不
为空,VB就执行循环内部的那两条语句。只要条件IsEmpty(ActiveCell)测试为假,这个过程就反
复继续着。因为过程ApplyBold2在循环的前面就测试条件,如果第一个单元格就为空的话,循环内
部的语句就不会运行。在下一段,你将有机会试验它。
和Do…While循环类似,Do…Until循环也有第二种语法让你在循环的底部测试条件:
Do
语句1
语句2
语句N
Loop Until 条件
如果你想要程序至少执行一次,那么就将条件放置于Loop语句一行,无论条件的值是什么。
我们来试验一下下面的例子,该例子将工作簿里的空工作表删除。
1。 在你前面创建的DoLoop模块里输入下面的过程DeleteBlankSheets:
Sub DeleteBlankSheets()
Dim myRange As Range
Dim shcount As Integer
shcount = Worksheetsunt
Do
116
… 页面 133…
Worksheets(shcount)。Select
Set myRange = ActiveSheet。UsedRange
If myRange。Address = 〃A1〃 And _
Range(〃A1〃)。Value = 〃〃 Then
Application。DisplayAlerts = False
Worksheets(shcount)。Delete
Application。DisplayAlerts = True
End If
shcount = shcount … 1
Loop Until shcount = 1
End Sub
2。 手动在当前工作簿里面插入一些工作表。在一个工作表里输入一些数据与单元格A1;另一个工
作表的单元格B2和C10里输入一些数据;第三个工作表里不要输入任何数据。
3。 运行过程DeleteBlankSheets。当你运行该过程时,无论何时,只要两个条件都为真——属性
UsedRange返回单元格A1并且A1为空,VB就会删除所选的工作表。属性UsedRange应用于对象
Worksheet,包含工作表中的每个非空单元格以及他们之间的空单元格。例如,如果你在单元
格B2和C10里输入里东西(译者:包括格式),使用了的区域为B2:C10。如果你后面又在A1
里输入了数据,那么UsedRange将会是A1:C10。已使用区域是一个从左上角最远的地方到
右下角最远的地方包围起来的区域。因为工作簿至少要保留一个工作表,所以代码执行到变量
shcount等于1时就停止了。语句shcount = shcount…1确保变量shcount在循环里面的代码每执
行一次就减少1。变量shcount的值在过程的开始处用下列语句:Worksheetsunt初始化了。
注意,当删除工作表的时候,Excel通常会显示一个确认对话框,如果你不想看到这个确认提
示框的话,就是要下列语句:
Application。DisplayAlerts = False
当你完成任务时,使用下列语句,再打开系统信息。
Application。DisplayAlerts = True
技巧6…3 计数器
计数器是个数字变量,用来追踪已进行的项目次数。上面的过程DeleteBlankSheets声明了变量
shcount来追踪检查的工作表个数。计数器变量必须在程序的开始就被初始化(赋值),这可以确保
你总能在开始使用之前知道计数器的确切值。计数器可以按照确定的值增加或减少。参见本章后面
的使用计数器的For…Next循环。
2。观察过程执行
当你使用循环结构运行过程时,有时很难看到该过程会按预期地执行。有时,你很想观察程序慢慢
地运行,这样你就能够检查该程序的逻辑。我们来看看VB如何让你一行接一行地执行程序。
1。 在单元格区域A1:A5里面输入任何数据
2。 选择单元格A1
3。 在Excel窗口,选择“工具”…“宏”…“运行宏”
4。 在宏对话框里,选择ApplyBold2并点击“单步执行”按钮。VB编辑屏幕将出现,过程的名称被
黄色加亮(参加图6…1)。注意代码窗口左边的黄色箭头。
117
… 页面 134…
图6…1 观察程序一行接一行地执行
5。 使VB窗口缩小一些,可以点击VB标题栏的“还原”按钮缩小窗口
6。 按下F8,黄色加亮区将跳到DoUntil IsEmpty(ActiveCell)行
7。 继续按F8,同时观察代码和工作表窗口
3。While…Wend 循环
While…Wend循环功能上和Do…While循环一样,它是从Microsoft Basic的早期版本遗留下来的并
且VBA保留它也是为了支持兼容性。该循环以关键字While开始以关键字Wend结束。这是它的语法:
While 条件
语句1
语句2
语句N
Wend
条件在循环的上面就被测试,只要提供的条件为真,这些语句就会被执行。一旦条件为假,VB就将
退出该循环。我们来看一个使用While…Wend循环结构的过程:
1。 在当前工程里插入一新模块,重命名为WhileLoop
2。 输入下述过程:
Sub ChangeRHeight()
While ActiveCell 〃〃
ActiveCell。RowHeight = 28
ActiveCell。Offset(1; 0)。Select
Wend
End Sub
3。 在单元格区域B1:B4里输入一些数据
4。 选择单元格B1并且运行过程ChangeRHeight。当当前单元格不为空时,上面的过程
ChangeRHeight将设置行高位28。
118
… 页面 135…
4。For…Next 循环
当你知道你需要重复运行多少次某段语句时,可以使用For…Next语句。它的语法如下:
For 计数器 = 开始 To 结束 '步长'
语句1
语句2
语句N
Next '计数器'
括号里面的代码是可选的。计数器是个储存反复次数的数字型变量,开始是你期望的起始计数点,
结束则表明循环应该执行多少次。
例如,你想要重复执行循环里的语句5次,使用下述For语句:
For counter = 1 To 5
你的语句
Next
当VB遇到关键字Next时,它将回到循环的开始处,并且再次执行循环里面的代码,直到计数器到达
结束值。一旦计数器的值大于关键字To后面的数值,VB就会跳出循环。因为计数器变量在每次执行
循环后会自动地变化,它早晚会超出结束的值。每次VB执行循环里的语句后,变量计数器的值会默
认地增加1,你可以使用Step语句来改变这个默认设置。例如,要使计数器每次增加3,就可以使用
以下语句:
For counter = 1 To 5 Step 3
你的代码
Next counter
当VB遇到上面的语句,它会执行循环里的语句两次。在第一次的循环里,counter等于1,第二次则
等于4(3+1)。在执行两次循环后,counter就等于7(4+3),这导致VB退出该循环。
注意,步长(Step)是可选的。可选语句总是显示则方括号里面(参加本段开头部分的语法)。步
长不需要明确,除非它不等于1。你可以在Step后面放个负值作为步长,那么VB每次遇到关键字Next
后都会将计数器减小。
关键字Next后面的变量名称(counter)也是可选的,然而,好的编程习惯是要强制在关键字Next
后面加上计数器。
如何将For…Next循环使用在Excel里面呢?假使你只想要在你的销售报告里面包括某几个特定月
份的产品销售,当你从Access导入数据时,你同样也会将那些销售额为0的数据行一起导入。你如
何快速取出数据为0的行呢?尽管,有很多种方法可以解决这个问题,但是,我们来看看如何使用
For…Next循环来处理这个问题吧。
1。 在VB窗口,在当前工程里插入一个模块并且命名为ForNextLoop
2。 在ForNextLoop模块里输入下列过程:
Sub DeleteZeroRows()
Dim totalR As Integer
Dim r As Integer
Range(〃A1〃)。CurrentRegion。Select
totalR = Selection。Rowsunt
Range(〃B2〃)。Select
For r = 1 To totalR…1
If ActiveCell = 0 Then
Selection。EntireRow。Delete
totalR = totalR – 1
Else
ActiveCell。Offset(1; 0)。Select
End If
Next r
End Sub
3。 切换到Excel界面,并且准备下述表格:
119
… 页面 136…
A B
1 Product Name Sales (in Pounds)
2 Apples 120
3 Pears 0
4 Bananas 100
5 Cherries 0
6 Blueberries 0
7 Strawberries 160
4。 运行过程DeleteZeroRows。
我们来一行接一行地检查一下过程DeleteZeroRows。开始两语句计算当前区域的总行数,并且将该
值储存于变量totalR,接下来,VB选择单元格B2然后遇到关键字For。因为电子表格的第一行包含
了列标题,所以要从总行数里减掉1(totalR…1)。VB将需要执行循环里面的指令6次。
嵌套在循环里面的条件语句(If…Then…Else)告诉VB根据当前活动单元格的值作出决定。如果该
值为0,VB就删除当前行,并且将总行数减掉1。否则,条件为假,因此,VB将选择下一行的单元格。
VB每完成一次循环,它就跳到关键字For来比较r的值和totalR…1的值。当过程结束后,销售表里就
不会包含没有销售的产品了。
技巧6…4 成对语句
For和Next必须是成对的,如果有一个漏掉了,VB就将产生一个错误信息“For没有Next”
5。For Each…Next 循环
当你的过程需要在一个集合的所有对象或者一个数组的所有元素(数组将在第七章里涉及)之间循
环�