Excel VBA:跳转到for循环:“Next for For For” - 我做错了什么?

时间:2016-11-08 17:09:06

标签: excel vba excel-vba for-loop goto

老实说,我不知道为什么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

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

但这种编码不应该起作用吗?我刚看到它here。然而,奇怪的是,那里的编译器似乎没有强迫B H将他的跳跃点NextIteration:移动到最左边但是允许它保持在第二个缩进级别,因此,< em>在 for - 循环中,看起来如此。 (这甚至重要吗?)

2 个答案:

答案 0 :(得分:2)

试试这个(评论中标注的修订版):

    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

答案 1 :(得分:1)

那里有一些不错的意大利面条代码。 GoTo只是适当控制流程的不良替代品。

Neal Stephenson thinks it's cute to name his labels 'dengo'

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

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

VBA语法要求关闭块:就像Sub DoSomething()过程必须End Sub结束而With必须End With结尾,For必须Next结尾。适当的缩进和小程序机构通常有助于实现这一目标。

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

那说很难判断你的代码是否以及在哪里格式错误,因为你没有包含整个程序范围,所以我们必须假设你的代码片段后面没有其他内容 - 而且你发布的代码片段丢失了End If as user3598756 has noted

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

那么,如何进行重组呢?

  • 假设Outside行标签位于End Sub之前(或者是End Function?),那么您可以将其替换为Exit Sub(或{{1}并称之为一天。
    • 如果有更多的代码需要在循环之后但在程序范围结束之前运行,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 > 1已经消失了。