2016-11-08 255 views
0

我真的不知道为什么VBA编译器唠叨我,因为GoTo Jump,分别Jump:Excel VBA:在for循环中跳转:“Next without For” - 我做错了什么?

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:移动到最左边,但允许它停留在第二个缩进级别,因此之内for -loop,as它似乎。 (难道,即使有关系吗?)

+2

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

回答

1

试试这个(修订标记注释):

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 

但是你应该避免goto方法

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 SubWith必须一端与End With,一个For必须一端与Next。正确的缩进和小程序机构通常有助于获得正确的结果。

很多其他语言(C#,Java和C++等)有什么使一个有效的代码块(不匹配{}括号中使用它们AFAIK每一种语言编译器错误)类似的限制,所以这不是VBA挑剔或抱怨没有理由。

这就是说很难判断你的代码是否存在错误,以及你的代码在哪里存在错误,因为你没有包含整个过程范围,所以我们不得不假设你的代码片段中没有其他东西 - 并且你发布的代码片段丢失了一个End Ifas 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 > 1重复两次,所以有进一步重组的空间。但是,已经所有GoTo都没有了。