VBA更优化:过滤隐藏的行

时间:2012-10-08 11:37:34

标签: excel vba excel-vba

我需要过滤超过50000行512次的Excel工作表。我目前正在使用以下代码。

Do While Not IsEmpty(ActiveCell.value)

        Worksheets("Sheet1").Activate
        filtro = ActiveCell.value

        Sheets("Sheet2").Select
        Range("D1").Select
        Selection.AutoFilter
        ActiveSheet.Range("$A$1:$I$" & lastRow("D")).AutoFilter Field:=4, Criteria1:=filtro

        Range("A1").Select

        Do While Not IsEmpty(ActiveCell.value)

            Do

                ActiveCell.offset(1, 0).Select
                oProgress.Increase 1

            Loop While ActiveCell.EntireRow.Hidden = True

                Call functio ' this function do something with the actual row

        Loop

    Loop

问题是它花了这么多时间来分析50000行X 512次!我想也许最好过滤然后将行复制到临时表中,并检查那里的值?。

Active行由函数readValues

处理

3 个答案:

答案 0 :(得分:2)

与此问题的其他海报一样,我真的对过滤512次时持怀疑态度!但是,既然你说你绝对需要它,请参阅下面的代码。我认为它仍然可以根据您的需求进行清理,但如果没有看到更大的范围,很难说。然而,它应该带你到比现在更有效的地方。

我试图评论我的所有假设,但如果您需要更多解释,请与我们联系。

Sub FilterAll512()

Dim wks1 As Worksheet
Set wks1 = Sheets(1)

Dim rng512 As Range, cel As Range
Set rng512 = wks1.Range("A1:A512") '-> say your filter values are in this range, adjust if needed

Dim wks2 As Worksheet
Set wks2 = Sheets(2)

For Each cel In rng512

    With wks2

        Dim rngFound As Range
        Set rngFound = .Columns(4).Find(cel.Text, LookIn:=xlWhole) ' -> make sure value is there to be filtered on

        If rngFound Then

                .UsedRange.AutoFilter 4, cel.Text '-> assumes upper left most cell is A1

                Dim rngSearch As Range, rngCel As Range
                '-> assumes upper left most cell is A1 and row 1 has headers
                Set rngSearch = Intersect(.UsedRange, .UsedRange.Offset(1), .Columns(4).EntireColumn).SpecialCells(xlCellTypeVisible)

                For Each rngCell In rngSearch

                    oProgress.Increase 1 '-> i don't know what this does, but it doesn't look very efficient, see notes below

                    Call functio

                Next

                '-> perhaps above you are just counting rows?
                    'if so, you can use rngSearch.Rows.Count to get a total count
                    'or you can use rngCell.Row to get the current row



        End If 'iF rngFound Then

    End With ' With wks2

Next 'For Each cel In rng512

Set rngCell = Nothing
Set rngSearch = Nothing
Set rngFound = Nothing
Set cel = Nothing
Set rng512 = Nothing
Set wks2 = Nothing
Set wk1 = Nothing

End Sub

答案 1 :(得分:0)

Excel内置了过滤工具(大多数人会将其描述为excel的一个非常基本的功能)。即使你必须遍历500,000行,这很可能是你能做到的最糟糕(最慢)和最离奇的方式之一:

Do                 
    ActiveCell.offset(1, 0).Select 
Loop While ActiveCell.EntireRow.Hidden = True 

你可以查看Range()。Sort和Range()。AutoFilter这是正确的方法。祝你好运。

答案 2 :(得分:-1)

您可以做的是计算所有行号或行号范围,然后应用如下代码:

rowNumbers = "1:3,10:10,30:50"
Range(rowNumbers).EntireRow.Hidden = True