Home » excel » excel vba – Get reference to next visible cell in autofiltered table

excel vba – Get reference to next visible cell in autofiltered table

Posted by: admin May 14, 2020 Leave a comment

Questions:

I have a UserForm that sits on top of my spreadsheet and simply displays information from the row containing the currently selected cell. Buttons on the form allow the user to move up/down the spreadsheet row by row. For example, when the “next record” button is clicked, the code executed is something like:

Cells(ActiveCell.Row + 1, ActiveCell.Column).Select
LoadValues

I would like it to work even if the user filters the data and then loads the form. However, using the above code, it wants to loop through all cells, not just the ones still visible after filtering. I’ve seen solutions for immediately looping through only visible cells, e.g.,

For Each viscell In rng.SpecialCells(xlCellTypeVisible)
    ...
Next viscell

So there seems like there should be a better, more direct way to do this than looping through all rows until I get to the next one with .Hidden = False but I can’t seem to figure out how to get a reference to “the next visible cell” in order to select it.

Any pointers would be greatly appreciated. Thanks.

How to&Answers:

I really struggled with this too and used Ryan’s solution, albeit a little abbreviated, for my purposes..
This may be as brief as it gets. 🙂

ActiveCell.EntireColumn.SpecialCells(xlCellTypeVisible).Find(What:="*", After:=ActiveCell).Activate

Answer:

Here is one method using a simple loop until the next row down is visible.

Dim rng As Range
Set rng = ActiveCell

Dim n As Long: n = 1

Do Until rng.Offset(n, 1).Rows.Hidden = False
    n = n + 1
Loop

rng.Offset(n, 1).Select
LoadValues

Answer:

Here’s a lightning-quick way to activate the first not-blank, visible cell in a filtered range. Just change ‘Range(“A1”)’ to whatever range you’d like to search after. Also consider whether you want xlByColumns or xlByRows.

ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Find(What:="*", _
    After:=ActiveSheet.Range("A1"), LookIn:=xlFormulas, lookat:=xlPart, searchorder:=xlByColumns, _
    SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate

I recommend using tables whenever possible, as they have variable named ranges built-in that are easy to reference.

Here’s another example, using tables. It’s targeted to search a specific column, so it’ll be even faster.

Just find and replace TABLE_NAME and COLUMN_NAME with your values.

ActiveSheet.Range("TABLE_NAME[[#All], COLUMN_NAME]]").SpecialCells(xlCellTypeVisible).Find _
    (What:="*", After:=ActiveSheet.Range("TABLE_NAME[[#Headers],[COLUMN_NAME]]"), _
    LookIn:=xlFormulas, lookat:=xlPart, searchorder:=xlByColumns, SearchDirection:=xlNext, _
    MatchCase:=False, SearchFormat:=False).Activate

No loops required because it’s built off of Excel’s “Find” functionality.

And just a tip,you can also use this to grab the data of such a cell on separate worksheet without activating/selecting it at all.

Just find and replace Dbl_EXAMPLE, SHEET_NAME, TABLE_NAME and COLUMN_NAME with your references.

Dim Dbl_EXAMPLE as Double

Dbl_EXAMPLE = Sheets("SHEET_NAME").Range("TABLE_NAME[[#All], COLUMN_NAME]]").SpecialCells(xlCellTypeVisible).Find _
    (What:="*", After:=Sheets("SHEET_NAME").Range("TABLE_NAME[[#Headers],[COLUMN_NAME]]"), _
    LookIn:=xlFormulas, lookat:=xlPart, searchorder:=xlByColumns, SearchDirection:=xlNext, _
    MatchCase:=False, SearchFormat:=False).Value2

Just replace “.Value2” at the end with whatever property you’re looking for.

Examples:

.Formula
.Row
.Column

The list goes on