У вас есть какой-то хороший код спагетти там. GoTo
- лишь плохая альтернатива правильному потоку управления.
Один GoTo
к "перейти к следующей итерации", это одно. Другой - GoTo Outside
(где бы это ни было) - это что-то другое.
VBA (спецификация языка) не заботится о том, в какой колонке начинается метка линии; для всех, кого мы знаем, ответ, на который вы ссылались, был введен в поле ответа, а не в VBE. Когда VBE (IDE/editor) видит метку линии, она автоматически перемещает ее в столбец 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
(или 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
исчезли.
Измените структуру IF на ElseIF, как показано ниже. Затем вы можете удалить строку перехода goto и заменить goto Outside на 'Exit For'. –