【问题标题】:Excel VBA: Jump inside a for loop: "Next without For" – What am I doing wrong?Excel VBA:跳入 for 循环:“Next without For”——我做错了什么?
【发布时间】:2017-03-22 10:02:49
【问题描述】:

老实说,我不知道为什么 VBA 编译器会因为 GoTo Jump 和 Jump: 而唠叨我。

    counter2 = 0
    If (counter1 > 1) Then
        For i = 0 To (MaxLastCell - 4)
            If (IncompleteRows(i) = 1) Then
                If ((counter2 > 1) And (counter2 < counter1)) Then
                    x = x + ", " + CLng(i)
                    counter2 = counter2 + 1
                    GoTo Jump
                End If
                If ((counter2 > 1) And (counter2 = counter1)) Then
                    x = x + " and " + CLng(i)
                    GoTo Outside
                If (counter2 = 0) Then
                    x = CLng(i)
                    counter2 = 1
                End If
            End If
Jump:
        Next i

每次我试图运行我的代码时,这个代码 sn-p 似乎都是一个问题。编译器在最底部标记Next,并告诉我有一个"Next without For"。

但是这种编码不应该有效吗?我刚看到here。然而,奇怪的是,那里的编译器似乎并没有强制 B H 将他的跳转点 NextIteration: 移到最左边,而是让它保持在第二个缩进级别,因此 within for-loop,看起来。 (这还重要吗?)

【问题讨论】:

  • 将您的 IF 结构更改为 ElseIF,如下面的答案。然后,您可以删除 goto Jump 行并将 goto Outside 替换为 Exit For。

标签: vba excel for-loop goto


【解决方案1】:

试试这个(用 cmets 标记的修订):

    counter2 = 0
    If (counter1 > 1) Then
        For i = 0 To (MaxLastCell - 4)
            If (IncompleteRows(i) = 1) Then
                If ((counter2 > 1) And (counter2 < counter1)) Then
                    x = x + ", " + CLng(i)
                    counter2 = counter2 + 1
                    GoTo Jump
                End If
                If ((counter2 > 1) And (counter2 = counter1)) Then
                    x = x + " and " + CLng(i)
                    GoTo Outside
                ElseIf (counter2 = 0) Then '<--*** changed from simple 'If'
                    x = CLng(i)
                    counter2 = 1
                End If
            End If
Jump:
        Next i
    End If '<--*** added

但你应该避免 GoTos

【讨论】:

    【解决方案2】:

    那里有一些不错的意大利面条代码。 GoTo 只是适当控制流的一个糟糕替代方案。

    一个GoTo“跳到下一个迭代”是一回事。 GoTo Outside(无论在哪里)的另一个是别的东西。

    VBA(语言规范)不关心行标签从哪一列开始;据我们所知,您链接到的答案是在答案框中输入的,而不是在 VBE 中。当 VBE(IDE/编辑器)看到一个行标签时,它会自动将其移动到第 1 列,就像它自动在运算符和操作数之间插入空格一样,就像它在您键入时自动调整关键字和标识符的大小写一样。所以不,这根本不重要。

    VBA 语法要求关闭块:就像Sub DoSomething() 过程必须 以End Sub 结尾和With 块必须 以End With 结尾, For 块必须以 Next 结尾。适当的缩进和小程序主体通常有助于做到这一点。

    许多其他语言(C#、Java、C++ 等)对于有效代码块的构成有类似的限制(不匹配的 { 和 } 大括号在使用它们的每种语言中都是编译器错误 AFAIK) ,所以这不是 VBA 挑剔或无缘无故抱怨。

    这就是说很难判断您的代码是否以及在哪里格式错误,因为您没有包括整个过程范围,所以我们必须假设在您的 sn-p 和您的 sn-p 之后没有其他内容张贴缺少End If as user3598756 has noted:

    If (counter1 > 1) Then
        '...code...
    End If
    

    那么,如何进行重组呢?

    • 假设Outside 行标签位于End Sub 之前(或者是End Function?),那么您可以将其替换为Exit Sub(或Exit Function)并收工。
      • 如果有更多代码需要在循环之后但在过程范围结束之前运行,Exit For 将让您退出循环,同时让您保持在过程中 - 下一行运行将是第一个可执行语句在Next 令牌之后。
    • 现在采用使循环跳过迭代的条件,并相应地改写循环体;使用ElseIf 来避免评估不需要的条件,并删除所有这些无关紧要和令人困惑的括号:

      If IncompleteRows(i) = 1 And counter2 > 1 And counter2 < counter1 Then
          x = x + ", " + CLng(i)
          counter2 = counter2 + 1
      ElseIf counter2 > 1 And counter2 = counter1 Then
          x = x + " and " + CLng(i)
          Exit For ' assuming...
      ElseIf counter2 = 0 Then
          x = CLng(i)
          counter2 = 1
      End If
      

      这将是整个循环体。当然它仍然可以改进; counter2 &gt; 1 重复了两次,因此还有进一步重组的空间。但已经,所有GoTo 都不见了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 2018-05-30
      • 1970-01-01
      • 2019-06-30
      • 2016-10-20
      • 1970-01-01
      相关资源
      最近更新 更多