如果我收到错误,我试图写一个VBA代码。
我希望代码检查其中一个值(" S925,S936,S926,G")是否不在单元格10上。
Sub checklist()
Dim x
Dim LineType
NumRows = Cells(Rows.Count, "j").End(xlUp).Row
For x = 2 To NumRows
If LineType = "G" Then
If Not InStr("S925,S936,S926,G", cellsCells(x, 10).Value) Then
cells Cells(x, 52).Interior.Color = rgbCrimson
cells Cells(x, 52).Value = "G"
End If
End If
End If
Next x
End Sub
答案 0 :(得分:5)
这不会导致错误,但会导致程序出现问题,所以我会解释一下。
InStr
不返回布尔值,而是返回搜索字符串第一次出现的索引。如果找不到该字符串,则返回0。
例如,InStr("12345", "23")
将返回2.
因为除了0之外的所有内容都被投射为True
,所以类似If Instr(....) Then
的内容将按预期执行。
但是,如果您使用If Not InStr(....) Then
其他可以/将要发生的事情
If Not InStr("12345", "23") Then
Debug.Print "test evaluated as True!"
End If
即使“12345”中包含“23”,也会打印test evaluated as True!
。这不是因为InStr
返回了False
。我们可以将InStr
表达式替换为2来更好地理解:
Debug.Print 2 '2 (duh)
Debug.Print CBool(2) 'True (2 converted to Boolean)
Debug.Print Not 2 '-3
Debug.Print CBool(Not 2) 'True (-2 converted to Boolean)
Wy被Not 2
评为-3?这是因为2
在应用Not
之前未转换为布尔值,但Not
按比特应用于2
,这意味着每个位都被翻转。因此,2(0010
)变为1101
,这是-3,因为计算机使用two's complement来表示负数。 (实际上Integer
使用了更多的位,但它的工作原理相同。)由于-3不是0,它将被转换为True
。由于Not 0
也将被评估为True
(0000
将转换为1111
,其为-1作为二进制补码),将始终对表达式Not InStr(...)
进行求值是的。
在使用布尔值时,不会注意到这种逐位行为,因为它们在内部表示为0000
和1111
。这也很明显:
Debug.Print 1 = True 'False
Debug.Print CBool(1) = True 'True
Debug.Print -1 = True 'True
Debug.Print CBool(-1) = True'True
Debug.Print CInt(True) '-1 (True converted to Integer)
正如您在此处所见,True
转换为整数而不是整数转换为布尔进行=
比较。
详尽解释,简短修复:使用If InStr(...) > 0 Then
代替If InStr(...) Then
和If InStr(...) = 0 Then
代替If Not InStr(...) Then
。
PS:如果您将两个InStr
测试与And
结合使用,这也会导致令人困惑的行为,因为And
也将按位应用。