试图减少代码的长度,以至于减少了查看和调试的麻烦,我一直在愚弄,我偶然发现了这个奇怪的事实:
Debug.Print 5<9<8 'returns "True"
起初我以为这是因为它只检查了第一组,但后来我找到了
Debug.Print 5<4<8 '*also* returns "True"
VBA是否将这种三重不等式解释为Or
语句?我无法想象为什么有人会选择做出VBA所做的解释,因为它几乎肯定是较少使用的选项,但我很难想到另一种解释。
此外,编写If 5 < X < 8 Then
(使用样本编号)的快速而漂亮的方法是什么,而不必诉诸无尽的And
语句,即If 5 < x And X < 8 Then
?一个语句没问题,但长度加倍会加快,特别是因为变量通常不是X
。
编辑:好吧,它当然不是Or
,因为VBA还说Debug.Print 8<6<2
是True
。究竟是什么思考?
答案 0 :(得分:4)
我没有任何线索,但我的教育猜测是,它首先评估等式左边(5 <9),得到真。然后,它继续评估其余部分(TRUE&lt; 8)并隐式地将TRUE转换为其整数值(我相信这在VB中为-1)。
-1&lt; 8 - &gt; TRUE
同样适用于第二种情况,因为FALSE将转换为0和0 <8。
基本上它与将布尔值隐式转换为整数以及它们在VBA中的相应值有关。
答案 1 :(得分:3)
它与VBA评估表达式和隐式转换的方式有关。计算等式的第一部分,并将结果存储为数值(布尔值隐式转换为整数)
(嗯......从技术上讲,布尔 只是一个整数,但我们只是这样......)
'// True = -1
'// False = 0
Debug.Print 5 < 9 < 8
Debug.Print CInt(5 < 9) '// Prints -1
Debug.Print -1 < 8 '// = True
这就是为什么以下给出&#34; False&#34;代替:
Debug.Print 5 < 9 < -1
由于
Debug.Print Cint(5 < 9) '// True = -1
Debug.Print -1 < -1 '// False
如果你想知道某些东西是否在另外两个数字的中间,那么你必须使用And
运算符来强制进行单独的评估(然后评估运算符的任一侧并进行逻辑比较)< / p>
Debug.Print (3 < 5 And 5 < 4) '// False
答案 2 :(得分:3)
从解析树的角度来看,它可以为为什么以这种方式工作提供更多的启示。
排除THEN
令牌之后的任何指令,If 5 < X < 8 Then
的解析树可能看起来像这样(非常简化):
比较运算符是二元运算符,其两侧都有表达式,并且为了解析{{}的布尔表达式1}},VBA需要按特定的顺序访问树节点:因为VBA从左到右解析表达式,IfBlockStatement
部分独立地作为表达式,然后该表达式的结果用于解析表达式的5 < X
部分。
因此,当VBA解析{expression} < 8
时,因为它是5 < X
,结果是ComparisonExpression
值;当需要将该布尔值与Boolean
整数文字进行比较时,VBA会执行隐式类型转换并实际比较8
,无论第一个结果是什么,它都将评估为CInt({Boolean}) < 8
表达式,因为True
转换为False
而0
在表示为整数字面时转换为True
,并且都是-1
。
这些机制内置于运行时的工作方式,因此为了评估< 8
和X
之间是否5
,您需要构建表达式,以便它能够在8
和If X > 5 And X < 8 Then
之间运行。解析如下:
LogicalAndOperator
它为您提供了两个不同的表达式树,它们由{{1}}连接,然后在两边都有效的布尔表达式。
答案 3 :(得分:0)
5&lt; 9&lt; 8 = True&lt; 8 = True
5&lt; 4&lt; 8 = False&lt; 8 = True
答案 4 :(得分:0)
其他答案很好地掩盖了问题的第一部分,但未令人满意地掩盖了问题的第二部分,即 If 5 < X < 8 Then
的一种快速而美观的书写方式是什么(使用样本编号),而不必诉诸于无尽的And语句,即If 5 < x And X < 8 Then
?
有两种方法。第一个:
Select Case X
Case 5 To 8
...
End Select
在此,关键字To
之前的值必须是两者中较小的值。还要注意,尽管这将适用于整数,但我不知道它是否适用于Double
之类的类型(我怀疑不会)。
第二种方法,不管区间边界是否为整数,都可以工作,但不一定会更短,但是它可以通过一次比较来评估事物:
If Sgn(x - 5) + Sgn(x - 8) = 0 Then ...
这是一种评估值是否在某些范围之间的有趣方法,因为它还可以提供有关该值是否等于这些范围之一或“超出”范围(以及位于哪个“范围”)的信息。 )。例如,在-∞..0..+∞
轴上:
当然,如果要在区间中包括边界,例如测试If 5 <= x And X <= 8 Then
,则上面的比较将变为If Abs(Sgn(x - 5) + Sgn(x - 8)) < 2 Then ...
,这是检查表达式是否为-1,0的另一种快捷方式或1。
最后,以上方法都不比Between(x, 5, 8)
假设函数短,但至少它们是“经典”方法的替代方法。