我有一列超过 500 行的数字。我需要使用 VBA 来检查变量 X 是否与列中的任何值匹配。
有人可以帮帮我吗?
范围的查找方法比使用 for 循环手动遍历所有单元格要快。
这是在 vba 中使用 find 方法的示例
Sub Find_First()
Dim FindString As String
Dim Rng As Range
FindString = InputBox("Enter a Search value")
If Trim(FindString) <> "" Then
With Sheets("Sheet1").Range("A:A") 'searches all of column A
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Application.Goto Rng, True 'value found
Else
MsgBox "Nothing found" 'value not found
End If
End With
End If
End Sub
最简单的就是使用Match
If Not IsError(Application.Match(ValueToSearchFor, RangeToSearchIn, 0)) Then
' String is in range
如果您想在没有VBA 的情况下执行此操作,您可以使用IF
、ISERROR
和MATCH
.
因此,如果所有值都在 A 列中,请在 B 列中输入此公式:
=IF(ISERROR(MATCH(12345,A:A,0)),"Not Found","Value found on row " & MATCH(12345,A:A,0))
这将查找值“12345”(也可以是单元格引用)。如果未找到该值,则MATCH
返回“#N/A”并ISERROR
尝试捕捉它。
如果要使用 VBA,最快的方法是使用 FOR 循环:
Sub FindMatchingValue()
Dim i as Integer, intValueToFind as integer
intValueToFind = 12345
For i = 1 to 500 ' Revise the 500 to include all of your values
If Cells(i,1).Value = intValueToFind then
MsgBox("Found value on row " & i)
Exit Sub
End If
Next i
' This MsgBox will only show if the loop completes with no success
MsgBox("Value not found in the range!")
End Sub
您可以在 VBA 中使用工作表函数,但它们很挑剔,有时会引发无意义的错误。FOR
循环非常简单。
试试这个:
If Application.WorksheetFunction.CountIf(RangeToSearchIn, ValueToSearchFor) = 0 Then
Debug.Print "none"
End If
只是为了修改斯科特的答案以使其成为一个函数:
Function FindFirstInRange(FindString As String, RngIn As Range, Optional UseCase As Boolean = True, Optional UseWhole As Boolean = True) As Variant
Dim LookAtWhat As Integer
If UseWhole Then LookAtWhat = xlWhole Else LookAtWhat = xlPart
With RngIn
Set FindFirstInRange = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=LookAtWhat, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=UseCase)
If FindFirstInRange Is Nothing Then FindFirstInRange = False
End With
End Function
如果未找到该值,则返回 FALSE,如果找到,则返回范围。
您可以选择告诉它区分大小写和/或允许部分单词匹配。
我拿出了 TRIM,因为如果你愿意,你可以事先添加它。
一个例子:
MsgBox FindFirstInRange(StringToFind, Range("2:2"), TRUE, FALSE).Address
这会在第二行进行区分大小写的部分单词搜索,并显示一个带有地址的框。以下是相同的搜索,但不区分大小写的全词搜索:
MsgBox FindFirstInRange(StringToFind, Range("2:2")).Address
您可以根据自己的喜好轻松调整此功能,或将其从 Variant 更改为布尔值或其他任何值,以加快速度。
请注意,VBA 的 Find 有时比暴力循环或 Match 等其他方法慢,所以不要仅仅因为它是 VBA 的原生方法就认为它是最快的。它更加复杂和灵活,这也可能使其并不总是那么高效。它有一些有趣的怪癖需要注意,比如“Object variable or with block variable not set”错误。
修复了@JeffC 在来自@sdanse 的函数中提到的问题:
Function FindFirstInRange(FindString As String, RngIn As Range, Optional UseCase As Boolean = True, Optional UseWhole As Boolean = True) As Variant
Dim LookAtWhat As Integer
If UseWhole Then LookAtWhat = xlWhole Else LookAtWhat = xlPart
With RngIn
Set FindFirstInRange = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=LookAtWhat, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=UseCase)
If FindFirstInRange Is Nothing Then
FindFirstInRange = False
Exit Function
End If
If IsEmpty(FindFirstInRange) Then
FindFirstInRange = False
Else
FindFirstInRange = True
End If
End With
End Function
尝试添加 WorksheetFunction:
If Not IsError(Application.WorksheetFunction.Match(ValueToSearchFor, RangeToSearchIn, 0)) Then
' String is in range
=IF(COUNTIF($C$2:$C$500,A2)>0,"Exist","Not Exists")