在字符串中查找特定数字?
Finding specific number inside a string?
这是我的数据样本,其中 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
我正在尝试编写一个宏来检测 cod
列中出现数字 1 的位置。比如我不想找10、13、21,而是1
。此栏中填写的数字从 1 到 21。
所有 cod
值都是字符串,但我想找到 1
的位置,即使它与字符串中的其他数字混合出现。此列中的数字始终用 ;
分隔,中间没有空格。
下面的代码会产生假 positives:
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
下面的代码会产生错误的negatives:
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
时出现?
*Code 1 was not supposed to be in Cod column.
寻找适用于 Excel 2007 和更新版本的解决方案。
您可以使用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
或者,您可以使用通用 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")
然后您可以 copy/paste 它在所有 C
个单元格中。
此外,您可以在任何 VBA 代码中方便地使用该功能来显示您想要的消息。
此解决方案使用 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
这是我的数据样本,其中 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
我正在尝试编写一个宏来检测 cod
列中出现数字 1 的位置。比如我不想找10、13、21,而是1
。此栏中填写的数字从 1 到 21。
所有 cod
值都是字符串,但我想找到 1
的位置,即使它与字符串中的其他数字混合出现。此列中的数字始终用 ;
分隔,中间没有空格。
下面的代码会产生假 positives:
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
下面的代码会产生错误的negatives:
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
时出现?
*Code 1 was not supposed to be in Cod column.
寻找适用于 Excel 2007 和更新版本的解决方案。
您可以使用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
或者,您可以使用通用 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")
然后您可以 copy/paste 它在所有 C
个单元格中。
此外,您可以在任何 VBA 代码中方便地使用该功能来显示您想要的消息。
此解决方案使用 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