这是我的数据示例,其中name
位于单元格A1
中。 C列不是数据的一部分,只是为了说明需要的内容。
name cod should be detected?
aa no
aa 14;15 no
aa 1;13;7 yes
bb 8;9;1 yes
bb 1;17 yes
bb 11;21 no
cz 7;8 no
cz 7;21 no
cz 8;1;20 yes
db 1 yes
db 13;1 yes
我正在尝试编写一个宏来检测出现数字1的列cod
。例如,我不想找到10,13,21,但是1
。此列中填写的数字从1到21。
所有cod
值都是字符串,但我想找到1
的位置,即使它与字符串中的其他数字混合在一起。此列中的数字始终以;
分隔,中间没有空格。
以下代码将产生错误的肯定:
Dim N As Range
Dim msg As String
Sub cod1()
msg = ""
For Each N In Range("A2", Range("A2").End(xlDown))
If InStr(1, N.Offset(, 1), 1, vbTextCompare) > 0 Then
msg = msg & "Code 1 was not supposed to be in Cod column." & vbLf
Exit For
End If
Next N
If Len(msg) > 1 Then
MsgBox msg
Else: MsgBox "There are no code 1 values in Cod column."
End If
End Sub
见结果:
name cod should be detected? problem
aa no
aa 14;15 no false positive
aa 1;13;7 yes
bb 8;9;1 yes
bb 1;17 yes
bb 11;21 no false positive
cz 7;8 no
cz 7;21 no false positive
cz 8;1;20 yes
db 1 yes
db 13;1 yes
以下代码将产生错误的否定:
Dim N As Range
Dim msg As String
Sub cod2()
msg = ""
For Each N In Range("A2", Range("A2").End(xlDown))
If InStr(1, N.Offset(, 1), 1, vbTextCompare) > 0 And _
InStr(1, N.Offset(, 1), 10, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 11, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 12, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 13, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 14, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 15, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 16, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 17, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 18, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 19, vbTextCompare) = 0 And _
InStr(1, N.Offset(, 1), 21, vbTextCompare) = 0 Then
msg = msg & "Code 1 was not supposed to be in Cod column." & vbLf
Exit For
End If
Next N
If Len(msg) > 1 Then
MsgBox msg
Else: MsgBox "There are no code 1 values in Cod column."
End If
End Sub
见结果:
name cod should be detected? problem
aa no
aa 14;15 no
aa 1;13;7 yes false negative
bb 8;9;1 yes
bb 1;17 yes false negative
bb 11;21 no
cz 7;8;10 no
cz 7;21 no
cz 8;1;20 yes false negative
db 1 yes
db 13;1 yes false negative
那么,只有在字符串中检测到数字1
时,才能使消息框*出现?
*代码1不应该在Cod专栏中。
寻找适用于Excel 2007及更新版本的解决方案。 子>
答案 0 :(得分:2)
您可以使用Like
运算符查找字符:
Dim N As Range
Dim msg As String
Sub cod1()
Dim expression As String
msg = ""
For Each N In Range("A2", Range("A2").End(xlDown))
expression = ";" & N.Offset(, 1) & ";"
If expression Like "*;1;*" Then
msg = msg & "Code 1 was not supposed to be in Cod column." & vbLf
End If
Next N
If Len(msg) > 1 Then
MsgBox msg
Else
MsgBox "There are no code 1 values in Cod column."
End If
End Sub
答案 1 :(得分:1)
或者,您可以使用通用UDF(用户定义函数),使用任何分隔符检测单元格内是否存在任何值:
Public Function hasItem(ByVal r As Range, item As Variant, sep As String) As Boolean
ar = Split(r.Text, sep)
For Each x In ar
If Trim(CStr(x)) = Trim(CStr(item)) Then
hasItem = True
Exit Function
End If
Next
End Function
将上述UDF放在代码模块Module1
中,并在列C
的单元格中使用它,例如在C1
中:
=IF(hasItem(B1, 1, ";"), "yes", "no")
然后,您可以将其复制/粘贴到所有C
单元格中。
此外,您可以在任何VBA代码中方便地使用该功能来显示所需的消息。
答案 2 :(得分:1)
此解决方案使用Split
函数在列B
中生成值数组,然后比较每个数组项。
Sub Test()
Dim rDta As Range, rRow As Range
Dim aRow As Variant, vItm As Variant
Dim sMsg As String, lRow As Long
With ThisWorkbook.Sheets("DATA.3").Cells(1).CurrentRegion 'change as required
Set rDta = .Offset(1).Resize(-1 + .Rows.Count)
End With
lRow = 1
For Each rRow In rDta.Rows
lRow = 1 + lRow
aRow = Split(rRow.Cells(2).Value2, ";")
For Each vItm In aRow
If vItm = 1 Then
If sMsg = vbNullString Then sMsg = "Code 1 was not supposed to be in Cod column of rows:"
sMsg = sMsg & vbLf & vbTab & lRow
rRow.Cells(1, 3).Value = "Code 1 was not supposed to be in Cod column." 'Remove if required
End If: Next: Next
If sMsg = vbNullString Then sMsg = "There are no code 1 values in Cod column."
MsgBox sMsg
End Sub