Как улучшить производительность в цикле Excel VBA For с вложенным циклом If?
Это мой первый пост, поэтому, если мне нужно внести какие-либо изменения, пожалуйста, дайте мне знать.
Я нашел несколько примеров способов оптимизации циклов, но я не могу применить какой-либо из них эффективно к моему коду. То, что я пытаюсь сделать, это перебрать около 170 ячеек в одном столбце и скрыть или показать всю строку в зависимости от того, равно ли значение ячейки 0 или нет.
Я хочу, чтобы код запускался каждый раз, когда я активирую определенные листы. Прямо сейчас этот кусок кода занимает около 4 секунд для запуска. Кажется, что это должно быть намного быстрее, чем это! Вот почему я здесь за помощью.
Вот код, который я использую (FormatSheet возвращает BOOLEAN, где True означает, что можно выполнить этот код на этом листе, а False - пропустить выполнение этого кода на этом листе:
Private Sub mobjWb_SheetActivate(ByVal Sh As Object)
Dim r As Long
Dim z As Long
Dim varray As Variant
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
If Not FormatSheet(Sh) Then
Exit Sub
End If
Set varray = Range("$F$1", Cells(Rows.count, "F").End(x1up)).Value
For Each r In varray
z = r.Value
If z = 0 Then
Range("F" & r).EntireRow.Hidden = True
Else
Range("F" & r).EntireRow.Hidden = False
End If
Next r
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
ActiveSheet.DisplayPageBreaks = True
End Sub
2 ответа
С несколькими очень незначительными изменениями:
Sub qwerty()
Dim r As Range
Dim z As Long, N As Long
Dim varray As Range
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
N = Cells(Rows.Count, "F").End(xlUp).Row
Set varray = Range("F1:F" & N)
For Each r In varray
z = r.Value
If z = 0 Then
r.EntireRow.Hidden = True
Else
r.EntireRow.Hidden = False
End If
Next r
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayStatusBar = True
Application.EnableEvents = True
ActiveSheet.DisplayPageBreaks = True
End Sub
беги довольно быстро
Я думаю, что самый быстрый способ - использовать автофильтр. Установите для автофильтра значения <> 0 и вуаля!
Одна вещь, которая может ускорить это немного.. Я бы не использовал переменную z. Вы можете сделать то же самое с существующим р.
For Each r In varray
If r.Value = 0 Then
Range("F" & r).EntireRow.Hidden = True
Else
Range("F" & r).EntireRow.Hidden = False
End If
Next r