Удалить строки на основе нескольких значений ячеек в столбце на другом листе - PullRequest
0 голосов
/ 14 февраля 2019

Я все еще новичок в VBA.Это новый пост, созданный, поскольку я не был достаточно конкретен в предыдущем.
Моя цель: я хочу удалить строку данных, основанную на столбце данных из другого листа.

У меня естьназвание листа данных: WorkingData.
WorkingData - это список базы данных с ProductIDs, который находится под столбцом A. productIDs будет существовать более одного раза, поскольку он идентифицирован по периоду.

ProductIDs    Date
132           30/9/2018
132           30/8/2018
132           30/7/2018
122           30/9/2018
122           30/8/2018
11            30/7/2018
11            30/6/2018
...

Sheets (ID для исключения)

ProductID
11
23
55
34
.....

У меня есть внешнее имя листа: IDs to exclude.
В Sheets("IDs to exclude") в столбце A есть список идентификаторов для исключенияпотому что они нечистые данные.Однако каждый месяц список будет продолжать складываться , поэтому диапазон должен идентифицировать последнюю строку.

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

Sub delete_Ids()
    Dim c As Range, MyVals As Range, SrchRng As Range
    Dim i As Long, lr1 As Long, lr2 As Long, x

    'This is a range containing all the criteria to search for
    lr1 = Sheets("WorkingData").Cells(Rows.Count, "A").End(xlUp).Row
    Set MyVals = Sheets("ProductIDs to Exclude").Range("A2:A" & lr1)

    Set SrchRng = Selection
    lr2 = SrchRng.Rows.Count

    For i = lr2 To 1 Step -1
        For Each c In MyVals
    x = InStr(SrchRng(i), c)

    If x > 0 Then
                SrchRng(i).EntireRow.Delete
                Exit For
            End If
        Next c
    Next i  
End Sub

1 Ответ

0 голосов
/ 14 февраля 2019

Чтобы сделать ваш код быстрее:

  1. Считать данные (столбец A) в массив ArrIDs
  2. Считать идентификаторы для вывода в массив ArrExclude

  3. Цикл по данным ArrIDs и

  4. Проверьте, совпадает ли он с любым из идентификаторов для исключения с помощью метода WorksheetFunction.Match.
  5. Соберите все подходящие строки в переменную RowsToDelete
  6. В конце удалите их сразу.

Это будет один из самых быстрых способов, как мне кажется.

Проблема в том, что каждое действие чтения / записи в ячейке занимает много времени, поэтому мы стараемся уменьшить их.Если вы удалите каждую строку отдельно, то у вас будет много действий записи.Но если вы сначала соберете их с помощью Union и сразу удалите их, у вас будет только одно действие записи.

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

Option Explicit

Public Sub AlternativeDeleteIDs()
    Dim wsData As Worksheet 'define datat sheet
    Set wsData = ThisWorkbook.Worksheets("WorkingData")

    Dim ArrIDs() As Variant 'read data into array
    ArrIDs = wsData.Range("A1", wsData.Cells(wsData.Rows.Count, "A").End(xlUp)).Value

    Dim ArrExclude() As Variant 'read IDs to exclude into array
    With ThisWorkbook.Worksheets("IDs to exclude")
        ArrExclude = .Range("A2", .Cells(.Rows.Count, "A").End(xlUp)).Value
    End With

    Dim RowsToDelete As Range 'we collect all rows to delete here
    Dim MatchedRow As Long

    Dim iRow As Long
    For iRow = LBound(ArrIDs, 1) + 1 To UBound(ArrIDs, 1) '+1 because of header in data
        MatchedRow = 0 'initialize
        On Error Resume Next 'next line throws error if ID is not in exclude list
        MatchedRow = Application.WorksheetFunction.Match(ArrIDs(iRow, 1), ArrExclude, False)
        On Error GoTo 0

        If MatchedRow <> 0 Then 'ID was found in exclude list
            'mark ID for delete
            If RowsToDelete Is Nothing Then
                Set RowsToDelete = wsData.Rows(iRow)
            Else
                Set RowsToDelete = Union(RowsToDelete, wsData.Rows(iRow))
            End If
        End If
    Next iRow

    'delete all rows at once
    RowsToDelete.Delete
End Sub

Таким образом, в этом коде у нас есть только 2 действия чтения (в массив) и 1 действие записи (удаление).

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