"если не instr" не работает, как я думал, это должно быть в VBA
У меня есть лист со списком контрактов со столбцом для имени поставщика и один для даты окончания, я хочу сделать все пройденные даты красными, если контракт не от конкретного поставщика. Я ранее использовал InStr
чтобы проверить, есть ли в ячейке строка внутри, так как я только начал с VBA, я подумал о вставке следующего в мой цикл
If Not InStr(LCase(Data.Cells(i, 4).Value), "flowserve") Then
If CDate(Data.Cells(i, "h").Value) < Date Then _
Data.Cells(i, "h").Font.Color = -16776961
End If
ожидая, что это будет окрашивать прошедшие даты контрактов, которые не имеют "flowserve" в названии поставщика. Но вместо этого кажется, что все прошедшие даты окрашены, как будто InStr
не нашел ничего нигде.
Я тогда пытался сделать
If InStr(LCase(Data.Cells(i, 4).Value), "flowserve") Then
'do nothing
Else
If CDate(Data.Cells(i, "h").Value) < Date Then _
Data.Cells(i, "h").Font.Color = -16776961
End If
и это работает, как я хотел, так что я предполагаю, что Not
не работает, как я думал.
Теперь, даже если бы у меня было какое-то решение, я надеялся, что кто-нибудь сможет объяснить, что пошло не так в первом коде. Надеюсь, я был достаточно ясен.
всем заранее спасибо!
4 ответа
https://msdn.microsoft.com/en-us/library/8460tsh1%28v=vs.90%29.aspx
InStr возвращает значение не булево, попробуйте сравнить его со значением, которое оно возвращает.
If InStr(LCase(Data.Cells(i, 4).Value), "flowserve") = 0 Then
If CDate(Data.Cells(i, "h").Value) < Date Then _
Data.Cells(i, "h").Font.Color = -16776961
End If
Вы должны быть очень осторожны, используя Not
с Integer
значение. Смотрите следующие примеры:
Sub InStrTest()
Dim DataCellsTrue As String
Dim DataCellsFalse As String
DataCellsTrue = "flowserve"
DataCellsFalse = "haha"
Debug.Print InStr(LCase(DataCellsTrue), "flowserve") 'return 1
Debug.Print Not InStr(LCase(DataCellsTrue), "flowserve") 'return -2
Debug.Print CBool(InStr(LCase(DataCellsTrue), "flowserve")) 'return true
Debug.Print Not CBool(InStr(LCase(DataCellsTrue), "flowserve")) 'return false
Debug.Print InStr(LCase(DataCellsFalse), "flowserve") 'return 0
Debug.Print Not InStr(LCase(DataCellsFalse), "flowserve") 'return -1
Debug.Print CBool(InStr(LCase(DataCellsFalse), "flowserve")) 'return false
Debug.Print Not CBool(InStr(LCase(DataCellsFalse), "flowserve")) 'return true
End Sub
Не используйте логическое преобразование... вместо этого:
If InStr(LCase(Data.Cells(i, 4).Value), "flowserve") = 0 Then
Почему бы не создать свою собственную функцию, которая работает так, как вы ожидаете?
Public Function Contains(ByVal toSearch As String, ByVal toFind As String) As Boolean
Contains = (Instr(toSearch, toFind) <> 0)
End Function
Тогда вы могли бы сказать,
If Not Contains(LCase(Data.Cells(i, 4).Value), "flowserve") Then
If CDate(Data.Cells(i, "h").Value) < Date Then _
Data.Cells(i, "h").Font.Color = -16776961
End If
и это работает именно так, как вы хотели.
Также обратите внимание, что вам не нужно LCase
что-нибудь. Используйте опцию сравнения текста Instr
вместо.
Public Function Contains(ByVal toSearch As String, ByVal toFind As String) As Boolean
Contains = (Instr(1, toSearch, toFind, vbTextCompare) <> 0)
End Function
If Not Contains(Data.Cells(i, 4).Value, "flowserve") Then
If CDate(Data.Cells(i, "h").Value) < Date Then _
Data.Cells(i, "h").Font.Color = -16776961
End If