答案 0 :(得分:5)
1
不是True
的整数表示,-1
是
Debug.Print CInt(True) 'prints -1
Debug.Print CInt(False) 'prints 0
布尔运算符(Not
,And
,Or
,XOr
)在其操作数为布尔值时表现为“逻辑运算符”。如果不是,则它们表现为“按位运算符”,但事实是,它们总是按位运算。
整数值1
转换为布尔值True
的原因仅在于True
被定义为Not False
,这意味着 any 非零值是布尔值True
。但是,当您将-1
用于True
时,只有正确/预期的逻辑行为。
Integer
用16位表示,所以1
是这样的:
0000 0000 0000 0001
这使得Not 1
如此:
1111 1111 1111 1110
符号位为开,因此该值为负-修剪无关紧要的数字,您将得到:
10
哪个是2
的二进制表示形式。因此,Not 1
是-2
。
相反,-1
为:
1111 1111 1111 1111
Not -1
因此:
0000 0000 0000 0000
答案 1 :(得分:3)
VBA / VBScript没有真正的逻辑运算符(AND,OR,NOT)。您看到的逻辑运算符实际上是按位运算符,仅此而已。 VBA玩一些带有True
和False
值的游戏,因此在大多数情况下都可以使用,但是有时您会发现“陷阱”。
在这种情况下,您不必写If Not InStr() Then
来代替If InStr() <= 0 Then
。
您不必写If InStr() Then
If InStr() > 0 Then
换句话说:InStr()
返回一个数字。不要试图将其视为布尔值。
答案 2 :(得分:2)
其他答案已经解释了为什么,因此,我想重点介绍编码实践。
您发现,Not x
不一定是您想要的。实际上,您希望更像Not CBool(x)
。但是,CBool()
可能会引发错误-例如,CBool(Null)
会产生错误91(无效使用null)。
可以声称可以通过强变量化变量来避免这种情况,但是即使不使用Variant
也不保证在表达式中Boolean
将保留Boolean
。示例:
?typename(true and 0)
Integer
在实践中,意外地让VBA为您执行伏都教隐式转换太容易了,因此出于这个原因,改变编码习惯可能更适合您。
要测试真实值,您需要像这样的表达式:
If x Then
对于虚假值,您需要像这样的表达式:
If x = False Then
无论x
的类型如何,无论它们是否是表达式,它们都可以工作,因此,与If x = True Then
或{{1}相比,其行为更加一致/可预测。 }。通过采用这种代码习惯,可以帮助避免因意外转换而远离If Not x Then
类型并产生按位运算而不是逻辑运算而引起的细微错误。
对于赋值,使用Boolean
变量可以确保始终一致地将其强制转换为Boolean
或True
而不是某些随机数。