优化在VBA中删除隐藏行的性能

时间:2015-05-24 16:51:23

标签: performance vba loops excel-vba filter

我在使用自动过滤器将自动过滤器应用到VBA中的大页面时使用以下代码来删除隐藏/过滤行(大约意味着大约30,000行):

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

代码来自此处:Delete Hidden/Invisible Rows after Autofilter Excel VBA

此外,我读了这个帖子:Speeding Up Code that Removes Hidden Rows on a Sheet

情况:我已经对包含12列的表应用了5个不同的过滤器,因此在过程之后会过滤掉许多行(隐藏)。当我尝试删除它们时,上面的代码需要很长时间。在我的情况下,我不知道Excel是否仍在工作,所以我不得不强制退出。这导致了以下问题:

除了遍历所有隐藏的行并删除它们之外还有其他方法吗?

我想到的一个想法是仅将剩余的未经过滤的(即非隐藏)内容复制到新工作表中,然后删除包含完整信息的旧工作表。如果是这样,怎么办呢?

2 个答案:

答案 0 :(得分:3)

我认为您不需要涉及其他工作表。只需复制现有Range.CurrentRegion property下方的行,然后删除过滤器并删除原始数据。

<div ng-messages="myForm.fieldName.$error && (myForm.firldName.$dirty || myForm.$submitted)">
    <div ng-message="required">This field is required</div>
    <div ng-message="minlength">Your field is too short</div>
</div>

您也可以通过Code Review (Excel)发布一些关于此主题的优秀,专注的帮助。

答案 1 :(得分:2)

You can improve performance significantly with a function like this:

Option Explicit

Public Sub deleteHiddenRows(ByRef ws As Worksheet)

    Dim rngData As Range, rngVisible As Range, rngHidden As Range

    With ws
        Set rngData = .UsedRange
        With rngData
            Set rngVisible = .SpecialCells(xlCellTypeVisible)
            Set rngHidden = .Columns(1)
        End With
    End With

    If Not (rngVisible Is Nothing) Then

        ws.AutoFilterMode = False

        ' invert hidden / visible
        rngHidden.Rows.Hidden = False
        rngVisible.Rows.Hidden = True

        ' delete hidden and show visible
        rngData.SpecialCells(xlCellTypeVisible).Delete
        rngVisible.Rows.Hidden = False

    End If
End Sub

I tested it on a file with 2 filters applied to it

The function was adapted from the code in this suggestion