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

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 имеет значение false, но утверждение после и все еще оценивается. Это дает мне ошибку индексации вне диапазона во время выполнения.

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

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

У VBA этого нет.

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

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

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

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

VBA причудливый 🙂

Ответ – да, 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 

Или если у вас есть отrotation к вложенным 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 

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

? False And Null
False

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

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

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

 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 

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

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

если sfsf, то перейти SkipAB

если fdf, то goto goneBad

если 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, то GoTo BADFile SkipFileMatch: если не wFF.UsingDaysAgo, то GoTo SkipDaysAgo Если нет wFF.OKDaysAgo, тогда GoTo BADFile SkipDaysAgo:

[/код]

  • Что означает $ mean / do в Haskell?
  • Оператор «&&» и «и» в C
  • Почему sizeof считается оператором?
  • Что делает знак вопроса и точечный оператор?. означает в C # 6.0?
  • Что делает «: =» делать?
  • Каковы операторы Pointer-to-Member -> * и. * В C ++?
  • В чем разница между оператором dot (.) И -> в C ++?
  • Оператор копирования и оператор присваивания
  • Оператор массива C ++ с несколькими аргументами?
  • Является ли регистр C # нечувствительным к оператору?
  • Что такое x после «x = x ++»?
  • Давайте будем гением компьютера.