У меня есть цикл, который идет от -55 до -1, затем от 1 до 55, прежде чем снова вернуться к -55. Я хочу сделать цикл, идущий от произвольной точки в этом цикле к другой произвольной точке, но никогда не доходя до полного цикла.
Поскольку конечное значение счетчика может быть больше или меньше начального значения, я изначально сделал условие выхода для цикла, которое fra
равно til
.
Однако я также хочу что-нибудь сделать, когда fra = til
, так что в итоге мой цикл выглядел так, как вы можете видеть ниже, с вспомогательной переменной, запускающей выход.
Я не очень доволен тем, как это в итоге выглядело, мне кажется, что логика немного неуклюжая. Есть ли способ улучшить приведенный ниже код?
Option Explicit
Dim første_økt_anodeskift(1 To 10, 1 To 2) As Long
Const farge_anodeskift_1 As Long = 14395790 ' RGB(142, 169, 219)
Sub main()
Dim syklus As Long
syklus = 1
Call legg_inn_verdier
Call fargelegg(første_økt_anodeskift(syklus, 1), første_økt_anodeskift(syklus, 2), farge_anodeskift_1)
End Sub
Private Sub fargelegg(fra, til, farge)
Dim exit_on_next As Boolean
exit_on_next = False
Do
' Do stuff
If exit_on_next Then Exit Do
fra = fra + 1
If fra = 0 Then
fra = 1
ElseIf fra = 56 Then
fra = -55
End If
If fra = til Then exit_on_next = True
Loop While True
End Sub
Private Sub legg_inn_verdier()
første_økt_anodeskift(1, 1) = -11: første_økt_anodeskift(1, 2) = 6
End Sub
```
2 ответа
Может, тебе так кажется лучше. Инкапсуляция логики цикла в специализированные одноцелевые процедуры обычно упрощает чтение и понимание цикла (IMO). В этом случае условия цикла, требующие повторного выполнения кода «в последний раз», также становятся немного более ясными.
Option Explicit
Dim første_økt_anodeskift(1 To 10, 1 To 2) As Long
Const farge_anodeskift_1 As Long = 14395790 ' RGB(142, 169, 219)
Sub main()
Dim syklus As Long
syklus = 1
Call legg_inn_verdier
Call fargelegg(første_økt_anodeskift(syklus, 1), første_økt_anodeskift(syklus, 2), farge_anodeskift_1)
End Sub
Private Sub fargelegg(fra, til, farge)
Do
DoStuff fra, til, farge
fra = GetNextFra(fra)
If fra = til Then
DoStuff fra, til, farge
Exit Do
End If
Loop While True
End Sub
Private Sub legg_inn_verdier()
første_økt_anodeskift(1, 1) = -11: første_økt_anodeskift(1, 2) = 6
End Sub
Private Sub DoStuff(fra, til, farge)
' Do stuff
End Sub
Private Function GetNextFra(fra) As Variant
fra = fra + 1
If fra = 0 Then
fra = 1
ElseIf fra = 56 Then
fra = -55
End If
GetNextFra = fra
End Function
Если можно, я дам вам дополнительный совет. Я заметил, что ваши идентификаторы написаны на норвежском языке (?). Обычно рекомендуется использовать простой ASCII и даже имена на английском языке.
Проблема с идентификаторами: некоторые компиляторы или интерпретаторы могут иметь проблемы с нестандартными символами. Поведение не всегда четко документируется и может быть непредсказуемым. Норвежский (или датский …) должен быть в порядке, но я не уверен, что VBA по-прежнему поддерживает полный диапазон Unicode. В контексте VBA и Windows ссылкой, вероятно, является набор символов Windows-1252, который должен охватывать большинство латинских алфавитов.
Но если вы использовали имена переменных арабским или японским шрифтом, я не уверен, как программа отреагирует.
Проблема с использованием имен переменных на вашем родном языке заключается в том, что иностранцам будет труднее понять логику вашего кода, потому что имена для них не интуитивно понятны.
Все больше и больше проектов командная работа, они также могут развиваться в проекты с открытым исходным кодом и публиковаться на Github. Если вы не используете английский язык, вы ограничиваете аудиторию возможных последователей и участников.
Кроме того, переменные с суффиксами типа _1 или _2 — плохие имена. Это верный признак того, что соглашения об именах нуждаются в улучшении.
Второе, что я заметил, это отсутствие Комментарии. Это типичный спагетти-код VB, за которым нелегко следить за потоком выполнения из-за:
- структура, плюс процедуры вызова, которые имеют циклы
- язык (выбор идентификаторов)
- отсутствие комментариев
Все эти факторы в совокупности приводят к тому, что код становится трудным для понимания посторонними, такими как мы.
Комментарии очень важны не только для таких рецензентов, как мы, но и для коллег или других людей, которым, возможно, придется настроить ваш код во время вашего отпуска или после того, как вы уволились из компании. Самое главное, что комментарии также для вас, потому что через 6 месяцев вы забудете ход своих мыслей, вам придется заново проанализировать собственный код тура и, черт возьми, вы думали.
Проще говоря, Комментарии делает цель вашего кода более ясной.
Кроме того, вам следует избегать таких многострочных операторов:
første_økt_anodeskift(1, 1) = -11: første_økt_anodeskift(1, 2) = 6
Всего две строчки, это более читабельно (несмотря на то, что намерение не проясняется):
Private Sub legg_inn_verdier()
første_økt_anodeskift(1, 1) = -11
første_økt_anodeskift(1, 2) = 6
End Sub
Но обратите внимание, как аккуратно выстроены утверждения.
С точки зрения спектакль и ясность: выберите правильный тип данных для переменных и возвращаемых значений. Это означает, что не используйте тип данных Long для коротких чисел. См. Этот пост для более подробного обсуждения типов данных VBA.
Функция GetNextFra
возвращает целочисленное значение, поэтому не объявляйте функцию как вариант. Всегда. Целое число (или длинное, как указано в вышеупомянутом сообщении) должно подойти.
Эта функция может быть упрощена (и должна). Если у вас есть цикл, который вы хотите сбросить на 55, вам нужен модуль. Реализация будет такой (непроверенной):
Private Function GetNextFra(fra) As Integer
GetNextFra = (fra mod 55) +1
End Function
Что делает эта функция: возвращает fra + 1, если fra = 55, тогда мы сбрасываем счетчик на 1. Если это не совсем то, что вам нужно, вы можете внести соответствующие изменения. Вуаля.
Но поскольку эта функция теперь однострочная, вы также можете отказаться от нее. Скопируйте однострочный текст в тело вашей программы. Выполнено. Вы уже упростили код.
Честно говоря, я не совсем понимаю, что на самом деле делает ваш код. Если бы я это сделал, то, возможно, мог бы предложить еще несколько идей.
Нет необходимости в
Call
— FreeMan
Да, мне нравится такой подход, спасибо за вклад 🙂
— Эйрикдауде