检查VBA中的列中是否存在值

时间:2012-09-28 14:40:30

标签: excel vba matching

我有一列超过500行的数字。我需要使用VBA来检查变量X是否与列中的任何值匹配。

有人可以帮帮我吗?

7 个答案:

答案 0 :(得分:45)

范围的查找方法比使用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

答案 1 :(得分:30)

最简单的方法是使用Match

If Not IsError(Application.Match(ValueToSearchFor, RangeToSearchIn, 0)) Then
    ' String is in range

答案 2 :(得分:21)

如果您想在不使用 VBA的情况下执行,则可以使用IFISERRORMATCH的组合。

因此,如果所有值都在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循环非常简单。

答案 3 :(得分:0)

尝试一下:

If Application.WorksheetFunction.CountIf(RangeToSearchIn, ValueToSearchFor) = 0 Then
Debug.Print "none"
End If

答案 4 :(得分:0)

只需修改scott的答案即可使其起作用:

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更改为boolean或其他,以加快速度。

请注意,VBA的“查找”有时比诸如暴力循环或“匹配”之类的其他方法要慢,因此请不要仅仅因为它是VBA固有的就认为它是最快的。它更加复杂和灵活,这也可能使其效率不总是那么高。它有一些有趣的怪异之处,例如“对象变量或未设置块变量” error

答案 5 :(得分:0)

修正@sdanse函数中@JeffC提到的问题:

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

答案 6 :(得分:-1)

尝试添加WorksheetFunction:

If Not IsError(Application.WorksheetFunction.Match(ValueToSearchFor, RangeToSearchIn, 0)) Then
' String is in range