VBA(如果使用InStr)

Dan*_*man -3 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
Run Code Online (Sandbox Code Playgroud)

arc*_*nct 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
Run Code Online (Sandbox Code Playgroud)

test evaluated as True!即使“ 12345”中包含“ 23”,也会打印此内容。这不是因为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)
Run Code Online (Sandbox Code Playgroud)

Wy为Not 2评价为-3?这是因为2之前未将转换为,Not而是将Not逐位应用于2,这意味着每一位都被翻转了。因此2(0010)变为1101-3,因为计算机使用二进制补码表示负数。(实际上,使用了更多的位,Integer但它的工作原理相同。)由于-3不为0,因此它将转换为True。由于Not 0还将被评估为True0000将被转换1111为-1作为二进制补码),因此表达式Not InStr(...)将始终被评估为True。

在使用布尔值时,不会注意到这种按位行为,因为它们在内部表示为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)
Run Code Online (Sandbox Code Playgroud)

如您在这里看到的,将True转换为Integer而不是将Integer转换为布尔值进行=比较。


长解释,短解决:使用If InStr(...) > 0 Then代替If InStr(...) ThenIf InStr(...) = 0 Then代替If Not InStr(...) Then


PS:如果将两个InStr测试结合使用,也会导致混乱的行为,And因为And也会按位应用。