Получить последнюю строку из отфильтрованного диапазона

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

    ...
    With ws
        LR = .Range("A" & Rows.Count).End(xlUp).Row
        .Range("A1:E" & LR).AutoFilter Field:=2, Criteria1:="=4"
        LRfilt = .Range("A" & Rows.SpecialCells(xlCellTypeVisible).Count).End(xlUp).Row
        Debug.Print LR
        Debug.Print LRfilt
    End With
    ...

Файл можно найти здесь:

wikisend.com/download/443370/FindLRFilteredData.xls

Изменить:

После обсуждения с Сиддхартом я понял, что мне не нужно свойство Last Row, которое мне нужно для подсчета количества видимых строк, которые привели к решению Сида ниже ...


person Alistair Weir    schedule 25.09.2012    source источник


Ответы (5)


РЕДАКТИРОВАТЬ: сообщение после чата

Option Explicit

Sub FilterTest()
    Dim rRange As Range, fltrdRng As Range, aCell As Range, rngToCopy As Range
    Dim ws As Worksheet
    Dim LR As Long

    '~~> Change this to the relevant sheet
    For Each ws In ThisWorkbook.Worksheets
        If Not ws.Name = "Sheet1" Then
            With ws                    
                '~~> Remove any filters
                .AutoFilterMode = False

                LR = .Range("A" & Rows.Count).End(xlUp).Row

                '~~> Change this to the relevant range
                Set rRange = .Range("A1:E" & LR)

                With rRange
                    '~~> Some Filter. Change as applicable
                    .AutoFilter Field:=2, Criteria1:=">10"

                    '~~> Get the filtered range
                    Set fltrdRng = .SpecialCells(xlCellTypeVisible)
                End With

                For Each aCell In fltrdRng
                    If aCell.Column = 1 Then
                        If rngToCopy Is Nothing Then
                            Set rngToCopy = aCell
                        Else
                            Set rngToCopy = Union(rngToCopy, aCell)
                        End If
                    End If
                Next

                Debug.Print ws.Name
                Debug.Print rngToCopy.Address

                'rngToCopy.Copy

                Set rngToCopy = Nothing

                '~~> Remove any filters
                .AutoFilterMode = False
            End With
        End If
    Next
End Sub
person Siddharth Rout    schedule 25.09.2012
comment
Хм, это дает тот же результат, что и вышеупомянутый метод. Я использую цикл для нескольких листов, но протестировал его на одном листе и получил тот же результат. Не уверен, что происходит, могу я отправить вам файл? - person Alistair Weir; 26.09.2012
comment
да. вы можете загрузить файл на www.wikisend.com и поделиться ссылкой в ​​своем вопросе. - person Siddharth Rout; 26.09.2012
comment
Это дает мне правильные результаты. Test Sheet A Lastrow: 11 и Test Sheet B Lastrow: 1 Я что-то упускаю - person Siddharth Rout; 26.09.2012
comment
Test Sheet A Должен ли фильтрованный LR не быть 8, поскольку 3 строки скрыты? - person Alistair Weir; 26.09.2012
comment
Я думаю, вы путаете реальную последнюю строку и количество видимых строк? - person Siddharth Rout; 26.09.2012
comment
Это может быть проблема с терминологией? Когда я говорю Last Row, я полагаю, что технически имею в виду количество видимых строк. - person Alistair Weir; 26.09.2012
comment
позвольте нам продолжить это обсуждение в чате - person Alistair Weir; 26.09.2012

После фильтра с использованием той же формулы для последней строки будет возвращена последняя отфильтрованная строка:

...
With ws
    LR = .Range("A" & Rows.Count).End(xlUp).Row
    .Range("A1:E" & LR).AutoFilter Field:=2, Criteria1:="=4"
    LRfilt =  .Range("A" & Rows.Count).End(xlUp).Row
    Debug.Print LR
    Debug.Print LRfilt
End With
...
person nutsch    schedule 25.09.2012
comment
Был уверен, что я это проверил! Должно быть, я пытаюсь все усложнить. - person Alistair Weir; 26.09.2012
comment
Хорошо, проверил это на работе, и он не работает. LRFilt по-прежнему совпадает с LR. Сильно запутался, потому что я использую Excel 2007 дома, а разница только W7 дома и XP в офисе. @Siddharth, ты можешь восстановить свой ответ? - person Alistair Weir; 26.09.2012

Предполагая, что ваши данные уже отфильтрованы, вы можете попробовать следующее:

Range("A1").Select

Dim FinalRowFiltered as Long

Dim FR as as String

FinalRowFiltered = Range("A" & Rows.Count).End(xlUp).Row

FR = "A" & CStr(FinalRowFiltered)

Range(FR).Select
person GvMLux    schedule 14.05.2021

Кажется, это работает. Когда фильтры находятся в обычном порядке .end (xlUp) дает последнюю строку отфильтрованного диапазона, но не последнюю строку листа. Я предлагаю вам использовать эту технику, чтобы получить последнюю строку:

Sub GetLastRow
    '   Find last row regardless of filter
    If Not (ActiveSheet.AutoFilterMode) Then        ' see if filtering is on if already on don't turn it on    
        Rows(1).Select                            ' Select top row to filter on
        Selection.AutoFilter                      ' Turn on filtering
    End if           
    b = Split(ActiveSheet.AutoFilter.Range.Address, "$") ' Split the Address range into an array based on "$" as a delimiter.  The address would yeild something like $A$1:$H$100
    LastRow= Val(b(4))   '  The last value of the array will be "100" so find the value 
End sub
person Peter M-B    schedule 27.04.2016

Это простейшее решение

...
        With ws
            .Range("A1:E1").AutoFilter Field:=2, Criteria1:="=4"
             LRfilt=.Range("A1", .Range("A1").End(xlDown)).End(xlDown).Row
             Debug.Print LRfilt
        End With
        ...
person user3466047    schedule 15.04.2014
comment
Это неверно в соответствии с измененным вопросом, и в любом случае это точно такой же ответ в Nutch's - person Alistair Weir; 15.04.2014