如果使用InStr,VBA

时间:2016-10-06 07:09:22

标签: excel vba excel-vba

如果我收到错误,我试图写一个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

1 个答案:

答案 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也将被评估为True0000将转换为1111,其为-1作为二进制补码),将始终对表达式Not InStr(...)进行求值是的。

在使用布尔值时,不会注意到这种逐位行为,因为它们在内部表示为00001111。这也很明显:

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(...) ThenIf InStr(...) = 0 Then代替If Not InStr(...) Then

PS:如果您将两个InStr测试与And结合使用,这也会导致令人困惑的行为,因为And也将按位应用。