VBA 中的 AndAlso/OrElse
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3242560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AndAlso/OrElse in VBA
提问by Luis
I'm trying to get a lazy evaluation with 'And' in my Excel macro by doing the following:
我正在尝试通过执行以下操作在我的 Excel 宏中使用“And”进行懒惰的评估:
If Not myObject Is Nothing *And* myObject.test() Then
'do something'
Else
'do something else'
End If
I know lazy evaluation exists in VB.NET as AndAlsoand OrElsebut cannot find anything similar in VBA. If lazy evaluation does not exist in VBA, what's the best way to structure the code so that it will evaluate the way I expect?
我知道 VB.NET 中存在惰性求值AndAlso,OrElse但在 VBA 中找不到类似的东西。如果 VBA 中不存在惰性求值,那么构建代码以使其按照我期望的方式求值的最佳方法是什么?
回答by Alex K.
The only short circuiting (of a sort) is within Caseexpression evaluation, so the following ungainly statement does what I think you're asking;
唯一的短路(某种)是在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
回答by neizan
This is an old question, but this issue is still alive and well. One workaround I've used:
这是一个老问题,但这个问题仍然存在并且很好。我使用过的一种解决方法:
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
This basically inverts the logic in the original question, but you get the same result. I think it's a cleaner solution than the others here that only use Ifstatements. The solution using a Selectstatement is clever, but if you want an alternative using only Ifstatements, I think this is the one to use.
这基本上颠倒了原始问题中的逻辑,但您会得到相同的结果。我认为这是一个比这里只使用If语句的其他解决方案更干净的解决方案。使用Select语句的解决方案很聪明,但是如果您想要仅使用If语句的替代方案,我认为这是可以使用的。
回答by William
Or you could create a function that takes your object as a parameter and returns boolean for either case. That's what I usually to.
或者您可以创建一个函数,该函数将您的对象作为参数并在任一情况下返回布尔值。这就是我通常要做的。
i.e.
IE
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
回答by Cohan
Since the following syntax works
由于以下语法有效
If myObject.test() Then do something
Then the one liner syntax could be used to short circuit the evaluation. Below, the first Ifstatement ensures that myObjectis something. Otherwise, it won't even try to evaluate the second If.
然后可以使用 one liner 语法来短路评估。下面,第一条If语句确保了这myObject一点。否则,它甚至不会尝试评估第二个If.
If Not myObject Is Nothing Then If myObject.test() Then
'do something'
Else
'do something else'
End If
Of course, if you want 'do something else' if myObject Is Nothing, then this may not work.
当然,如果您想在 myObject Is Nothing 的情况下“做其他事情”,那么这可能不起作用。
回答by carlossierra
Improving on this answerto a different question about the same basic problem, here is what I chose to do:
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
I think this code is clearer than the other answers that have been suggested, and you (usually) don't need a different variable for each validation, which is the improvement over the original answer to the other question. By the way, each new condition you need adds just one more line of code.
我认为此代码比建议的其他答案更清晰,并且您(通常)不需要每次验证都使用不同的变量,这是对其他问题的原始答案的改进。顺便说一下,您需要的每个新条件只增加一行代码。
回答by W. Nema
A trick around missing values may help:
绕过缺失值的技巧可能会有所帮助:
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)
回答by Dick Kusleika
If Not myObject Is Nothing Then
If myObject.test() Then
'do something'
End If
Else
'do something else'
End If
I think that's the way you have to do it.
我认为这就是你必须这样做的方式。
Edit
编辑
Maybe like this
也许像这样
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
Isn't VBA great?
VBA 不是很好吗?

