我正在尝试创建一个宏,它将找到包含特定值的每个单元格(例如:Location),然后删除该单元格的整行。将有多个单元格包含该值,我希望所有这些都被删除,所以我创建了一个循环,但由于我已经完成它的方式,它在最后一个之后中断,并且它不会继续使用最后一个的宏。我找不到另一种方式,所以我希望有人比我更聪明,可以帮助我解决这个问题。代码现在看起来像这样:
Do
If Cells.Find(What:="Location").Activate Then
ActiveCell.EntireRow.Select
Selection.Delete
Else MsgBox ("All headers deleted")
End If
Loop
答案 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