Может ли за одной строкой VBA If Then следовать одна строка ElseIf Then?

Попытка следовать одной строке 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

Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
1
0
94
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Нет. Встроенный синтаксис предназначен для коротких условий и быстрых 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

Я имел в виду именно это. Нет ошибок. Оказывается, если этот блок кода находится внутри другого блока If, ошибки компиляции нет. Посмотрите, поместите ли его в блок If True Then... End If и посмотрите, не выдает ли он по-прежнему ошибку компиляции. Не то, чтобы это имело значение, так как не может этого сделать в любом случае. Думаю, я придерживаюсь того, что есть. С открывающим условием If Then и кодом в отдельных строках, а ElseIf — отдельными строками. Коротко и читабельно. Спасибо ребята. Не уверен, кому я должен дать ответ.

NOYB 12.01.2023 07:52

Привет @NOYB, пожалуйста, посмотри на мой отредактированный ответ, я думаю, он должен прояснить отношение к твоему первому фрагменту кода.

GWD 12.01.2023 16:55
Ответ принят как подходящий

Синтаксис оператора VBA If

Хотя ответ Матье технически правильный - это невозможно с операторами 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

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 символа — хорошая работа, показывающая больше альтернативных выражений! Хотя вертикальный код, возможно, легче читать и поддерживать, чем горизонтальный 😉

Mathieu Guindon 11.01.2023 16:45

@MathieuGuindon, вы, конечно, правы насчет максимальной длины строки, у меня небольшой провал в памяти! Кроме того, я согласен с вами, что вертикальный код обычно легче читать. В некоторых случаях, когда условия и операторы короткие, код, подобный первому из моих примеров, может быть очень читаемым, имхо :)

GWD 11.01.2023 16:53

Я хотел бы снова проголосовать за часть отступа. Слава!

Mathieu Guindon 12.01.2023 17:00

Ах ха, отступ действительно проливает свет на то, что происходит. ElseIf связаны с внешним If True, а не с внутренним однострочным If WD. Так что да, они никогда ничего не сделают. Теперь интересно, если внешнее If False и изменить внутреннее If WD на и ElseIf ожидаемым образом. Не знаю, сделал бы я это таким образом, но могу попробовать, просто чтобы посмотреть, работает ли это.

NOYB 13.01.2023 13:00

Привет @NOYB, я только что добавил еще один вариант к своему ответу. Спасибо за ваш комментарий, ваша идея If False Then заставила меня осознать это.

GWD 13.01.2023 13:06

Другие вопросы по теме