【问题标题】:Delete rows using .Range.Find() method使用 .Range.Find() 方法删除行
【发布时间】:2020-01-15 11:55:36
【问题描述】:

我正在尝试查找包含以下值“# Results”的每个单元格,如果右侧的单元格 == 0,则删除整行以及下面的行。

但是,由于我正在删除行,因此 .Range.Find 方法会出现错误,并且在第一次删除后无法找到下一个出现。我怎样才能使这段代码工作?

代码如下:

sub KillEmptyResults()

Dim sRows As Range
Dim X As Range

Set X = Nothing
SearchStr = Chr(35) & " Results"
With ActiveSheet.UsedRange
    Set X = .Cells.Find(What:=SearchStr, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlRows, SearchDirection:=xlPrevious, MatchCase:=False)
        If Not X Is Nothing Then
        sFirstAddress = X.address
        Do
            'Transform anchor row to entire range to delete
            If X.Offset(0, 1).Value = "0" Then
                Set sRow = Rows(X.Row).EntireRow
                Set sRows = sRow.Resize(sRow.Rows.Count + 1, sRow.Columns.Count)
                sRows.Delete
            End If
            Set X = .FindNext(X)
        Loop While Not X Is Nothing And X.address <> sFirstAddress
        End If
End With

End Sub

谢谢

【问题讨论】:

  • Union找到单元格,然后在Loop之后立即删除
  • 我认为你应该从Set X = .Cells.Find(What:=SearchStr, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlRows, SearchDirection:=xlPrevious, MatchCase:=False)循环直到X什么都没有,如果它返回到第一个重合,则添加一个断点。
  • 顺便说一句,另一种方法是简单地AutoFilter 你的UsedRange。您可能会发现这不那么令人困惑?您似乎对包含您的条件和偏移值的相同列感兴趣
  • @JvdV - 你如何用 AF 删除下面的行?
  • @SJR,我会使用SpecialCells(12) 设置Range 对象,然后使用简单的Resize 循环通过Areas/Cells。如果它更容易理解,它只是 OP 的一个选项。无论如何,我仍然会选择我的第一条评论 =)

标签: excel vba


【解决方案1】:

是的,问题是,如果您正在删除行,则会更改先前找到的单元格的地址,因此请随时存储相关范围,并在最后进行删除:

Sub KillEmptyResults()

Dim sRows As Range
Dim X As Range, sFirstAddress As String, SearchStr As String, rDelete As Range

SearchStr = Chr(35) & " Results"

With ActiveSheet.UsedRange
    Set X = .Cells.Find(What:=SearchStr, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlRows, SearchDirection:=xlPrevious, MatchCase:=False)
        If Not X Is Nothing Then
            sFirstAddress = X.Address
            Do
                'Transform anchor row to entire range to delete
                If X.Offset(0, 1).Value = 0 Then
                    If rDelete Is Nothing Then 'establish range to be deleted
                        Set rDelete = X.Resize(2).EntireRow
                    Else
                        Set rDelete = Union(rDelete, X.Resize(2).EntireRow)
                    End If
                End If
                Set X = .FindNext(X)
            Loop While X.Address <> sFirstAddress
        End If
End With

If Not rDelete Is Nothing Then rDelete.Delete

End Sub

【讨论】:

  • 如果有空行,UsedRange 会起作用吗?话虽如此,OP已经接受了答案,所以我认为情况并非如此
  • @Zac - 是的,应该这样做(currentregion 会失败),尽管通常不建议这样做。
  • 有趣。我认为UsedRange 有空行问题,但使用非连续范围。我有一个宏正在运行,但一旦完成就会试一试。这对我来说是一天的新事物:)
  • @Zac - 无论如何都要给它一个测试,但usedrange 是基于最后使用的单元格,并且可能是一个问题,因为仍然可能包含以前包含某些内容的空单元格(如果文档未保存)。
  • 你很聪明。这就是我刚刚注意到的行为。我离开UsedRange 的唯一目的是我认为它停在第一排空荡荡的行。如果场景需要,我将来会使用它。谢谢
猜你喜欢
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多