Оценивает ли оператор VBA «И» второй аргумент, если первый является ложным?

39
Function Foo(thiscell As Range) As Boolean
  Foo = thiscell.hasFormula And (InStr(1, UCase(Split(thiscell.formula, Chr(40))(0)), "bar") > 0)
End Function

Эта функция существует для проверки наличия определенной подстроки (bar в этом случае) до (.

Случай, с которым у меня возникают проблемы, - это когда ячейка, переданная в функцию, пуста, thisCell.hasFormula является ложной, но оператор после и все еще оценивается. Это дает мне индекс ошибок вне диапазона во время выполнения.

Действительно ли VBA продолжает оценивать второй аргумент для И, даже если первый был ложным?

  • 3
    Обратите внимание, что оператор And VBA не замыкает накоротко, потому что это побитовый оператор, а не логический . См .: stackoverflow.com/questions/8042744/…
  • 3
    @jtolle не true - он будет возвращать логическое значение, если его аргументы логические, поэтому он поддерживает как побитовую, так и логическую операцию. (конечно, вы могли бы утверждать, что логический - это особый случай побитового использования 1-битных целых чисел, но дело в том, что Microsoft могла бы поддерживать короткое замыкание, если они этого захотят)
Показать ещё 3 комментария
Теги:
excel
operators

6 ответов

46
Лучший ответ

То, что вы ищете, называется " оценка короткого замыкания".

У VBA этого нет.

Вы можете увидеть подход, который, вероятно, адаптируется к вашей ситуации здесь.

Подход, выбранный там, заключался в замене a Select Case на If. Существует также пример использования вложенных Ifs.

  • 69
    Когда я работаю с VBA, мне начинает казаться, что я пытаюсь нарисовать Мона Лизу мелками.
  • 1
    В самом деле. Жаль, что вы не можете использовать C # вместо этого :(
10

Как DOK, упомянутый: Нет, VBA не имеет оценки короткого замыкания.

Технически более эффективно использовать операторы 2 If-then вместо использования оператора AND, но если вы этого не делаете много раз, вы не заметите сбережений, поэтому идите на то, что более читаемо. И если вы хотите получить действительно технический, VBA обрабатывает несколько операторов If-then быстрее, чем Select Case.

VBA причудлива:)

2

Ответ: да, VBA не проводит оценку короткого замыкания.

Это не просто вопрос стиля; это имеет большое значение в такой ситуации:

If i <= UBound(Arr, 1) And j <= UBound(Arr, 2) And Arr(i, 1) <= UBound(Arr2, 1) Then
    Arr2(Arr(i, 1), j) = Arr(i, j)
End If

... что неверно. Более целесообразно:

If i <= UBound(Arr, 1) And j <= UBound(Arr, 2) Then
    If Arr(i, 1) <= UBound(Arr2, 1) Then
        Arr2(Arr(i, 1), j) = Arr(i, j)
    End If
End If

Или, если у вас есть отвращение к вложенным ifs:

If i > UBound(Arr, 1) Or j > UBound(Arr, 2) Then
    ' Do Nothing
ElseIf Arr(i, 1) > UBound(Arr2, 1) Then
    ' Do Nothing
Else
    Arr2(Arr(i, 1), j) = Arr(i, j)
End If
1

У VBA есть одно поведение, подобное короткому замыканию. Обычно Null распространяется через выражения, например. 3 + Null - Null, а True And Null - Null. Однако:

? False And Null
False

Это похоже на поведение короткого замыкания - что происходит? Null не распространяется, когда другой аргумент конъюнкции (And) равен False или 0 - результат равен всего False или 0. Неважно, если это левый или правый аргумент. То же самое относится, если другим аргументом для дизъюнкции (Or) является True или ненулевое целое число (значение с плавающей запятой округляется до целого с помощью это правило).

Таким образом, побочные эффекты и ошибки не могут быть предотвращены в аргументах And и Or, но Null распространение может быть "закорочено". Это поведение кажется унаследованным от SQL.

  • 0
    Хм, я заблудился, не могли бы вы добавить пример того, как это работает для условия A And B
  • 0
    @Enissay два из моих примеров использования And . Возможно, вы могли бы лучше объяснить, что вас смущает?
Показать ещё 1 комментарий
0

Я думаю, что это лучшая практика:

sub my conditions()
        If Condition1=constraint1 then
         if Condition2=constraint2 then
          if condition3=constraint3 then
           ...
            ....
        end if
         end if
          end if
    else
      end if
           ....
    end if
end sub

Таким образом, вы будете проходить только через условия тогда и только тогда, когда условие я заполнено.

  • 0
    Более 5 лет назад ОП спрашивал, является ли ключевое слово and в условном выражении «короткозамкнутым», если первое условие было ложным. Вы отвечаете на этот вопрос?
  • 0
    @ppovoski да я действительно
0

Рассмотрим машинный код, который должен быть запущен. Самый быстрый должен быть по линии сочетания кода вроде...

если sfsf, а затем перейти SkipAB

если fdf затем перешел в

если dffdefedwf, а затем goto MustHave

SkipAB:  если dsda > 4, то MustHave

GoneBad: функция выхода

Musthave: ThisIS = true

'сохраняет только несколько моментов, когда программа должна запускать его много тысяч раз... например, поиск файлов на большом диске или когда простой булевский тест используется, чтобы пропустить функцию времени как найти все листы и имена в закрытом листе [Код]

     If Not wFF.UsingFileExtMatch Then GoTo SkipExt
                If Not wFF.OKFileEXTMatch Then GoTo BADFile

SkipExt:                   Если не wFF.UsingFileNameMatch, то GoTo SkipFileMatch                   Если не wFF.OKFileNameMatch Then GoTo BADFile SkipFileMatch:                   Если не wFF.UsingDaysAgo, то GoTo SkipDaysAgo                   Если не wFF.OKDaysAgo, то GoTo BADFile SkipDaysAgo:

[/код]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню