Подтвердить что ты не робот

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 нет ленивой оценки, какой лучший способ структурировать код так, чтобы он оценивал то, что я ожидаю?

4b9b3361

Ответ 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)