AndAlso/OrElse в VBA
Я пытаюсь получить ленивую оценку с помощью "И" в своем макросе Excel, выполнив следующее:
If Not myObject Is Nothing *And* myObject.test() Then
'do something'
Else
'do something else'
End If
Я знаю, что ленивая оценка существует в VB.NET как AndAlso
и OrElse
, но не может найти ничего подобного в VBA. Если в VBA нет ленивой оценки, какой лучший способ структурировать код так, чтобы он оценивал то, что я ожидаю?
Ответы
Ответ 1
Единственное короткое замыкание (сортировки) находится в оценке выражения Case
, поэтому следующее неудобное утверждение делает то, что, как я думаю, вы спрашиваете;
Select Case True
Case (myObject Is Nothing), Not myObject.test()
MsgBox "no instance or test == false"
Case Else
MsgBox "got instance & test == true"
End Select
End Sub
Ответ 2
Это старый вопрос, но этот вопрос все еще жив и здоров. Один обходной путь, который я использовал:
Dim success As Boolean ' False by default.
If myObj Is Nothing Then ' Object is nothing, success = False already, do nothing.
ElseIf Not myObj.test() Then ' Test failed, success = False already, do nothing.
Else: success = True ' Object is not nothing and test passed.
End If
If success Then
' Do stuff...
Else
' Do other stuff...
End If
Это в основном инвертирует логику в исходном вопросе, но вы получаете тот же результат. Я думаю, что это более чистое решение, чем другие, которые используют только выражения If
. Решение с использованием оператора Select
является умным, но если вы хотите использовать альтернативу только с инструкциями If
, я думаю, что это тот, который нужно использовать.
Ответ 3
Или вы можете создать функцию, которая берет ваш объект в качестве параметра и возвращает значение boolean для любого из этих случаев. Это то, к чему я обычно привык.
то есть.
if Proceed(objMyAwesomeObject) then
'do some really neat stuff here
else
'do something else, eh
end if
...
end sub
private function Proceed(objMyAwesomeObject as Object)
if not objMyAweseomeObject is nothing then
Proceed = true
elseif objMyAwesomeObject.SomeProperty = SomeValue then
Proceed = true
else
Proceed = false
endif
end function
Ответ 4
Поскольку следующий синтаксис работает
If myObject.test() Then do something
Затем синтаксис с одной линией может быть использован для короткого замыкания оценки. Ниже первый оператор If
гарантирует, что myObject
является чем-то. Иначе он даже не попытается оценить второй If
.
If Not myObject Is Nothing Then If myObject.test() Then
'do something'
Else
'do something else'
End If
Конечно, если вы хотите "сделать что-то еще", если myObject Is Nothing, то это может не сработать.
Ответ 5
If Not myObject Is Nothing Then
If myObject.test() Then
'do something'
End If
Else
'do something else'
End If
Я думаю, что вы должны это сделать.
Edit
Может быть, это
Dim bTestsFailed as Boolean
bTestsFailed = False
If Not myObject Is Nothing Then
If myObject.test() Then
'do something'
Else
bTestsFailed = True
End If
Else
bTestsFailed = True
End If
If bTestsFailed Then
'do something else
End If
Не большой VBA?
Ответ 6
Улучшение этого ответа на другой вопрос о той же основной проблеме, вот что я решил сделать:
dim conditionsValid as boolean
conditionsValid = myObject Is Nothing
if conditionsValid then conditionsValid = myObject.test()
if conditionsValid then conditionsValid = myObject.anotherTest()
if conditionsValid then
'do something'
else
'do something else'
end if
Я думаю, что этот код более понятен, чем другие предложенные ответы, и вам (обычно) не нужна отдельная переменная для каждой проверки, что является улучшением по сравнению с первоначальным ответом на другой вопрос. Кстати, каждое новое условие добавляет только одну строку кода.
Ответ 7
Трюк с отсутствующими значениями может помочь:
Dim passed, wrongMaxPercent, wrongPercent, rightMinPercent, rightPercent
wrongPercent = 33
rightPercent = 55
'rightMinPercent = 56
wrongMaxPercent = 40
passed = (Len(wrongMaxPercent) = 0 Or wrongPercent < wrongMaxPercent) And _
(Len(rightMinPercent) = 0 Or rightPercent >= rightMinPercent)