Find First Visible Filtered Row (Sub vs. Function)

Keifffer

New Member
Joined
Apr 23, 2011
Messages
2
Greetings,

Here's my goal: Pull the value of the first visible cell in Col B (visible after a filter has been applied), to use as a title/legend/label on a chart which updates itself as the filter is changed.
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:eek:ffice:eek:ffice" /><o:p></o:p>
My preference is to create a user defined function, rather than a Sub macro, as the UDF will automatically update itself, where I would have to capture some event to trigger the VBA. I’m using Excel 2003.
<o:p></o:p>
So I tried both ways with unexpected results. In my example, the first visible row is 4 (excluding the header) after filtering Col B on “Large”.
<o:p></o:p>
1 SIZE<o:p></o:p>
2 Small<o:p></o:p>
3 Medium<o:p></o:p>
4 Large
<o:p></o:p>
Code:
[FONT=Arial]Sub FirstVisibleRow()<o:p></o:p>[/FONT]
[FONT=Arial]  FirstVisibleRowNumber = ActiveSheet.AutoFilter.Range.Offset(1, 0).SpecialCells(xlCellTypeVisible).Cells(1, 2).Row<o:p></o:p>[/FONT]
[FONT=Arial]End Sub[/FONT]
<o:p></o:p>
The subroutine returns the value FirstVisibleRowNumber = 4, as desired.
<o:p></o:p>
<o:p></o:p>
Code:
[FONT=Arial]Function First_Visible_Row()<o:p></o:p>[/FONT]
[FONT=Arial]  First_Visible_Row = ActiveSheet.AutoFilter.Range.Offset(1, 0).SpecialCells(xlCellTypeVisible).Cells(1, 2).Row<o:p></o:p>[/FONT]
[FONT=Arial]End Function [/FONT]
<o:p></o:p>
The function returns the value First_Visible_Row = 2, which is its “apparent” row number when filtered, but I want to be able to pull the contents of Cells(First_Visible_Row, 2) -- i.e. Row 4. Surprisingly, as I step through the code in the Function, the watched value of First_Visible_Row is actually 4, until the End Function line is executed, and my cell containing the UDF reports a value of 2.
<o:p></o:p>
I even tried having the UDF call the Sub, with the same result.
<o:p></o:p>
I expect I’m missing some pretty fundamental behavior of UDFs. Thanks in advance for the help.
<o:p></o:p>
May God bless you all this Easter.
<o:p></o:p>
Keifffer
 

Excel Facts

Control Word Wrap
Press Alt+Enter to move to a new row in a cell. Lets you control where the words wrap.
Greetings,

Here's my goal: Pull the value of the first visible cell in Col B (visible after a filter has been applied), to use as a title/legend/label on a chart which updates itself as the filter is changed.
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:eek:ffice:eek:ffice" /><o:p></o:p>
My preference is to create a user defined function, rather than a Sub macro, as the UDF will automatically update itself, where I would have to capture some event to trigger the VBA. I’m using Excel 2003.
<o:p></o:p>
So I tried both ways with unexpected results. In my example, the first visible row is 4 (excluding the header) after filtering Col B on “Large”.
<o:p></o:p>
1 SIZE<o:p></o:p>
2 Small<o:p></o:p>
3 Medium<o:p></o:p>
4 Large
<o:p></o:p>
Code:
[FONT=Arial]Sub FirstVisibleRow()<o:p></o:p>[/FONT]
[FONT=Arial] FirstVisibleRowNumber = ActiveSheet.AutoFilter.Range.Offset(1, 0).SpecialCells(xlCellTypeVisible).Cells(1, 2).Row<o:p></o:p>[/FONT]
[FONT=Arial]End Sub[/FONT]
<o:p></o:p>
The subroutine returns the value FirstVisibleRowNumber = 4, as desired.
<o:p></o:p>
<o:p></o:p>
Code:
[FONT=Arial]Function First_Visible_Row()<o:p></o:p>[/FONT]
[FONT=Arial] First_Visible_Row = ActiveSheet.AutoFilter.Range.Offset(1, 0).SpecialCells(xlCellTypeVisible).Cells(1, 2).Row<o:p></o:p>[/FONT]
[FONT=Arial]End Function [/FONT]
<o:p></o:p>
The function returns the value First_Visible_Row = 2, which is its “apparent” row number when filtered, but I want to be able to pull the contents of Cells(First_Visible_Row, 2) -- i.e. Row 4. Surprisingly, as I step through the code in the Function, the watched value of First_Visible_Row is actually 4, until the End Function line is executed, and my cell containing the UDF reports a value of 2.
<o:p></o:p>
I even tried having the UDF call the Sub, with the same result.
<o:p></o:p>
I expect I’m missing some pretty fundamental behavior of UDFs. Thanks in advance for the help.
<o:p></o:p>
May God bless you all this Easter.
<o:p></o:p>
Keifffer
You can do this with a regular worksheet formula. Interested in that?
 
Upvote 0
Hi,

This formula would give you the desired result.

=INDEX(B2:B100,MATCH(1,SUBTOTAL(3,OFFSET(B2:B100,ROW(B2:B100)-ROW($B$2),,1)),0))

Confirmed with CTRL + SHIFT + ENTER

HTH
 
Upvote 0
If you prefer an UDF, may be..

Code:
Function FirstVisibleValue(ByRef Sht As Worksheet, ByVal FilterCol As Long)
    Dim r As Range
    
    If Sht.AutoFilterMode Then
        Set r = Sht.AutoFilter.Range
        FirstVisibleRow = r.Offset(1, FilterCol - 1).Resize(r.Rows.Count, 1).SpecialCells(12).Cells(1)
    End If
    
End Function

and call

Code:
MsgBox FirstVisibleValue(ActiveSheet, 2)

HTH
 
Upvote 0
Kris,

1. Formula using INDEX: Very elegant--thanks! I had originally tried something similar, but my sheet has about 50,000 rows, and so it slowed to an unusable crawl. This is very slick.

2. [Minor typo in your UDF: "FirstVisibleRow = " should read "FirstVisibleValue = "]

Your example re-highlights my original question. When I call your UDF, it gives the correct value. However, if I insert the UDF into Cell G1, it incorrectly returns the value in row 2 (which is filtered invisible).

So the question is from my original post is, why does the line...

Code:
FirstVisibleRowNumber = ActiveSheet.AutoFilter.Range.Offset(1, 0).SpecialCells(xlCellTypeVisible).Cells(1, 2).Row
...within a subroutine work, but the line...

Code:
First_Visible_Row = ActiveSheet.AutoFilter.Range.Offset(1, 0).SpecialCells(xlCellTypeVisible).Cells(1, 2).Row

...within a function, inserted into a cell, produce an inaccurate result? I'm stumped!

Biff: If your regular worksheet formula isn't the same as Kris', then yes I'm interested.

Thanks to all,

Keifffer
 
Upvote 0

Forum statistics

Threads
1,214,584
Messages
6,120,385
Members
448,956
Latest member
JPav

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top