400 Ошибка Макроса Excel

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

Sub deleteRows()
    Dim count As Integer
    count = Application.WorksheetFunction.CountA(Range("AF:AF"))
    Dim i As Integer
    i = 21
    Do While i <= count
        If (Application.WorksheetFunction.IsNumber(Application.WorksheetFunction.Search("OSR Platform", Range("B" & i))) = False) Then
            If (Application.WorksheetFunction.IsNumber(Application.WorksheetFunction.Search("IAM", Range("B" & i))) = False) Then
                Rows(i).EntireRow.Delete
                i = i - 1
                count = count - 1
            End If
        End If
        i = i + 1
    Loop
End Sub

теперь он должен делать следующее:

1.) Найти количество строк, чтобы пройти и установить, что как count (это работает)

2.) Начните с строки 21 и найдите "OSR Platform" и "IAM" в столбце B [этот вид работ (см. ниже)]

3.) Если он не находит ни того, ни другого, удалите всю строку и отрегулируйте граф и номер строки по мере необходимости (это работает)

по какой-то причине, когда код попадает в первый оператор If, появляется окно ошибки с красным X, которое просто говорит "400."Насколько я могу судить, я все написал синтаксически грамотно, но явно что-то не так.

2 ответов


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

For i = count To 21 Step -1

кроме того, вы слишком полагаетесь на Application.WorksheetFunction:

(Application.WorksheetFunction.IsNumber(Application.WorksheetFunction.Search("OSR Platform", Range("B" & i))) = False)

to

InStr(Range("B" & i).value, "OSR Platform") > 0

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

код count также можно получить без A.WF:

  • Excel 2000/03:count = Range("AF65536").End(xlUp).Row
  • Excel 2007/10:count = Range("AF1048576").End(xlUp).Row
  • независимого версии: count = Range("AF" & Rows.Count).End(xlUp).Row

еще одна вещь что вы можете сделать (и должны сделать в этом случае) объединить If заявления в одно.

сделать эти изменения, вы в конечном итоге с:

Sub deleteRows()
    Dim count As Integer
    count = Range("AF" & Rows.Count).End(xlUp).Row
    Dim i As Integer
    For i = count To 21 Step -1
        If Len(Range("B" & i).value) > 0 Then
            If InStr(Range("B" & i).value, "OSR Platform") > 0 Or InStr(Range("B" & i).value, "IAM") > 0 Then
                Range("B" & i).Interior.Color = RGB(255, 0, 0)
            End If
        End If
    Next i
End Sub

если это не поможет, то вы можете шаг за шагом через строку кода. Добавьте точку останова и выполните шаг с ф8. Выделите переменные в коде, щелкните правой кнопкой мыши, выберите "Добавить часы"...", нажмите кнопку "OK", (вот отличный ресурс, который поможет вам с отладкой в генерал!--50-->) и обратите внимание на следующее:

  • какая строка попадает в ошибку?
  • каково значение i и count когда это произойдет? (добавьте часы на эти переменные, чтобы помочь)

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

Sub DeleteRows()

Dim currentSheet As Excel.Worksheet
Dim rngfilter As Excel.Range
Dim lastrow As Long, lastcolumn As Long

Set currentSheet = ActiveSheet

' get range
lastrow = currentSheet.Cells(Excel.Rows.Count, "AF").End(xlUp).Row
lastcolumn = currentSheet.Cells(1, Excel.Columns.Count).End(xlToLeft).Column
Set rngfilter = currentSheet.Range("A1", currentSheet.Cells(lastrow, lastcolumn))

' filter by column B criteria
rngfilter.AutoFilter Field:=2, Criteria1:="<>*OSR Platform*", Operator:= _
        xlAnd, Criteria2:="<>*IAM*"

' delete any visible row greater than row 21 which does not meet above criteria
rngfilter.Offset(21).SpecialCells(xlCellTypeVisible).EntireRow.Delete

' remove autofilter arrows
currentSheet.AutoFilterMode = False
End Sub

этот код применяет автофильтр к столбцу B, чтобы увидеть, какие строки не содержат ни "OSR Platform", ни" IAM " в столбце B. Затем он просто удаляет оставшиеся строки больше 21. Сначала проверьте его на копии книги.

С огромным кивком этот OzGrid thread, потому что я никогда не могу вспомнить правильный синтаксис для выбора видимых ячеек после фильтрующий.