41

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

有人可以帮帮我吗?

4

8 回答 8

58

范围的查找方法比使用 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
于 2012-09-28T15:37:49.933 回答
38

最简单的就是使用Match

If Not IsError(Application.Match(ValueToSearchFor, RangeToSearchIn, 0)) Then
    ' String is in range
于 2012-09-28T23:25:11.843 回答
24

如果您想在没有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循环非常简单。

于 2012-09-28T14:52:54.703 回答
5

试试这个:

If Application.WorksheetFunction.CountIf(RangeToSearchIn, ValueToSearchFor) = 0 Then
Debug.Print "none"
End If
于 2019-02-18T11:18:16.713 回答
1

只是为了修改斯科特的答案以使其成为一个函数:

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”错误

于 2019-11-18T17:00:51.010 回答
0

修复了@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
于 2021-05-27T14:11:05.117 回答
-1

尝试添加 WorksheetFunction:

If Not IsError(Application.WorksheetFunction.Match(ValueToSearchFor, RangeToSearchIn, 0)) Then
' String is in range
于 2018-05-02T22:19:37.253 回答
-1
=IF(COUNTIF($C$2:$C$500,A2)>0,"Exist","Not Exists")
于 2021-09-27T06:41:20.120 回答