Reputation: 473
I'm trying to speed up my VBA code and am not sure how to do it. The slowest task by far is my loop to hide empty rows. (I have several pivot tables aligned vertically and I had to leave space to allow them to expand when new data is added.)
Public Sub HideRows(list1 As Range)
Dim cell As Range
For Each cell In list1
cell.EntireRow.Hidden = (cell.Value = "")
Next cell
End Sub
Public Sub UnhideRows(list1 As Range)
Dim cell As Range
For Each cell In list1
If (cell.Value <> "") Then cell.EntireRow.Hidden = False
Next cell
End Sub
Upvotes: 1
Views: 8266
Reputation: 2430
No need to loop -- you should be able to hide the entire range all at once -- I tested using this sub:
Public Sub HideRows_test(list1 As Range)
list1.EntireRow.Hidden = True
End Sub
edit: sorry, I jumped the gun on this, didn't realize there was a condition on the range. However, instead of hiding each separately, you can build a new range using your existing loop then hide all rows in it afterwards.
edit: I mentioned you can build the range dynamically, then hide all rows at the end -- here's how:
Public Sub HideRows(list1 As Range)
Dim cellsToHide As Range
Set cellsToHide = Nothing
Dim cell As Range
For Each cell In list1
If cell.Value = "" Then
If cellsToHide Is Nothing Then
Set cellsToHide = cell
Else
Set cellsToHide = Union(cellsToHide, cell)
End If
End If
Next cell
cellsToHide.EntireRow.Hidden = True
End Sub
However, I think you can indeed get rid of the for each entirely by using SpecialCells(xlCellTypeBlanks)
, like so:
Public Sub HideRows(list1 As Range)
Set list1 = list1.SpecialCells(xlCellTypeBlanks)
list1.EntireRow.Hidden = True
End Sub
Upvotes: 2
Reputation: 14145
Look into using Application.ScreenUpdating
. Setting this to false prevents Excel from updating the display after every operation, which increases speed significantly - ESPECIALLY when using a slow command such as hide/unhide.
If you don't need to iterate through your cells, you can do something similar to mr Reband's answer.
But in general, Application.ScreenUpdating = false
will speed up nearly all code interacting with Excel significantly.
Public Sub HideRows(list1 As Range)
Dim cell As Range
Application.ScreenUpdating = False
For Each cell In list1
cell.EntireRow.Hidden = (cell.Value = "")
Next cell
Application.ScreenUpdating = True
End Sub
Public Sub UnhideRows(list1 As Range)
Dim cell As Range
Application.ScreenUpdating = False
For Each cell In list1
If (cell.Value <> "") Then cell.EntireRow.Hidden = False
Next cell
Application.ScreenUpdating = True
End Sub
Upvotes: 1