开始结束循环结束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会计算startendstep 。 Visual Basic仅在此时评估这些值,然后将start分配给counter 。 在语句块运行之前,Visual Basic比较end 。 如果counter已经大于end值(或者如果step是负值,则计数值更小),则For loop结束并且控制传递给Next语句后面的语句。 否则,语句块将运行。

每次Visual Basic遇到Next语句时,它都会逐步递增并返回到For语句。 它再次比较counterend ,再次运行模块或退出循环,具体取决于结果。 这个过程一直持续到counter传递end或遇到Exit For语句。 [强调我的]

鉴于它每次迭代检查counterend ,不应该改变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进行:

    1. 如果<step-increment>的数据值为零或正数,且<bound-variable-expression>的值大于<end-value> ,则<forstatement>执行立即完成; 否则,进入步骤2。

    2. 如果<step-increment>的数据值是一个负数,并且<bound-variable-expression>的值小于<end-value> ,那么<for-statement>立即完成; 否则,进入步骤3。

    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