2016-11-08 6 views
0

VBAコンパイラがなぜGoTo JumpのそれぞれJump:のために私にとばわれているのか、正直に分かりません。Excel VBA:forループ内をジャンプ: "For 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:を左に移動させるように強制していないようだが、それは2番目のインデントレベルにあるので、for -loopそうみたいです。 (?でもかまいというん。)

+2

IF構造を以下のようなElseIFに変更してください。ジャンプのジャンプ行を削除してgoto Outsideを 'Exit For'で置き換えることができます。 –

答えて

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 

をしかし、あなたはそこにいくつかの素晴らしいスパゲッティコードを持っているGOTOS

1

を避ける必要があります。 GoToは、適切な制御フローの貧弱な代替方法です。 "次の繰り返しにスキップする"

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

一つGoToは一つのことです。 GoTo Outsideへの別のもの(どこにいても)は別のものです。

VBA(言語仕様)では、行ラベルがどの列で開始されるかは気にしません。私たちが知っているすべてのものは、VBEではなく、あなたが答えた答えが回答ボックスに入力されています。 VBE(IDE /エディタ)で行ラベルが表示されると、演算子とオペランドの間に自動的に空白が挿入されるように、列ラベルが自動的に列1に移動し、入力時に自動的にキーワードと識別子の囲みが調整されます。そうではありません。全く問題ではありません。

VBAの構文が閉じられるようにブロックが必要です。ちょうどEnd SubEnd WithNextで終わらなければなりませんForブロックを終了する必要がありWithブロックで終了する必要がありますSub DoSomething()手順のように。適切な押し込みや小規模の手技体は、通常、この権利を得るのに役立ちます。

他の言語の多く(のC#やJava、C++など)(不一致{}中括弧は、私の知る限り、それらを使用するすべての言語でのコンパイルエラーです)有効なコードブロックを作るものについて同様の制約があるので、このVBAが何の理由もなく不快であると不平を言っているわけではありません。

あなたのコードが不正であるかどうかを判断するのは難しいと言われています。手順のスコープ全体が含まれていないため、スニペットに続くものがないと仮定する必要があります。 End Ifas user3598756 has noted:だから

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

、この再編について移動する方法?Outside行ラベルがちょうどEnd Subの前に位置する(またはそれがEnd Functionある?)されたと仮定すると、

  • 、あなたはExit Sub(またはExit Function)と交換し、その日にそれを呼び出すことができます。
    • ループの後で、プロシージャスコープの最後の前に実行する必要があるコードがさらにある場合は、手順の中に入れてループを抜け出します。実行する次の行が最初の実行文これはNextトークンの後に続きます。
  • ここで、ループに繰り返しをスキップさせ、それに応じてループ本体を改訂する条件を指定します。

    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 
    

    そして、それがループの本体全体のようになります。あなたがする必要がある、これらのすべての余分なと混乱括弧を削除しない条件を評価避けるためにElseIfを使用しています。もちろん、それはまだ改善することができます。 counter2 > 1が2回繰り返されているため、今後の再編の余地があります。しかし、すでに、GoToのすべてがなくなってしまった。

関連する問題