我非常擅长为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
答案 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