Удалить строки из Excel, используя значения из столбца на другом листе?

Я работаю над листом Excel с несколькими столбцами и примерно 6000 строк. Sheet1 будет содержать основную информацию.(6000 строк и столбцов до R). Sheet2 — это мой список исключений, который мне нужно использовать для фильтрации/удаления этих строк.

Сейчас это то, что я использую, и оно находит только точные совпадения. Мне нужно это, чтобы найти исключения из листа2, даже если они являются частью другого слова.

Например: когда я запускаю это, он найдет и удалит каждую строку, содержащую только слово привет. но не привет мир или привет фу. Мне нужно это, чтобы удалить строку с hello world и hello foo.

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

Sub CheckA()
Dim LR As Long, i As Long
With Sheets("IR Temp")
    LR = .Range("A" & Rows.Count).End(xlUp).Row
    For i = LR To 1 Step -1
        If IsNumeric(Application.Match(.Range("A" & i).Value, Sheets("Exceptions").Columns("A"), 0)) Then .Rows(i).Delete
    Next i
End With
End Sub

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


person Christopher Zion Hall    schedule 22.01.2016    source источник
comment
Я не голосую за закрытие этого вопроса, но я рассмотрел его как минимум в полудюжине других вопросов. См. раздел Установка нескольких подстановочных знаков для автоматической фильтрации. Этот Q также имеет некоторые ссылки на исключение определенных значений из совпадений с подстановочными знаками.   -  person    schedule 23.01.2016
comment
Я вижу, куда идет автоматическая фильтрация с несколькими подстановочными знаками, я думаю, но это заставляет меня помещать каждое исключение или отфильтрованный элемент по одному вместо того, чтобы вытаскивать его из первого столбца второго листа. Мне нужно это, чтобы посмотреть на этот лист и получить список элементов, которые нужно отфильтровать, потому что я не буду единственным человеком, обновляющим этот список исключений, и он может быть обновлен позже другой программой.   -  person Christopher Zion Hall    schedule 23.01.2016
comment
Все, что находится на листе, может быть прочитано в массив и зациклено. метод AutoFilter просто более эффективен, чем перебор отдельных удалений. (что также может не охватывать каждое появление).   -  person    schedule 23.01.2016
comment
Святая корова @Jeeped Я только что прочитал ответ, на который вы ссылались, и я был поражен, используя ключи Scripting.Dictionary как Criteria. Whattttttttttttt твердый   -  person Dan Wagner    schedule 23.01.2016
comment
@DanWagner - спасибо! Ответы на этот метод развивались, но я доволен тем, что получилось. Очень быстро тестирует большие блоки данных.   -  person    schedule 23.01.2016
comment
Привет, @Jeeped -- я на 100% в команде, использующей Range.Autofilter вместо For i = 100000 to 2 Step -1 с тобой, производительность невероятная. Я даже сделал короткий скринкаст, сравнивая их в этом ответе   -  person Dan Wagner    schedule 23.01.2016


Ответы (2)


Функция ПОИСКПОЗ может принимать совпадения с подстановочными знаками, но вам нужно изменить способ определения удаляемых строк. Просто добавьте префикс и суффикс критерия rtem со звездочками (например, Chr(42) ).

Ваш код не удалил более одного вхождения значения критерия. Вероятно, лучше зациклить его, пока не останется совпадений. Поскольку ПОИСКПОЗ возвращает ошибку при несоответствии, лучше полагаться на СЧЁТЕСЛИ для возврата значения больше нуля.

Sub CheckA()
    Dim str As String, a As Long, vSTRs As Variant

    With Worksheets("Exceptions")
        vSTRs = .Range(.Cells(1, 1), .Cells(Rows.Count, 1).End(xlUp)).Value2
    End With

    With Sheets("IR Temp")
        For a = LBound(vSTRs, 1) To UBound(vSTRs, 1)
            If CBool(Len(Trim(CStr(vSTRs(a, 1))))) Then
                str = Chr(42) & vSTRs(a, 1) & Chr(42)
                Do While CBool(Application.CountIf(.Columns(1), str))
                    .Rows(Application.Match(str, .Columns(1), 0)).EntireRow.Delete
                Loop
            End If
        Next a
    End With
End Sub

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

person Community    schedule 22.01.2016
comment
Теперь я сталкиваюсь с ошибкой времени выполнения Excel VBA «13». Несоответствие типов. У меня есть идея, почему, и я читаю об этом больше. Я знаю, что не упоминал об этом раньше, но в столбце A Sheets (IR Temp) также есть числа и %: %? $ _ . ( ) Также список фильтров в рабочих листах (исключения). - person Christopher Zion Hall; 23.01.2016
comment
В этом случае мое первоначальное предложение из комментариев Q было бы более подходящим. - person ; 23.01.2016

Ниже предполагается, что ваш список слов для поиска находится в столбце Sheet2 A, а ваш список для их проверки - это столбец Sheet1 A, начальная строка 2. Может быть более приятный способ, чем вложенный цикл, но здесь у нас есть ваш список слов в массив, проходя по всем ячейкам, которые мы хотим увидеть, содержат ли они одно из слов, и для каждой из этих ячеек, проходя по циклу, чтобы проверить, есть ли там одно из перечисленных слов.

Public Sub testing()

Dim x As Integer
Dim i As Integer
Dim ws As Worksheet
Dim listws As Worksheet
Dim endList As Integer
Dim endR As Integer
Dim arr() As Variant

Set ws = ThisWorkbook.Worksheets("Sheet1")
endR = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Set listws = ThisWorkbook.Worksheets("Sheet2")
endList = listws.Cells(ws.Rows.Count, "A").End(xlUp).Row
arr = listws.Range("A1:A" & endList)

x = 2
While x <= endR
    For i = 1 To UBound(arr, 1)
        If InStr(ThisWorkbook.Worksheets("Sheet1").Cells(x, 1).Value, arr(i, 1)) > 0 Then
            ThisWorkbook.Worksheets("Sheet1").Cells(x, 1).EntireRow.Delete
        End If
    Next i
    x = x + 1
Wend

End Sub
person andrewf    schedule 23.01.2016
comment
Вы правы, это работает, но не так, как мне нужно. Мне все еще нужно это, чтобы использовать второй лист в качестве рабочего списка, к которому я могу добавить. Я не хочу добавлять каждый элемент, который мне нужно отфильтровать, из этого списка в VBA, поскольку их становится все больше, и их нужно легко обновлять. Jeeped указал мне направление использования массива, если я правильно это понимаю. Или, может быть, я больше запутался сейчас, чем когда я начал. Что я знаю точно, так это то, что мне нужно еще много читать, так как я новичок в программировании. - person Christopher Zion Hall; 23.01.2016
comment
Это вроде работает для меня! И спасибо за это: D Прямо сейчас единственная проблема, с которой я столкнулся, заключается в том, что мне нужно запустить макрос несколько раз, чтобы удалить все строки. Иногда он пропускает некоторые из них. Кроме того, мой список исключений работает довольно хорошо, и все меняется хорошо. Однако мне нужно поработать над некоторыми модификациями. - person Christopher Zion Hall; 24.01.2016
comment
Теперь, когда мой список составляет примерно треть от первоначального размера, я понял, что у меня есть элементы, которые являются (почти) дубликатами, и мне нужно решить, как избавиться от них. Например, sdf_left.top.var.status и sdf_left.top.var.value для меня — это две отдельные строки, но мне нужна только одна из них. Я не могу просто добавить .status или .value в свой список исключений, потому что у меня есть другие элементы, которые я не хочу фильтровать с .value или .status в конце. sdf_left.top.var.status ~ необходимо удалить. sdf_left.top.var.value ~должен остаться sdf_left.top.bit.value ~должен остаться sdf_left.right.var.status ~должен остаться - person Christopher Zion Hall; 24.01.2016
comment
разве вы не можете просто поместить весь sdf_left.top.var.status в список удаляемых слов? - person andrewf; 25.01.2016
comment
Это сработало бы, если бы нужно было фильтровать только это, и я знал название каждой комбинации. в этой небольшой базе данных 6k строк это возможно. Некоторые из моего списка составляют более 15-25 тысяч строк. если я добавлю каждое из них, могут быть добавлены еще сотни исключений. Я понимаю, что если бы я сделал это однажды, это было бы не навсегда. пока я не получил новую базу данных. Часть проблемы в том, что я не знаю, что будет в базах данных. - person Christopher Zion Hall; 26.01.2016