VBA: как использовать оператор like для списка значений?

#excel #vba #wildcard #vb-like-operator

#excel #vba #подстановочный знак #vb-like-operator

Вопрос:

Вот часть моего кода. Есть ли какой-нибудь способ упростить это? Спасибо.

 For i = 2 To ws.Range("E1").CurrentRegion.Rows.Count

If ws.Cells(i, 4).Value Like ("*SSI*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*Settlement instruction*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*delivery Instruction*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*Request form*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.cells(i, 4).Value Like ("*Sales to onboarding*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*Application*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*Doc Check list*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*Prime to Credit*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*Prime to Legal*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*Prime_Legal*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*Prime_Credit*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*LEXIS*") Then ws.Cells(i, 4).EntireRow.Delete
If ws.Cells(i, 4).Value Like ("*Withdrawal Request*") Then ws.Cells(i, 4).EntireRow.Delete

Next i
  

Комментарии:

1. Логическое условие = Подобное условию 1 или подобное условию 2 или подобное условию 3 … и т.д. Если (условие) выполнить весь цикл. Удалить.

2. Обратите внимание — способ, которым вы это делаете, и, возможно, это то, что вам нужно, но если Cells(2,4) имеет SSI , то строка будет удалена. Затем он снова посмотрит на Cells(2,4) , проверит, есть ли там это Settlement instruction , и если да, удалит, затем снова ищет следующее … и т.д.

3. также существует VBA.Filter() функция. смотрите здесь

Ответ №1:

Есть много способов сделать это, но вот один:

Во-первых, при удалении строк всегда начинайте с нижней части диапазона и двигайтесь вверх — это предотвращает пропуск строк при удалении.

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

 Dim tmpAr As Variant
Dim test As Variant

Set ws = ActiveSheet
tmpAr = Split("SSI,Settlement instruction,delivery Instruction,Request form,Sales to onboarding,Application,Doc Check list,Prime to Credit,Prime to Legal,Prime_Legal,Prime_Credit,LEXIS,Withdrawal Request", ",")
For i = ws.Range("E1").CurrentRegion.Rows.Count To 2 Step -1
    For Each test In tmpAr
        If ws.Cells(i, 4).Value Like "*" amp; test amp; "*" Then
            ws.Cells(i, 4).EntireRow.Delete
            Exit For
        End If
    Next
Next i
  

Комментарии:

1. Как я должен определить tmpAr? Вариант? строка? Спасибо.

2. а также тестировать? Я не знаком с range. Спасибо

3. Объявления, добавленные в ответ. Создайте их как Variant и Split и For each.. сделает все остальное.

Ответ №2:

Вы могли бы попробовать что-то в этом роде

 Sub del()

Dim a As Variant
Dim s As Variant
Dim r As Range
Dim l As Long

a = Array("*abc*", "*def*", "efg*", "abcdef*hi")
Set r = Range("a1:a20")

For l = r.Rows.Count To 1 Step -1

    For Each s In a
        If r.Cells(l, 1).Value Like s Then
                Rows(l).EntireRow.Delete
                Exit For
        End If
    Next s

Next l

End Sub
  

Комментарии:

1. Вы могли бы также использовать диапазон в Excel для заполнения массива a и использовать r диапазон для заполнения начала и конца циклов.

Ответ №3:

  1. запустите цикл в обратном направлении
  2. избегайте пересчетов
  3. удалять только один раз

 For i = ws.Range("E1").CurrentRegion.Rows.Count To 2 Step -1
    DR = False
    Set r = ws.Cells(i, 4)
    s = r.Value
    If s Like ("*SSI*") Then DR = True
    If s Like ("*Settlement instruction*") Then DR = True
    If s Like ("*delivery Instruction*") Then DR = True
    If s Like ("*Request form*") Then DR = True
    If s Like ("*Sales to onboarding*") Then DR = True
    If s Like ("*Application*") Then DR = True
    If s Like ("*Doc Check list*") Then DR = True
    If s Like ("*Prime to Credit*") Then DR = True
    If s Like ("*Prime to Legal*") Then DR = True
    If s Like ("*Prime_Legal*") Then DR = True
    If s Like ("*Prime_Credit*") Then DR = True
    If s Like ("*LEXIS*") Then DR = True
    If s Like ("*Withdrawal Request*") Then DR = True
    If DR Then ws.Cells(i, 4).EntireRow.Delete
Next i
  

Ответ №4:

Пожалуйста, обратите внимание:

  1. Когда строка удаляется, ячейки сдвигаются вверх, поэтому строка ниже фактически будет иметь тот же номер строки, вот почему я использовал вместо этого цикл do с i = i - 1 после удаления строки /e: да, я мог бы использовать шаг -1 или написать его по-другому, но хотел показать что-то отличное от других ответов
  2. Также нет необходимости использовать оператор like, он не поддерживается в vbs, поэтому, если вы когда-нибудь решите изучить vbs, рекомендуется избегать этого

Вот мой подход, вы можете продолжать добавлять больше ключевых слов в массив или вместо этого создать коллекцию:

 MyArr = Array("SSI", "Settlement instruction", "delivery Instruction", "Request form", "Sales to onboarding", "Application", "Doc Check list", "Prime to Credit", "Prime to Legal", "Prime_Legal", "Prime_Credit", "LEXIS", "Withdrawal Request")

LastRow = ws.Range("E1").CurrentRegion.Rows.count
i = 1
Do Until i > LastRow
    i = i   1
    cVal = ws.Cells(i, 4).Value
    For Each ma In MyArr
        If InStr(1, cVal, ma) > 0 Then
            ws.Cells(i, 4).EntireRow.Delete
            i = i - 1 'cells below will shift up, so next row will have the same row number
            Exit For
        End If
    Next
Loop