1

Я новичок в VBA, поэтому код, который я написал, очень небрежный. Мои извенения.

Суть моей проблемы в том, что мне нужно удалить дубликаты строк с листа ок. 45 000 строк. Каждая итерация, где удаляется строка, занимает около 30 секунд, и мне нужно сделать это для тысяч строк. Любые предложения о том, как улучшить мой код, чтобы все это прошло быстрее?

Sub delete_duplicate_rows()
For i = 1 To 85000
    If ActiveCell <> ActiveCell.Offset(1, 0) Or ActiveCell.Offset(0, -1) <> ActiveCell.Offset(1, -1) Or ActiveCell.Offset(0, 1) <> ActiveCell.Offset(1, 1) Or ActiveCell.Offset(0, 2) <> ActiveCell.Offset(1, 2) Or ActiveCell.Offset(0, 3) <> ActiveCell.Offset(1, 3) Or ActiveCell.Offset(0, 4) <> ActiveCell.Offset(1, 4) Or ActiveCell.Offset(0, 5) <> ActiveCell.Offset(1, 5) Or ActiveCell.Offset(0, 6) <> ActiveCell.Offset(1, 6) Or ActiveCell.Offset(0, 7) <> ActiveCell.Offset(1, 7) Or ActiveCell.Offset(0, 8) <> ActiveCell.Offset(1, 8) Or ActiveCell.Offset(0, 9) <> ActiveCell.Offset(1, 9) Or ActiveCell.Offset(0, 10) <> ActiveCell.Offset(1, 10) Or ActiveCell.Offset(0, 11) <> ActiveCell.Offset(1, 11) Or ActiveCell.Offset(0, 12) <> ActiveCell.Offset(1, 12) Or ActiveCell.Offset(0, 13) <> ActiveCell.Offset(1, 13) Then
        ActiveCell.Offset(1, 0).Select
        GoTo NextIteration
    Else
    End If
    If ActiveCell.Value = "" Then Exit Sub
    ActiveCell.Offset(0, -1).Range("A1:Q1").Select
    Selection.Delete Shift:=xlUp
    ActiveCell.Offset(0, 1).Range("A1").Select
NextIteration:
    Next i
End Sub

Большое спасибо.

1 ответ1

0

Как уже говорили другие, ваш код медленный, чтобы сделать пару вещей, таких как с помощью select , activate и goto

Я полагаю, что причиной медленной производительности является одновременная проверка нескольких условий, поскольку вы можете проверить изменения в ячейках.

sub delete_duplicate_rows(byref ws as worksheet)

    ' Dim tbl_width as long, tbl_height as long
    ' Dim row_n, col_n as long
    '
    ' This would be the correct form of one line var declarations, as it was stated in the comments
    ' I prefer this style, so I can group things like iters, table sizes, variants for `For each` 
    ' and save some lines and see more code(I've a small screen)

    dim tbl_width as long 
    dim tbl_height as long
    dim row_n as long 
    dim col_n as long
    with ws
        for row_n=tbl_height to 2 step -1
            for col_n=1 to tbl_width
                if .range(.cells(row_n, col_n)) <> .range(.cells(row_n - 1, col_n)) then
                    .range(.cells(row_n , 1), .cells(row_n, tbl_width)).delete shift:=xlShiftUp
                    col_n = tbl_width
            next col_n
        next row_n
    end with

end sub

Это не зависит от фиксированного набора строк, не активирует и не выбирает ничего, и внутренний цикл может быть завершен раньше, когда одно из условий не выполнено. Таким образом, вы будете проверять только достаточно, чтобы принять решение об удалении.

Вы можете вложить другой цикл, поэтому он будет проверять все строки, а не только те, что ниже.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .