Excel VBA для оптимизации цикла - выход при j = 2 - PullRequest
0 голосов
/ 26 сентября 2018

Я пытаюсь оптимизировать код, который будет удалять строки, которые соответствуют определенным критериям.У меня есть рабочий код, но следующий код создает 7 секунд времени ожидания для выполнения:

Dim j As Long
For j = 2 To Rows.Count
If (Range("J" & j).Value <> "") Then
Range("A" & j & ":R" & j).Select
Selection.Delete Shift:=xlUp
End If
Next j

Следующий код выполняется мгновенно;однако, я не могу заставить его работать один раз j = 2. Какой код нужно добавить, чтобы остановить цикл, прежде чем он удалит заголовки столбцов в строке 1?

' Delete rows where column J is not blank
For j = Range("J" & Rows.Count).End(xlUp).Row To 1 Step -1
If (Range("J" & j).Value <> "") Then
Range("A" & j & ":R" & j).Select
Selection.Delete Shift:=xlUp
End If
Next j

1 Ответ

0 голосов
/ 26 сентября 2018

Как уже упоминалось в комментариях, вы должны смотреть назад для удаления.Если вы выполните удаление от row#2 до последней строки, возможно, некоторые строки следует удалить, но они остались там.Возьмем для примера, предположим, что мы собираемся удалить row#3 и row#4.Если мы сделаем это вперед, row#4 станет новым row#3 после удаления старого row#3.И следующая строка, которую нужно проверить, это row#4, то есть оригинал row#5.Таким образом, данные в row#4 на самом деле находятся в row#3 сейчас, и они никогда не будут удалены.

Однако, когда ваши данные достаточно массивны, удаление займет так много ресурсов, что снижает скорость.,Было бы лучше найти все диапазоны для удаления и удалить их сразу в конце.Мы можем сделать это методом Union.И это также может предотвратить проблему, упомянутую ранее, поэтому мы можем продвигаться вперед как другие циклы.

Наконец, вы можете избежать выбора диапазонов, поскольку это не так эффективно.Range().Delete может просто удалить диапазон и без его выбора.

Код будет таким:

'pseudo code
Sub deletion()
    For i = 2 To lastrow
        If shouldBeDeleted Then
             If deletingRng Is Nothing Then
                 Set deletingRng = Cells(i, X)
             Else
                 Set deletingRng = Union(deletingRng, Cells(i, X)
             End If
        End If
     Next i

     deletingRng.Delete Shift:=xlUp
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...