Количество строк на основе отфильтрованных данных

#excel #vba #function #count

#excel #vba

Вопрос:

Я использую приведенный ниже код, чтобы получить количество отфильтрованных строк данных в VBA, но при получении количества отображается ошибка времени выполнения:

«Требуется объект».

Не могли бы некоторые сообщить мне, какие изменения необходимы?

 Set rnData = .UsedRange

With rnData
    .AutoFilter Field:=327, Criteria1:=Mid(provarr(q), 1, 2)
    .Select
    .AutoFilter Field:=328, Criteria1:=Mid(provarr(q), 3, 7)
    .Select
    .AutoFilter Field:=330, Criteria1:=Mid(provarr(q), 10, 2)
    .Select
    .AutoFilter Field:=331, Criteria1:=Mid(provarr(q), 12, 2)
    .Select

     Rowz = .AutoFilter.Range.SpecialCells(xlCellTypeVisible).Rows.count

     ....
End With
  

Ответ №1:

Если вы попытаетесь подсчитать количество строк в уже автоматически отфильтрованном диапазоне следующим образом:

 Rowz = rnData.SpecialCells(xlCellTypeVisible).Rows.Count
  

Будет учитываться только количество строк в первой непрерывной видимой области автоматически отфильтрованного диапазона. Например, если диапазон автофильтра составляет строки с 1 по 10, а строки 3, 5, 6, 7 и 9 отфильтрованы, видны четыре строки (строки 2, 4, 8 и 10), но оно вернет 2, потому что первый непрерывный видимый диапазон — это строки 1 (строка заголовка) и 2.

Более точной альтернативой является это (при условии, что ws содержит рабочий лист с отфильтрованными данными):

 Rowz = ws.AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible).Cells.Count - 1
  

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

Cells Свойство предоставит вам точное количество, даже если диапазон имеет несколько областей, в отличие от Rows свойства. Итак, мы просто берем первый столбец диапазона автофильтра и подсчитываем количество видимых ячеек.

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

1. Спасибо за ваш ответ. Я использую Excel 2007. в приведенном выше коде отображается сообщение об ошибке как «Объект не поддерживает это свойство или метод».

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

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

4. Решение «ячейки» — это то, что я искал. Спасибо 🙂

5. Спасибо за дополнительную информацию о свойстве «Ячейки против строк», я использую их годами, и это объясняет некоторые повторяющиеся проблемы.

Ответ №2:

Просто поместите это в свой код:

 Application.WorksheetFunction.Subtotal(3, Range("A2:A500000"))
  

Убедитесь, что вы применяете правильный диапазон, но только для ОДНОГО столбца

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

1. Идеальный. Решения, упомянутые выше, могут давать неправильные результаты в случае пустых строк в таблице и т. Д. Это работает как шарм 🙂

2. Для тех, кому потребуется его просмотреть, первый параметр указывает используемую агрегатную функцию; 3 — это «CountA», представляющее собой количество ячеек в столбце, которые не являются пустыми.

Ответ №3:

Хотя я согласен с приведенными результатами, они не сработали для меня. Если у вашей таблицы есть имя, это сработает:

 Public Sub GetCountOfResults(WorkSheetName As String, TableName As String)
    Dim rnData As Range
    Dim rngArea As Range
    Dim lCount As Long
        Set rnData = ThisWorkbook.Worksheets(WorkSheetName).ListObjects(TableName).Range
    With rnData
        For Each rngArea In .SpecialCells(xlCellTypeVisible).Areas
            lCount = lCount   rngArea.Rows.Count
        Next
        MsgBox "Autofilter " amp; lCount - 1 amp; " records"
    End With
    Set rnData = Nothing
    lCount = Empty      
End Sub
  

Это изменено для работы с ListObjects из оригинальной версии, которую я нашел здесь:

http://www.ozgrid.com/forum/showthread.php?t=81858

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

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

Ответ №4:

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

 Application.WorksheetFunction.Subtotal(2, .Range("A2:A" amp; .Rows(.Rows.Count).End(xlUp).Row))
  

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

Надеюсь, это поможет какому-нибудь другому путнику Сети, такому как я.

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

1. Правильно. Вы должны считать в обратном направлении

2. метод промежуточного итога 2 — «COUNT», он просто подсчитывает количество ячеек, содержащих числа

Ответ №5:

Я нашел способ сделать это, для чего требуется 2 шага, но это работает

 ' to copy out a filtered selection into a different sheet


number_of_dinosaurs = WorksheetFunction.Count(Worksheets("Dinosaurs").Range("A2", "A3000"))

With Worksheets("Dinosaurs")
    .AutoFilterMode = False
    With .Range("$A$4:$E$" amp; number_of_dinosaurs)
        .AutoFilter Field:=2, Criteria1:="*teeth*" ' change your criteria to whatever you like
        .SpecialCells(xlCellTypeVisible).Copy Destination:=Worksheets("Bad_Dinosaurs").Range("A1")
    End With
End With


' then do a normal count on the secondary sheet  

number_of_dinosaurs_that_eat_humans = WorksheetFunction.Count(Worksheets("Bad_Dinosaurs").Range("A2", "A30000"))
  

Ответ №6:

 Rowz = Application.WorksheetFunction.Subtotal(2, Range("A2:A" amp; Rows(Rows.Count).End(xlUp).Row))
  

Ответ №7:

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

Ответ №8:

 Rowz = Application.WorksheetFunction.Subtotal(2, Range("A2:A" amp; Rows(Rows.Count).End(xlUp).Row))
  

Это сработало для меня довольно хорошо