乐于分享
好东西不私藏

Excel VBA 编程基础 — 语句(十)- 循环语句(三)

Excel VBA 编程基础 — 语句(十)- 循环语句(三)

今天我们继续讨论循环语句。
今天的循环语句是 Do Until … Loop,其一般形式是:
Do Until condition[ statements ][ Exit Do ][ statements ]Loop
Do Until 和昨天的 Do While 正好相反:
  • Do While condition … Loop:如果 condition 为 True 则一直循环
  • Do Until … Loop:一直循环直到 condition 为 True
还是看例子。
例1. 求和 0 + 1 + 2 + … + 9
Dim total As IntegerDim i As Integertotal = 0i = 0Do Until i >= 10total = total + ii = i + 1LoopDebug.Print total
Do Until i >= 10 … Loop:这个循环结构表示“一直循环,直到 i 大于等于 10”。循环体包含两个语句:
  • total = total + i:表示对 i 累计求和
  • i = i + 1:递增循环控制变量,从而循环能够终止
这个循环如果用 Do While 来写,只需要写成 Do While i < 10 即可。
如果用 For … Next 循环结构来写,可以写成下面的样子:
Dim total As IntegerDim i As Integertotal = 0For i = 0 To 9total = total + 1Next iDebug.Print total
从上面的代码可以看出,For … Next 结构中没有更新循环控制变量的语句,对循环控制变量的更新隐含在了 For … Next 结构中。
昨天的例子中我们用到了 VBA 的 Find 方法,Find 方法的一般形式是:
robj.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
Find 方法参数众多,功能强大,不仅可以根据单元格的值来定位,还可以根据公式甚至注释来寻找。有了循环语句之后,我们可以自己写一个简单的 Find。因为还没有讨论 VBA 的 Sub 和 Function,我们就写一段代码,根据给出的值来寻找所在的单元格。
例2. 使用 For … Next 循环寻找单元格
Dim rowAsIntegerDim col AsIntegerDim cell AsRangeDim v As Variant= ""奉止Set cell = NothingForrow=1To100For col =1to100    If Cells(row, col).Value= v ThenSet cell = Cells(row, col)      Exit For' 找到了,退出当前的 col 循环    End If  Next col  If Not (cell Is Nothing) Then    Exit For  ' 已找到,退出 row 循环End IfNext rowIf cell Is Nothing Then  MsgBox "未找到单元格"End If
这段代码使用了嵌套的 For 循环,因为所要寻找的区域是一个二维的行、列结构,必须使用两重循环才能覆盖这个二维区域。另外还要注意的是,Exit For 只能退出当前循环。在 col 循环中,找到匹配单元格后,用 Exit For 退出当前的 col 循环,而在 row 循环中,使用 Not (cell Is Nothing) 来判断 cell 是否已经赋值,表达式为 True 说明 cell 已赋值,而赋值说明已经找到,因此退出 row 循环。表达式为 False 说明 cell 仍然是 Nothing,因此递增 row 进入下一行继续循环。
因为我们要搜索的区域是一个确定边界的二维行列结构,因此使用 For … Next 循环就是一个很自然的选择,当然也可以用 Do While 和 Do Until 来实现。
例3. 使用 Do While … Loop 循环寻找单元格
Dim rowAsIntegerDim col AsIntegerDim cell AsRangeDim v As Variant= "奉止"Set cell = Nothingrow=1Do While (row<=100And (cell Is Nothing)  col =1  Do While (col <=100And (cell Is Nothing)    If Cells(row, col).Value= v ThenSet cell = Cells(row, col)  ' 已找到    Else      col = col + 1               ' 未找到,继续下一列End If  Looprow=row+1LoopIf cell Is Nothing Then  MsgBox "未找到单元格"End If
Do While (row <= 100) And (cell Is Nothing) 表示 row <= 100 并且 cell 仍然为空的时候就继续循环,直到 row > 100 或者 cell 不为空时为止。
Do While (col <= 100) And (cell Is Nothing) 表示 col <= 100 并且 cell 仍然为空时就继续循环,直到 col > 100 或者 cell 不为空时为止。
col 循环的循环体是一个 If 语句,判断当前单元格的值是否与给定的值匹配,如果匹配则找到,使用 Set 语句为 cell 变量赋值,如果不匹配则递增 col 循环控制变量,进入下一轮循环。如果 col > 100,则结束当前的 col 循环,进入下一轮 row 循环。
在这个 Do While 循环的例子中,因为对 cell 是否为空的判断(cell Is Nothing)已经写在了 Do While 的条件中,因此就不需要再使用 Exit Do 来中途退出了。
例4. 使用 Do Until … Loop 循环寻找单元格
Dim rowAsIntegerDim col AsIntegerDim cell AsRangeDim v As Variant= "奉止"Set cell = Nothingrow=1Do Until (row>100OrNot (cell Is Nothing)  col =1  Do Until (col >100OrNot (cell Is Nothing)    if Cells(row, col).Value= v ThenSet cell = Cells(row, col)Else      col = col +1End If  Looprow=row+1LoopIf cell Is Nothing then  MsgBox "未找到单元格"End If
仔细观察 Do While … Loop 和 Do Until … Loop 的代码,可以看到,唯一的区别就在于二者条件表达式的不同:
  • W_condition:(row <= 100) And (cell Is Nothing)
  • U_condition:(row > 100) Or Not (cell Is Nothing)
对于这两个循环语句:
DoWhile W_condition ' 如果 W_condition 为真则一直循环...Loop
DoUntil U_condition  ' 一直循环直到 U_condition 为真...Loop
两个条件表达式的关系是:
  • W_condition = Not U_condition
  • U_condition = Not W_condition
相关阅读
Excel VBA 编程基础 — 语句(八)- 循环语句
Excel VBA 编程基础 — 语句(九)- 循环语句(二)