[英]Excel VBA: Jump inside a for loop: “Next without For” – What am I doing wrong?
I honestly do not know why the VBA compiler is nagging me because of that GoTo Jump
, respectively Jump:
. 老实说,我不知道为什么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
Every time I am trying to run my code, this code snippet appears to be a problem. 每当我尝试运行我的代码时,此代码段似乎都是一个问题。 The compiler marks
Next
at the very bottom and tells me that there is a "Next without For"
. 编译器在最底部标记了
Next
,并告诉我有一个"Next without For"
。
But shouldn't this kind of coding work? 但是这种编码方式不应该吗? I just saw it here .
我在这里看到了 。 A strange thing, however, is that the compiler there did not seem to coerce BH to move his jumping point
NextIteration:
to the very left but allowed it to stay at the second indent level and, thus, within the for
-loop, as it seems. 但是,奇怪的是,那里的编译器似乎没有强迫BH将其跳转点
NextIteration:
移到最左边,但允许它停留在第二个缩进级别,因此在 for
-loop中,因为它似乎。 (Does that even matter?) (这有关系吗?)
try this (revision marked in comments): 尝试一下(注释中标记为修订):
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
but you should avoid GoTos 但您应避免使用GoTos
You've got some nice spaghetti code there. 您那里有一些不错的意大利面条代码。
GoTo
is but a poor alternative to proper control flow. GoTo
只是适当控制流的替代品。
One GoTo
to "skip to next iteration" is one thing. GoTo
“跳到下一个迭代”是一回事。 Another to GoTo Outside
(wherever that is) is something else. GoTo Outside
(无论在哪里)的另一个问题是。
VBA (the language spec) doesn't care on which column a line label starts; VBA(语言规范)不在乎行标签从哪一列开始; for all we know the answer you linked to was typed in the answer box, not in the VBE.
因为我们知道您链接到的答案都是在答案框中键入的,而不是在VBE中键入的。 When the VBE (the IDE/editor) sees a line label, it moves it to column 1 automatically, just like it automatically inserts spaces between operators and operands, and just like it automatically adjusts the casing of keywords and identifiers as you type them.
当VBE(IDE /编辑器)看到行标签时,它会自动将其移动到第1列,就像它在运算符和操作数之间自动插入空格一样,就像在键入它们时自动调整关键字和标识符的大小写一样。 So no, it doesn't matter at all.
所以,没有关系。
VBA syntax requires blocks to be closed: just like a Sub DoSomething()
procedure must end with End Sub
and a With
block must end with End With
, a For
block must end with Next
. VBA语法要求关闭块:就像
Sub DoSomething()
过程必须以End Sub
结尾,而With
块必须以End With
, For
块必须以Next
结尾。 Proper indentation and small procedure bodies usually help getting this right. 适当的缩进和较小的过程主体通常有助于实现此目的。
A lot of other languages (C#, Java, C++, etc.) have similar constraints about what makes a valid code block (mismatched {
and }
braces are a compiler error in every language that uses them AFAIK), so this isn't VBA being picky or complaining for no reason. 许多其他语言(C#,Java,C ++等)对于有效代码块的构成也有类似的限制(不匹配的
{
和}
大括号是使用AFAIK的每种语言的编译器错误),所以这不是VBA无故挑剔或抱怨。
That said it's hard to tell whether and where your code is malformed, because you're not including the entire procedure scope so we have to assume there's nothing else that follows your snippet - and the snippet you've posted is missing an End If
as user3598756 has noted : 也就是说,很难判断您的代码是否格式错误以及在何处格式错误,因为您没有包括整个过程范围,因此我们必须假设在代码段之后没有其他内容-并且您发布的代码段缺少
End If
as user3598756指出 :
If (counter1 > 1) Then
'...code...
End If
So, how to go about restructuring this? 那么,如何进行重组呢?
Outside
line label is located just before End Sub
(or is it End Function
?), then you can replace it with Exit Sub
(or Exit Function
) and call it a day. Outside
标签位于End Sub
前面(或者是End Function
吗?),则可以将其替换为Exit Sub
(或Exit Function
)并将其命名为Day。
Exit For
will get you out of the loop while keeping you inside the procedure - next line to run will be the first executable statement that follows the Next
token. Exit For
将使您退出循环,同时将您保留在过程内-下一行将是紧随Next
的第一条可执行语句。令牌。 Now take the condition that makes the loop skip an iteration, and rephrase the loop body accordingly; 现在考虑使循环跳过迭代的条件,并相应地重新定义循环主体; use
ElseIf
to avoid evaluating conditions you don't need to, and remove all these extraneous and confusing parentheses: 使用
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
And that would be the entire body of the loop. 这就是循环的整个过程。 Of course it could still be improved;
当然,它仍然可以改进。
counter2 > 1
is repeated twice, so there's room for some further restructuring. counter2 > 1
重复两次,因此有进行进一步重组的空间。 But already, all GoTo
's are gone. 但是已经所有的
GoTo
都消失了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.