如何使用查找功能激活找到的单元格?

时间:2017-11-17 10:37:26

标签: excel-vba loops vba excel

我正在尝试创建一个宏,它将找到包含特定值的每个单元格(例如:Location),然后删除该单元格的整行。将有多个单元格包含该值,我希望所有这些都被删除,所以我创建了一个循环,但由于我已经完成它的方式,它在最后一个之后中断,并且它不会继续使用最后一个的宏。我找不到另一种方式,所以我希望有人比我更聪明,可以帮助我解决这个问题。代码现在看起来像这样:

  Do
   If Cells.Find(What:="Location").Activate Then
    ActiveCell.EntireRow.Select
    Selection.Delete
   Else MsgBox ("All headers deleted")
   End If
  Loop

3 个答案:

答案 0 :(得分:3)

你实际上非常接近。这里有一些如何让它发挥作用,一些未成年人"没有必要,但仍然很好有"改进:

Sub test()
    Dim rng As Range
    Do
        Set rng = Cells.Find(What:="b")
        If Not rng Is Nothing Then
            rng.EntireRow.Delete
        Else
            MsgBox ("All headers deleted")
            Exit Do
        End If
    Loop
End Sub

我添加Range对象并在我们进入If循环之前声明它的原因主要是为了提高可读性,但我们也不会尝试使用.Find几个倍。它不太可能产生任何重大影响 - 编译器可能会自行解决这个问题。无论如何,在代码中明确表达它并没有什么坏处。

删除最后一个实例后出错的原因是代码尝试.Activate空范围。不允许此操作。一个解决方案,即我在这里找到的解决方案,是在尝试调用其任何成员之前检查范围对象是否有效。如果对象无效,则循环将完全跳过它,我们不会收到任何错误。这样做的方式是Range.Find如果找不到任何内容,则返回Nothing(这是一个有效的对象状态)。您将在我的代码中看到,只有当rng 包含Nothing时,我才会告诉编译器进入循环。

我还删除了所有.Select次来电,因为它是not good practice。最佳做法是明确声明所有变量并直接在范围内工作。生成的代码也更短,更易于阅读。

最后一次修改是在Exit Do子句中添加Else。这是非常必要的,因为您没有向Do ... Loop添加任何中断条件。如果某个地方没有Exit Do,程序会永远向你扔MsgBox

也可以从Exit Do转移到更健壮的Do ... Loop with conditions - 它可能如下所示:

Sub test()
    Dim rng As Range
    Do
        Set rng = Cells.Find(What:="b")
        If Not rng Is Nothing Then
            rng.EntireRow.Delete
        Else
            MsgBox ("All headers deleted")
        End If
    Loop While (Not rng Is Nothing)
End Sub

答案 1 :(得分:1)

使用FindNext。在此示例中,它构建要删除的找到的单元格,并将它们全部设置为变量。然后它一次性全部删除它们 - 如果您要删除许多单元格然后逐个执行它们,这会快得多。

Dim DelRng As Range, fndCell As Range
Dim firstAddress As String

With ActiveSheet
    Set fndCell = .Cells.Find(What:="Location")
    If Not fndCell Is Nothing Then
        firstAddress = fndCell.Address
        Do
            If DelRng Is Nothing Then
                Set DelRng = fndCell
            Else
                Set DelRng = Union(DelRng, fndCell)
            End If
            Set fndCell = .Cells.FindNext(fndCell)
        Loop Until fndCell.Address = firstAddress
    End If
    If Not DelRng Is Nothing Then
        DelRng.EntireRow.Delete
        MsgBox ("All headers deleted")
    Else
        MsgBox ("No headers found")
    End If
End With

答案 2 :(得分:-1)

这对我有用。

Set cell = Selection.Find(What:=valueToFind, After:=ActiveCell, LookIn:=xlFormulas, _
    LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
    MatchCase:=False, SearchFormat:=False)
If Not cell Is Nothing Then
    cell.Select
 else
   msgbox "Cell with given Data not found"
end if