隐藏基于内容的行 - 速度

时间:2018-05-16 16:59:49

标签: excel vba

我非常擅长为excel编写VBA宏,并且大部分用Google搜索我想要在excel中完成的内容,并根据我的需要调整其他VBA代码。我的一个宏根据单元格的内容隐藏行。我发现运行它需要太长时间,并且可以使一些较旧的计算机锁定。有没有人建议用更少的资源更快地运行?以下是我正在使用的代码:

Sub Hiderow()
Dim LastRow As Long, c As Range 
Application.EnableEvents = False
LastRow = Cells(Cells.Rows.Count, "C").End(xlUp).Row    
On Error Resume Next 

For Each c In Range("B12:B812") 
    If c.Value = "" Then  
        c.EntireRow.Hidden = True    
    ElseIf c.Value <> "" Then    
        c.EntireRow.Hidden = False    
    End If    
Next
On Error GoTo 0
End Sub

3 个答案:

答案 0 :(得分:3)

您也可以使用SpecialCells()

Sub hide_empty_rows()
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

Dim rng As Range
Set rng = Range("B12:B812")
rng.SpecialCells(xlCellTypeBlanks).EntireRow.Hidden = True
rng.SpecialCells(xlCellTypeConstants).EntireRow.Hidden = False

Application.EnableEvents = True
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub

Application.[]部分将有助于加快速度。你不应该只用800行崩溃Excel,所以我假设你有一些公式/ etc,每次更新单元格时都会更新。 SpecialCells()应该单独加快速度,但三个Application.[]部分通常也很有用。

答案 1 :(得分:0)

您应该在运行时关闭屏幕更新,同时删除ElseIf并将其设为Else:

Dim LastRow As Long, c As Range
Application.EnableEvents = False
Application.ScreenUpdating = False
LastRow = Cells(Cells.Rows.Count, "C").End(xlUp).Row
On Error Resume Next



  For Each c In Range("B1:B812")
      If c.Value = "" Then
      c.EntireRow.Hidden = True
      Else
      c.EntireRow.Hidden = False
      End If
    Next

On Error GoTo 0
Application.ScreenUpdating = True

这会跑得更快

答案 2 :(得分:0)

另一种选择 - 使用AutoFilter + Rows.Hidden

Option Explicit

Public Sub HideEmptyRowsInColB()
    Const FIRST_ROW = 12
    Const FILTER_COL = "B"

    Dim ws As Worksheet, lr As Long, hide As Range, filterCol As Range, vis As Boolean

    Set ws = Sheet3     'Or: Set ws = ThisWorkbook.Worksheets("Sheet3")
    lr = ws.Cells(ws.Rows.Count, FILTER_COL).End(xlUp).Row

    Set filterCol = ws.Range(ws.Cells(FIRST_ROW, FILTER_COL), ws.Cells(lr, FILTER_COL))

    Application.ScreenUpdating = False
        ShowAllRows ws
        If lr > FIRST_ROW Then

            filterCol.AutoFilter Field:=1, Criteria1:="="
                Set hide = filterCol.SpecialCells(xlCellTypeVisible)
                vis = hide.Cells.Count = 1 And Len(hide.Cells(1)) = 0   'Count visible
                Set hide = IIf(vis, Nothing, hide.EntireRow)
            filterCol.AutoFilter

            If Not hide Is Nothing Then
                hide.Hidden = True
                hide.Rows(1).Hidden = (Len(hide.Cells(1)) > 0)
            End If
        End If
    Application.ScreenUpdating = True
End Sub
Public Sub ShowAll()
    ShowAllRows Sheet3
End Sub

Private Sub ShowAllRows(ByRef ws As Worksheet)
    If ws.AutoFilterMode Then ws.UsedRange.AutoFilter
    ws.Rows.Hidden = False
End Sub

<强> Performance

AutoFilter + Rows.Hidden (Current version):

 - Total Rows:   100,001, Hidden:  49,995 - Time:   2.199 sec
 - Total Rows:   200,001, Hidden:  99,995 - Time:   8.551 sec
 - Total Rows:   300,001, Hidden: 149,995 - Time:  19.016 sec
 - Total Rows:   400,001, Hidden: 199,995 - Time:  43.594 sec
 - Total Rows:   500,001; Hidden: 249,995 - Time:  61.387 sec
 - Total Rows: 1,048,573, Hidden: 524,276 - Time: 233.301 sec (almost 4 min)

AutoFilter (Previous version):

 - Total Rows:   500,001; Hidden: 249,995 - Time:   0.211 sec
 - Total Rows: 1,048,563; Hidden: 262,144 - Time:   0.469 sec