开始结束循环结束variables中间循环
从testing数据开始:
并运行代码:
Sub TestLoop() Dim LastRow As Long, CurRow As Long LastRow = Range("A" & Rows.Count).End(xlUp).Row For CurRow = 1 To LastRow Range("B" & CurRow).Value = "Done" LastRow = 2 Next CurRow End Sub
我期望循环在第2行结束,因为我更改了variablesLastRow
。 但结果是:
对于VB.NET的MSDN参考有这样的说法 :
当
For...Next
循环启动时,Visual Basic会计算start
,end
和step
。 Visual Basic仅在此时评估这些值,然后将start
分配给counter
。 在语句块运行之前,Visual Basic比较end
。 如果counter
已经大于end
值(或者如果step
是负值,则计数值更小),则For loop
结束并且控制传递给Next
语句后面的语句。 否则,语句块将运行。每次Visual Basic遇到
Next
语句时,它都会逐步递增并返回到For
语句。 它再次比较counter
的end
,再次运行模块或退出循环,具体取决于结果。 这个过程一直持续到counter
传递end
或遇到Exit For
语句。 [强调我的]
鉴于它每次迭代检查counter
的end
,不应该改变variables的end
?
我想在这里注意一些事情。 首先,你正在引用VB.Net文档。 所以,在谈论VBA时,我不会那么依赖。 事实上, For...Next
语句的VBA文档根本没有提到这种行为。 所以,我深入了一点,VBA确实和VB.Net一样。 以下是来自[MS-VBAL]:VBA语言规范 。
expression式
<start-value>
,<end-value>
和<step-increment>
将按照以下任一计算顺序进行一次评估。
这意味着您的示例中的LastRow
仅在首次进入循环时计算。 之后改变它对循环的运行次数没有影响。 (不是我build议试着这样做,开始。)
这也意味着你不能改变循环中间执行的步骤的大小,这段代码同时显示了这两者的“奇怪”行为。
Sub TestLoop() Dim LastRow As Long, CurRow As Long, StepsToTake As Integer LastRow = 100 StepsToTake = 2 For CurRow = 1 To LastRow Step StepsToTake Range("B" & CurRow).Value = "Done" LastRow = 2 StepsToTake = 1 Next CurRow End Sub
对于那些感兴趣的,这里是For...Next
语句的整个运行时语义。
运行时语义。
expression式
<start-value>
,<end-value>
和<step-increment>
将按照以下任一计算顺序进行一次评估。 如果<start-value>
,<end-value>
和<step-increment>
的值不是Let强制为Double,则立即引发错误13(types不匹配)。 否则,请使用原始未强制值继续执行以下algorithm。执行
<for-statement>
根据以下algorithm进行:
如果
<step-increment>
的数据值为零或正数,且<bound-variable-expression>
的值大于<end-value>
,则<forstatement>
执行立即完成; 否则,进入步骤2。如果
<step-increment>
的数据值是一个负数,并且<bound-variable-expression>
的值小于<end-value>
,那么<for-statement>
立即完成; 否则,进入步骤3。
<statement-block>
被执行。 如果存在一个<nested-for-statement>
,那么它将被执行。 最后,将<bound-variable-expression>
的值添加到<step-increment>
的值中,并将Let指定回<bound-variable-expression>
。 执行然后在步骤1重复。如果在
<for-statement>
之外定义的<goto-statement>
导致<statement-block>
<statement>
内的<statement-block>
被执行,则expression式<start-value>
,<end-value>
和<step-increment>
没有评估。 如果在执行包含过程期间,<statement-block>
完成并到达<statement-block>
的结尾,而未评估<start-value>
,<end-value>
和<step-increment>
生成错误(编号92,“For循环未初始化”)。 即使包含明确初始化<bound-variable-expression>
的赋值expression式,也会发生这种情况。 否则,如果已经计算了expression式<start-value>
,<end-value>
和<step-increment>
,则algorithm按照执行<for-statement>
所定义的规则在步骤3继续。当
<for-statement>
完成执行时,<bound-variable-expression>
的值保持在循环完成时保持的值。
鉴于正确的MSDN参考提到:
expression式
<start-value>
,<end-value>
和<step-increment>
将按照以下任一计算顺序进行一次评估。
看来,即使包含end
数量的variables发生变化,Visual Basic CAN也会记住循环end
时的值。
以上面的@ Chrismas007的回答为基础,如果要在For
结构的范围内短路回路,可以将递增的variables设置为终止值:
For CurRow = 1 To LastRow Range("B" & CurRow).Value = "Done" ' This will end the loop. ' When Next is hit, CurRow will be LastRow + 1. CurRow = LastRow ' Alternately, you can exit the for loop immediately. ' Usually this would be inside an If statement. Exit For Next CurRow