Ускорение поиска и удаления макроса - PullRequest
2 голосов
/ 04 января 2012

У меня есть список, содержащий три столбца.Первый столбец содержит имена, а два других столбца имеют номера.Макрос берет имя (A1) и затем ищет в столбце A другое вхождение.

Когда он находит его, он удаляет всю строку. Затем он переходит к A2 и выполняет то же самое.Он работает нормально около 500 записей, но использование 3000 записей значительно замедляет его.Есть ли способ ускорить этот код?

Sub Button1_DeleteRow()

Dim i As Integer
Dim j As Integer    
Dim Value As Variant
Dim toCompare As Variant

For i = 1 To 3000      
    Value = Cells(i, 1)
    For j = (i + 1) To 3000
        toCompare = Cells(j, 1)
        If (StrComp(Value, toCompare, vbTextCompare) = 0) Then
           Rows(j).EntireRow.Delete
        End If
      Next j  
Next i

End Sub 

Ответы [ 4 ]

4 голосов
/ 04 января 2012

Если вы используете xl07 / 10, вы можете сделать это одной строкой с Remove Duplicates.Если вы используете 03, тогда решение с автофильтром будет наиболее эффективным (я могу предоставить это, если вы используете более старую версию)

Удалить дубликаты

  1. Вручную

    • Выбрать столбец A
    • Данные .... Удалить дубликаты
    • Развернуть выбор
    • Выбрать только столбец A, чтобы найти дубликаты
  2. Код

    ActiveSheet.Range("$A$1:$A$3000").EntireRow.RemoveDuplicates Columns:=1, Header:=xlNo

before only A after

3 голосов
/ 04 января 2012

В дополнение к ответу @ brettdj, если вы работаете в Excel 2003, вы можете сделать это с помощью AdvancedFilter следующим образом:

Range("A1:A11").AdvancedFilter Action:=xlFilterInPlace, Unique:=True

Примечание: AdvancedFilter предполагает, что первая строка вашего диапазона (строка A в этом примере) содержит заголовки столбцов и не будет включать эту строку в фильтрацию.

Чтобы сделать это вручную: Данные> Фильтр> Расширенный фильтр ...> Только уникальные записи

2 голосов
/ 04 января 2012

Использование техники Бреттса - хороший ответ, но чтобы ответить на ваш вопрос о том, почему это занимает так много времени:
- Ваш макрос получает значение из более чем 4 миллионов ячеек одна за другой. Это очень медленно.
- Я не вижу, чтобы ваш макрос отключил обновление экрана и автоматический расчет: каждый раз, когда удаляется строка, экран обновляется и Excel пересчитывается. Если вы не выключили их, это очень медленно.
Этот код должен работать намного быстрее

Option Explicit
Sub Button1_DeleteRow()
Dim i As Long
Dim j As Long
Dim vArr As Variant
Dim iComp As Long
Dim Deletes(1 To 3000) As Boolean
Application.ScreenUpdating = False
iComp = Application.Calculation
Application.Calculation = xlCalculationManual
vArr = Range("a1:A3000")
For i = 1 To 3000
    For j = (i + 1) To 3000
        If (StrComp(vArr(i, 1), vArr(j, 1), vbTextCompare) = 0) Then
           Deletes(j) = True
        End If
      Next j
Next i
For j = 3000 To 1 Step -1
If Deletes(j) Then Rows(j).EntireRow.Delete
Next j
Application.ScreenUpdating = True
Application.Calculation = iComp
End Sub
0 голосов
/ 05 января 2012

Сортировка данных в столбце A сделает тривиальным определение и удаление дубликатов за один проход


В ответ на комментарий ниже я объясню, почему сортировка является полезной техникой.

Сортируя столбец A по порядку, удаление дубликатов просто становится вопросом сравнения смежных записей в столбце A. Затем можно удалить дубликаты строк по мере их нахождения или отметить их для последующего удаления.

Процесс на самом деле должен быть намного менее утомительным, поскольку вам нужно только отсортировать список (а сортировка, будучи встроенной, имеет тенденцию быть очень быстрой), а затем сделать один проход (вместо 4498500) через удаление списка пометка, как вы идете (очевидно, вам нужен последующий проход очистки, если вы идете для пометки).

Что касается изменения порядка списка, начните с добавления дополнительного столбца (например, столбца D), и пусть D2 будет содержать значение 2 (т.е. только номер строки). Быстрое заполнение позже и каждый ряд нумеруется. После сортировки и удаления / пометки восстановление исходного порядка - это просто вопрос повторной сортировки по столбцу D, который затем можно удалить.

Я использую этот метод, когда мне нужно выполнить ту или иную операцию с дубликатами. Другими словами, столбец A имеет повторяющиеся значения, но значения в столбцах B и C имеют смысл (например, я мог бы захотеть суммировать эти значения из всех записей, относящихся к конкретному значению столбца A). Однако во многих случаях было бы проще использовать SQL для достижения того же результата

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...