对于开始结束循环与结束变量中间循环 [英] For start To end Loop with end Variable Changing Mid-Loop

查看:146
本文介绍了对于开始结束循环与结束变量中间循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从测试数据开始:

并运行代码:

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行,因为我更改了变量 LastRow 。但是结果是:

I would expect the Loop to end at Row 2 because I changed the variable LastRow. However the result is:

MSDN参考对于VB.NET 有这样的说法

The MSDN Reference FOR VB.NET has this to say:


当一个循环开始,Visual Basic计算开始结束步骤。 Visual Basic仅在此时评估这些值,然后将开始分配给计数器。在语句块运行之前,Visual Basic将计数器 end 进行比较。如果计数器已经大于 end 的值(如果 step 为负), For循环结束,控制传递到 Next 语句之后的语句。否则,语句块运行。

When a For...Next loop starts, Visual Basic evaluates start, end, and step. Visual Basic evaluates these values only at this time and then assigns start to counter. Before the statement block runs, Visual Basic compares counter to end. If counter is already larger than the end value (or smaller if step is negative), the For loop ends and control passes to the statement that follows the Next statement. Otherwise, the statement block runs.

每次Visual Basic遇到 Next 语句时,它会递增 counter by step 并返回到对于语句。 再次,将计数器 end 进行比较,再次运行该块或退出循环,取决于结果。这个过程一直持续到 counter pass end Exit For 语句遇到 [强调我的]

Each time Visual Basic encounters the Next statement, it increments counter by step and returns to the For statement. Again it compares counter to end, and again it either runs the block or exits the loop, depending on the result. This process continues until counter passes end or an Exit For statement is encountered. [Emphasis mine]

鉴于它检查 / code>针对结束每次迭代,不应该更改变量更改结束

Given that it checks the counter against the end every iteration, shouldn't changing the variable change the end?

推荐答案

我想在这里注意几点。首先,您引用了 VB.Net 文档。所以,当谈论VBA 时,我不会依赖于这一点。事实上, $ $的VBA文档c $ c> For ... Next 语句根本没有提到这个行为。所以,我挖了一点更深层次,VBA确实与VB.Net一样。以下内容来自 [MS-VBAL]:VBA语言规范

I'd like to note a few things here. First, you're referencing the VB.Net documentation. So, I wouldn't rely on that when talking about VBA. In fact, the VBA Documentation for the For...Next statement doesn't mention this behavior at all. So, I dug a little deeper and VBA does indeed behave the same as VB.Net here. The following is from the [MS-VBAL]: VBA Language Specification.


表达式< start-value> >,按顺序,以及之前的任何以下计算。

The expressions <start-value>, <end-value>, and <step-increment> are evaluated once, in order, and prior to any of the following computations.

这意味着您的示例中的 LastRow 仅在首次输入循环。之后更改对循环运行的次数没有影响。 (不是我建议尝试这样做开始。)

This means that LastRow in your example is only calculated when first entering the loop. Changing it afterward has no effect on the number of times the loop will run. (Not that I advise trying to do that to begin with.)

这也意味着你不能改变循环中间执行的步骤的大小这个代码段一次显示这两个代码的奇怪行为。

This also means that you can not change the size of the steps the loop takes mid-execution as well and this snippet shows the "odd" behavior of both of these at once.

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 语句。


运行时语义


  • 表达式< start-value> < end-value> < step-increment> 是eva一次,按顺序,在任何
    之前进行以下计算。如果< start-value>
    < end-value> code>< step-increment> 不允许强制为Double,
    错误13(类型不匹配)立即被提升。否则,使用原始的,未被执行的值,使用以下算法来执行

  • The expressions <start-value>, <end-value>, and <step-increment> are evaluated once, in order, and prior to any of the following computations. If the value of <start-value>, <end-value>, and <step-increment> are not Let-coercible to Double, error 13 (Type mismatch) is raised immediately. Otherwise, proceed with the following algorithm using the original, uncoerced values.

执行< for-statement> ; 根据以下算法进行:

Execution of the <for-statement> proceeds according to the following algorithm:


  1. 如果数据值< step-increment> 为零或正数,< bound-variable-expression> 的值大于
    < end-value> 的值,然后执行< forstatement>
    立即完成

  1. If the data value of <step-increment> is zero or a positive number, and the value of <bound-variable-expression> is greater than the value of <end-value>, then execution of the <forstatement> immediately completes; otherwise, advance to Step 2.

如果数据值< step-increment> 一个负数,< bound-variable-expression> 的值小于$ code> ; ,执行< for-statement> 立即
完成;

If the data value of <step-increment> is a negative number, and the value of <bound-variable-expression> is less than the value of <end-value>, execution of the <for-statement> immediately completes; otherwise, advance to Step 3.

执行< statement-block> 如果存在< nested-for-statement> ,则执行它。最后,
< bound-variable-expression>
值被添加到
< step-增加> 并让我们分配回
< bound-variable-expression> 。执行然后在步骤1重复。

The <statement-block> is executed. If a <nested-for-statement> is present, it is then executed. Finally, the value of <bound-variable-expression> is added to the value of <step-increment> and Let-assigned back to <bound-variable-expression>. Execution then repeats at step 1.


  • 如果< goto-statement> ;在< for-statement> 之外定义的导致一个< statement>
    表达式< start-value> ,执行< statement-block> code>< end-value> 和< step-increment> 不评估
    。如果< statement-block> 的执行完成,并且
    到达< statement-block> 没有评估
    < start-value> < end-value> 和在
    执行封闭程序期间,< step-increment> 会生成错误(数字
    92,For循环未初始化) 。即使
    包含明确地初始化
    < bound-variable-expression> 的赋值表达式,即使这样也会发生。否则,如果
    表达式< start-value> < end-value> ,以及< step-increment>
    已经被评估,算法继续在步骤3
    根据为执行< for-statement>

  • If a <goto-statement> defined outside the <for-statement> causes a <statement> within <statement-block> to be executed, the expressions <start-value>, <end-value>, and <step-increment> are not evaluated. If execution of the <statement-block> completes and reaches the end of the <statement-block> without having evaluated <start-value>, <end-value> and <step-increment> during this execution of the enclosing procedure, an error is generated (number 92, "For loop not initialized"). This occurs even if contains an assignment expression that initializes <bound-variable-expression> explicitly. Otherwise, if the expressions <start-value>, <end-value>, and <step-increment> have already been evaluated, the algorithm continues at Step 3 according to the rules defined for execution of a <for-statement>.

    < for-statement> / code>已经执行完毕,< bound-variable-expression> 的值保持在
    循环完成时保存的值。

    When the <for-statement> has finished executing, the value of <bound-variable-expression> remains at the value it held as of the loop completion.

    这篇关于对于开始结束循环与结束变量中间循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆