Попытка следовать одной строке If Then с одной строкой ElseIf Then, но ElseIf Then не выполняется.
Не работает. Нет ошибки. Просто не делает ElseIf.
If WD = "Sat" Or WD = "Sun" Then State = "Z"
ElseIf HH >= 16 Then State = "A"
ElseIf HH >= 13 Then State = "B"
ElseIf HH >= 5 Then State = "C"
ElseIf HH >= 4 Then State = "D"
ElseIf HH >= 0 Then State = "E"
Работает как положено:
If WD = "Sat" Or WD = "Sun" Then
State = "Z"
ElseIf HH >= 16 Then State = "A"
ElseIf HH >= 13 Then State = "B"
ElseIf HH >= 5 Then State = "C"
ElseIf HH >= 4 Then State = "D"
ElseIf HH >= 0 Then State = "E"
End If
Можно ли следовать одной строке If Then с одной строкой ElseIf Then's?
Microsoft Visual Basic для приложений 7.1 Microsoft Office профессиональный плюс 2013 Эксель 2013
Нет. Встроенный синтаксис предназначен для коротких условий и быстрых Then и (возможно) быстрых маленьких Else операторов. Если условия нетривиальны, вам нужно использовать блочный синтаксис.
Встроенный синтаксис — это самостоятельный оператор; в VBA терминатор оператора является новой строкой, поэтому токен ElseIf не может начинать строку допустимого кода, если предыдущая строка не была зарегистрирована как условное выражение блочного синтаксиса.
Не уверен, что вы имеете в виду под "нет ошибки" в первом фрагменте... это ошибка компиляции... которая вообще предотвращает запуск кода:
Тем не менее, есть и другие способы выразить эти условия:
State = "Z"
If WD = "Sat" Or WD = "Sun" Then Exit Sub
Select Case HH
Case Is >= 16
State = "A"
Case Is >= 13
State = "B"
Case Is >= 5
State = "C"
Case Is >= 4
State = "D"
Case Is >= 0
State = "E"
End Select
Привет @NOYB, пожалуйста, посмотри на мой отредактированный ответ, я думаю, он должен прояснить отношение к твоему первому фрагменту кода.
Хотя ответ Матье технически правильный - это невозможно с операторами if - позвольте мне попытаться объяснить, почему.
Причина, по которой ваш первый пример не работает, заключается в том, что VBA допускает такой синтаксис:
Sub Demo()
Dim var As Long
If True Then var = 5
Debug.Print var
End Sub
Обратите внимание, что в приведенном выше примере End If не требуется, на самом деле это даже не разрешено и представляет собой синтаксическую ошибку.
If True Then var = 5 End If 'Syntax error!
Это означает, что после однострочного оператора If VBA считает блок If завершенным. Вот почему следующий пример приводит к ошибке компиляции ("ElseIf без If"):
If Wd = "Sat" Or Wd = "Sun" Then State = "Z" 'VBA considers If block complete here
ElseIf HH >= 16 Then State = "A" '"ElseIf without If"
Причина, по которой вы не увидели ошибку в своем примере, заключалась в том, что ваш фрагмент был заключен в другое выражение If.
В этом случае это действительно работает, просто не так, как вы ожидали. Возможно, следующий пример с правильным отступом может продемонстрировать это:
Sub Demo()
Dim State As String, Wd As String, HH As Long
HH = 10
Wd = "Do" '"Sat"
If True Then '<-- Will always get entered -> ElseIfs will never do anything
If Wd = "Sat" Or Wd = "Sun" Then State = "Z"
ElseIf HH >= 16 Then State = "A" '<-- all of the following ElseIfs will not
ElseIf HH >= 13 Then State = "B" ' get executed, because they belong to
ElseIf HH >= 5 Then State = "C" ' the same block as the "If True Then",
ElseIf HH >= 4 Then State = "D" ' which was already entered. In this
ElseIf HH >= 0 Then State = "E" ' case they are dead code and will never
End If ' do anything!
Debug.Print State
End Sub
VBA допускает однострочные ElseIf внутри уже запущенного If-блока, например:
If WD = "Sat" Or WD = "Sun" Then
State = "Z"
ElseIf HH >= 16 Then State = "A"
End If
Причина этого в том, что здесь EndIf является обязательным, поэтому синтаксис однозначен. Используя это, вы можете создать то, что, возможно, наиболее близко к фактическому ответу на ваш вопрос:
Sub Demo()
Dim State As String, Wd As String, HH As Long
HH = 10
Wd = "Do" '"Sat"
If False Then
ElseIf Wd = "Sat" Or Wd = "Sun" Then State = "Z"
ElseIf HH >= 16 Then State = "A"
ElseIf HH >= 13 Then State = "B"
ElseIf HH >= 5 Then State = "C"
ElseIf HH >= 4 Then State = "D"
ElseIf HH >= 0 Then State = "E"
End If
Debug.Print State
End Sub
Это If утверждение выглядит немного странно, но оно работает! Возможно, это обходной путь, который вы ищете. Если нет, есть дополнительные варианты с использованием синтаксиса продолжения строки с Select Case.
Select Case также может оценивать любое условие, как и операторы if, используя Select Case True, как показано в следующем фрагменте кода:
Sub Demo()
Dim State As String, Wd As String, HH As Long
HH = 10
Wd = "Do" '"Sat"
Select Case True:
Case Wd = "Sat" Or Wd = "Sun": State = "Z"
Case HH >= 16: State = "A"
Case HH >= 13: State = "B"
Case HH >= 5: State = "C"
Case HH >= 4: State = "D"
Case HH >= 0: State = "E"
End Select
Debug.Print State
End Sub
Кроме того, используя Select Case, вы можете пойти еще дальше и поместить все выражение в одну строку (до 1024 символов):
Sub Demo()
Dim State As String, Wd As String, HH As Long
HH = 10
Wd = "Do" '"Sat"
Select Case True: Case Wd = "Sat" Or Wd = "Sun": State = "Z": Case HH >= 16: State = "A": Case HH >= 13: State = "B": Case HH >= 5: State = "C": Case HH >= 4: State = "D": Case HH >= 0: State = "E": End Select
Debug.Print State
End Sub
Технически правильный, лучший вид правильного! Максимальная длина строки IIRC составляет 1024 символа — хорошая работа, показывающая больше альтернативных выражений! Хотя вертикальный код, возможно, легче читать и поддерживать, чем горизонтальный 😉
@MathieuGuindon, вы, конечно, правы насчет максимальной длины строки, у меня небольшой провал в памяти! Кроме того, я согласен с вами, что вертикальный код обычно легче читать. В некоторых случаях, когда условия и операторы короткие, код, подобный первому из моих примеров, может быть очень читаемым, имхо :)
Я хотел бы снова проголосовать за часть отступа. Слава!
Ах ха, отступ действительно проливает свет на то, что происходит. ElseIf связаны с внешним If True, а не с внутренним однострочным If WD. Так что да, они никогда ничего не сделают. Теперь интересно, если внешнее If False и изменить внутреннее If WD на и ElseIf ожидаемым образом. Не знаю, сделал бы я это таким образом, но могу попробовать, просто чтобы посмотреть, работает ли это.
Привет @NOYB, я только что добавил еще один вариант к своему ответу. Спасибо за ваш комментарий, ваша идея If False Then заставила меня осознать это.
Я имел в виду именно это. Нет ошибок. Оказывается, если этот блок кода находится внутри другого блока If, ошибки компиляции нет. Посмотрите, поместите ли его в блок If True Then... End If и посмотрите, не выдает ли он по-прежнему ошибку компиляции. Не то, чтобы это имело значение, так как не может этого сделать в любом случае. Думаю, я придерживаюсь того, что есть. С открывающим условием If Then и кодом в отдельных строках, а ElseIf — отдельными строками. Коротко и читабельно. Спасибо ребята. Не уверен, кому я должен дать ответ.