在Excel VBA中自动筛选后删除隐藏/不可见行

12

我想这很简单明了,但是出于某些原因,它似乎不起作用:(

我有以下代码,它根据我指定的条件自动过滤数据:

Dim lastrow As Long
lastrow = Sheet2.Cells(Sheet2.Rows.Count, "A").End(xlUp).Row

With Sheet2
    .AutoFilterMode = False

    With .Range("A1:AF" & lastrow)
    .AutoFilter
    .AutoFilter Field:=7, Criteria1:="Yes", Operator:=xlFilterValues

    End With

我现在想做的是删除所有不符合条件的未筛选 (隐藏) 行。

我迄今尝试过的方法:

Sub RemoveHiddenRows 
Dim oRow As Object 
For Each oRow In Sheets("Sheet2").Rows 
If oRow.Hidden Then oRow.Delete 
Next 
End Sub 
但是这段代码的问题在于,它只会删除连续隐藏行中的每一行之后的另一行,因为即使已经删除了一行并且所有较低的行都向上移动了一个位置,每个增量仍然会考虑偶数行。
此外,如果可能的话,我更喜欢没有循环的东西,有点像.SpecialCells(xlCellTypeVisible).EntireRow.Delete相反
非常感谢任何帮助。

1
为什么不直接将条件更改为 Criteria1:="<>Yes",然后执行 .SpecialCells(xlCellTypeVisible).EntireRow.Delete - Dmitry Pavliv
@simoco 在这种情况下是可以工作的,但在其他情况下,我基于3或4个多重条件过滤数据,有时每个条件都带有超过1个值。所以我有点想要摆脱未过滤的数据,而不是尝试反转所有标准并删除可见单元格。有什么建议吗? - CaptainABC
1
只需要循环遍历行,并检查 .Hidden = True,然后删除隐藏的行。如果你不想使用循环删除,可以先使用 Union 循环获取隐藏的行,然后一次性删除它们。 - WGS
2个回答

22

所以我想要摆脱未经过滤的数据,而不是尝试反转所有标准并删除可见单元格。

我会使用这个:

Sub RemoveHiddenRows()
    Dim oRow As Range, rng As Range
    Dim myRows As Range
    With Sheets("Sheet3")
        Set myRows = Intersect(.Range("A:A").EntireRow, .UsedRange)
        If myRows Is Nothing Then Exit Sub
    End With

    For Each oRow In myRows.Columns(1).Cells
        If oRow.EntireRow.Hidden Then
            If rng Is Nothing Then
                Set rng = oRow
            Else
                Set rng = Union(rng, oRow)
            End If
        End If
    Next

    If Not rng Is Nothing Then rng.EntireRow.Delete
End Sub

我复制粘贴了代码,但出现了错误,但只需要将 Sheets("Sheet3") 替换为 ActiveSheet 即可解决。现在完美运行! - Calculus Knight

2

我使用了Dmitry Pavliv的解决方案来过滤我的表格,它起作用了(谢谢!),但是有时会出现“删除范围类方法失败”的错误。

当只有一个隐藏行需要删除时,错误似乎会发生。可能重要的是,孤立的隐藏行恰好在表头下面。

通过代码进行调试,rng指向正确的单元格,并且仅显示单个单元格。可能是使用表格而不是命名范围的问题,尽管同一表格格式中的其他隐藏行也可以正常删除。

在我修改了代码的最后部分之后,宏一直运行良好,修改前的代码如下:

If Not rng Is Nothing Then rng.EntireRow.Delete

转换为:

If rng.Rows.Count = 1 Then
   ws.Rows(rng.Row & ":" & rng.Row).Delete
ElseIf rng Is Nothing Then
   rng.EntireRow.Delete
End If

不知何故,以这种格式删除单行是有效的。 我不太确定为什么。 rng对象指向正确的单元格,并且我正在使用它来获取行号,所以不确定为什么在rng.entirerow.delete语句中它无法正常工作。好吧。分享一下,因为遇到许多未解决此错误的帖子。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接