【问题标题】:Check if value exists in column in VBA检查VBA中的列中是否存在值
【发布时间】:2012-09-20 11:10:44
【问题描述】:

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

有人可以帮帮我吗?

【问题讨论】:

    标签: excel vba matching


    【解决方案1】:

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

    【讨论】:

    • 感谢您这样做,斯科特。对于非数字值,它将比FOR 循环更健壮。 @user1547174 您可以使用变量Rng 来获取有关匹配位置的信息,特别是调用Rng.Address,它将单元格位置作为字符串返回。
    【解决方案2】:

    最简单的就是使用Match

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

    【讨论】:

    • 在 VB 编辑器的自动完成中不显示,但似乎可以工作
    【解决方案3】:

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

    【讨论】:

    • 还有一件事 - 我如何要求它在特定的工作表中进行搜索?我当前的程序中有几个工作表,我需要它来搜索一个名为“代码”的工作表。谢谢。
    • 使用范围的find方法比遍历每个单元格要快得多
    • 仅供参考,你可以做的比匹配函数容易得多:=countif(A:A,12345)&gt;0 如果找到数字,将返回 True,否则返回 false。
    • @user1547174 要为特定工作表执行此操作,请引用如下单元格:Sheets("Codes").Cells(i,1).Value@scott true,但如果用户不检查许多值,则可能更容易实现 @987654332 @ 在范围上循环。如果@user1547174想用这个方法,查看MSDN上的FIND方法:msdn.microsoft.com/en-us/library/office/ff839746.aspx
    • @nutsch 好主意。也可以通过 VBA 与 Application.WorksheetFunction.CountIf 配合使用。
    【解决方案4】:

    试试这个:

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

    【讨论】:

      【解决方案5】:

      只是为了修改 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 更改为布尔值或其他任何值,以加快速度。

      请注意,VBA 的 Find 有时比蛮力循环或 Match 等其他方法慢,因此不要仅仅因为它是 VBA 的原生方法就认为它是最快的。它更加复杂和灵活,这也可能使其并不总是那么高效。它有一些有趣的怪癖需要注意,比如“对象变量或未设置块变量”error。

      【讨论】:

      • 我喜欢这个概念,但是当找不到字符串时,您的示例将不起作用,例如MsgBox FindFirstInRange(StringToFind, Range("2:2")).Address。它将抛出“需要对象”。
      • 由于这种方法是唯一有希望的方法,因此我解决了 JeffC 提到的问题:如果输入的搜索字符串为空,则问题是情况。我更改了函数,因此返回值始终是布尔值。你可以在下面的某个地方找到我完整的遮阳篷。
      【解决方案6】:

      修复了@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
      

      【讨论】:

        【解决方案7】:

        尝试添加 WorksheetFunction:

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

        【讨论】:

        • 使用 WorksheetFunction 改变了 VBA 如何处理在找不到值时出现的错误。 VBA 不是返回错误值(然后可以通过 IsError 函数检查),而是抛出一个需要错误处理或将停止执行的错误。为了测试一个值是否存在,你只需要一个 True 或 False 结果,而不是潜在地产生一个运行时错误。
        【解决方案8】:
        =IF(COUNTIF($C$2:$C$500,A2)>0,"Exist","Not Exists")
        

        【讨论】:

        • 这个答案被标记为Low Quality 并且可以从解释中受益。以下是How do I write a good answer? 的一些指南。仅代码答案不被视为好的答案,并且可能会被否决和/或删除,因为它们对学习者社区不太有用。它只对你很明显。解释它的作用,以及它与现有答案(如果有的话)有何不同/更好。 From Review
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-10
        • 2017-09-06
        • 1970-01-01
        • 2020-06-15
        • 2018-11-14
        相关资源
        最近更新 更多