2011-08-10 36 views
40
Function Foo(thiscell As Range) As Boolean 
    Foo = thiscell.hasFormula And (InStr(1, UCase(Split(thiscell.formula, Chr(40))(0)), "bar") > 0) 
End Function 

该功能之前(当第一个参数为假时,VBA“和”运算符是否会评估第二个参数?

我在使用是麻烦时,传递到该函数的单元是空的壳体存在,以测试特定子串的存在(栏,在这种情况下) ,thisCell.hasFormula是错误的,但是在和之后的语句仍然被评估,这给我一个下标超出了运行时的范围错误

是否VBA实际上继续评估第二个参数和,首先是假的?

+3

请注意,VBA的'And'运算符不会短路,因为它是*位运算符而不是*逻辑*运算符。请参阅:http://stackoverflow.com/questions/8042744/excel-vba-instr-condition-doesnt-work-with-2-or-more-conditions/8047021#8047021 – jtolle

+3

@jtolle不正确 - 它将返回一个布尔值如果它的参数是布尔值,那么它支持按位和逻辑运算。 (当然,你可能会认为逻辑是一种使用1位整数的特殊情况,但重点是如果他们选择微软可能会支持短路) –

+0

@Hugh,有趣。我一直假设'And'只是一个按位运算符,尽管模拟逻辑运算是因为'True = -1'和'False = 0'。但是你是对的,如果传递给它的表达式都是布尔型的,则'*'是一个逻辑运算符。如果一个或两个操作数都是数字,它只是按位进行的。但我想它不能短路,因为无论如何都必须对两个表达式进行评估,以确保其中一个或两个不是数字而不是布尔值。所以我认为“比特级”仍然会导致这里没有短路。 – jtolle

回答

51

你在找什么叫做“短路评估“。

VBA没有它。

您可以看到一种可能适用于您的情况的方法here

在那里选择的方法涉及用Select Case代替If。还有一个使用嵌套的示例Ifs

+65

当我在工作时用VBA它开始感觉我想用蜡笔画出蒙娜丽莎。 – James

+1

确实。太糟糕了,你不能使用C#而是:( –

10

作为DOK mentioned:否,VBA没有短路评估。

使用2 If-then声明而不是使用AND运算符在技术上效率更高,但除非您多次执行此操作,否则您不会注意到节省,因此请选择更具可读性的内容。如果你想获得真正的技术,VBA也可以比Select Case更快地处理多个If-then语句。

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 + NullNullTrue And NullNull。 不过:

? False And Null
False

这看起来像短路行为 - 这是怎么回事?当联合(And)的另一个参数是False0时,Null不会传播 - 结果仅为False0。它是左或右参数无关紧要。如果析取的另一个参数(Or)为True或非零整数(浮点值将使用this rule四舍五入为整数),则情况也是如此。

因此,在AndOr的参数中不能防止副作用和错误,但Null传播可以“短路”。这种行为似乎是从SQL继承。

+0

嗯,我迷路了,你可以添加一个例子说明它是如何工作的条件'A和B' – Enissay

+0

@ Enissay我的例子中有两个使用'And'。你可以更好地解释一下你感到困惑吗? –

+0

这与短路行为无关,两个表达式被评估,第一个返回False,第二个返回True,这里没有短路,然后VBA做了一些奇怪的投射并且不一致地返回了'假'或'空' – stenci

-1

考虑必须运行的机器代码。 最快的应该是沿着类似的代码混合的线...

如果SFSF然后转到SkipAB

如果FDF然后转到goneBad

如果dffdefedwf然后转到MustHave

SkipAB: 如果DSDA> 4然后MustHave

GoneBad: 退出功能

MustHave: THISIS =真

'不仅节省了片刻,当程序有通过它 数千次运行...如文件搜索大驱动 或当一个简单的布尔测试用于跳过一个耗时函数 比如寻找所有的片材和名称在一个封闭的工作表 [代码]

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

SkipExt: 如果不wFF.UsingFileNameMatch然后转到SkipFileMatch 如果不wFF.OKFileNameMatch然后转到BADFILE SkipFileMatch: 如果不wFF.UsingDaysAgo然后转到SkipDaysAgo 如果不wFF.OKDaysAgo然后转到BADFILE SkipDaysAgo:

[/代码]

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 

因此,只有当条件i满员时,您才会通过条件。

+0

5年前,OP询问条件语句中的“和”关键字是否“短路”,如果第一个条件是错误的,您是否回答了这个问题? – ppovoski

+0

@ppovoski yep我真的是 – Moreno

相关问题