Problem with finding last row with filtered rows

VBAExcellNoob

Board Regular
Joined
Feb 13, 2015
Messages
117
Hi guys,

I'm currently having a problem with finding the last row of a column that has filtered data in it.
If the last row in the filtered data isn't the last row of the unfiltered data set my code does not work properly. I've included some screen shots of the data as I can't explain it very well.

In the first image the data has been filtered for the 30/01/2015 and it calculates the correct amount of pass and fail and stores it after the last row in the column.

YBlCjHv.png


In the second image I have filtered the data for the 23/01/2015, however as you can see it does not display the pass/fail rate. It is reading in row 236 as the last row instead of row 248.
iVyvjDk.png


Here is the 3rd image showing what is going on when the wrong last row is selected
NNfmqPF.png


Here is the code I have written as well:

Code:
Private Sub CommandButton4_Click()
'Filters to a user inputted date
Dim i As Integer
Dim j As Integer


myDate = InputBox("Please enter date in the FORMAT MM/DD/20YY")


i = Worksheets.count


For j = 2 To i
With Sheets(j)


.Range("$A$1:$AU$247").AutoFilter Field:=42, Criteria1:=">=" & Format(myDate, "mm/dd/yyyy"), _
Operator:=xlAnd, Criteria2:="<=" & Format(myDate, "mm/dd/yyyy")


End With
Next j
End Sub


Private Sub CommandButton2_Click()
'Counts the number of Pass and Fail
Dim lastRow As Long
Dim ws As Worksheet
Dim rng As Range
Dim rng2 As Range
Dim countPass As Integer
Dim countFail As Integer
Dim total As Integer
Dim totalPass As Double
Dim totalFail As Double


Set ws = Worksheets("Absence")


lastRow = ws.UsedRange.SpecialCells(xlCellTypeLastCell).Row
Set rng = ws.Range("AT2:AT" & lastRow)
Set rng2 = ws.Range("AP2:AP" & lastRow)


ws.Range("AT" & Rows.count).End(xlUp)(3).Font.Bold = True
ws.Range("AU" & Rows.count).End(xlUp)(3).Font.Bold = True


ws.Range("AT" & Rows.count).End(xlUp)(3) = "Pass"
ws.Range("AU" & Rows.count).End(xlUp)(3) = "Fail"


countPass = Application.WorksheetFunction.CountIfs(rng, "Pass", rng2, myDate)
countFail = Application.WorksheetFunction.CountIfs(rng, "Fail", rng2, myDate)


total = countPass + countFail
totalPass = countPass / total
totalFail = countFail / total


ws.Range("AT" & Rows.count).End(xlUp)(2) = countPass
ws.Range("AU" & Rows.count).End(xlUp)(2) = countFail
ws.Range("AT" & Rows.count).End(xlUp)(2) = FormatPercent(totalPass)
ws.Range("AU" & Rows.count).End(xlUp)(2) = FormatPercent(totalFail)




End Sub

Sorry for the long post but I have been having trouble with this all day. Any help at all would be much appreciated!
 

Excel Facts

Can you sort left to right?
To sort left-to-right, use the Sort dialog box. Click Options. Choose "Sort left to right"
You already know the last used row from this....
lastRow = ws.UsedRange.SpecialCells(xlCellTypeLastCell).Row

You could use that row number (it should be 247 based on your example) to paste the results.
ws.Range("AT" & lastRow + 3) = "Pass"
ws.Range("AU" & lastRow + 3) = "Fail"


Or this could work as well to count the rows of the autofilter range...
ws.Range("AT" & ws.AutoFilter.Range.Rows.Count + 3) = "Pass"
ws.Range("AU" & ws.AutoFilter.Range.Rows.Count + 3) = "Fail"
 
Last edited:
Upvote 0
You already know the last used row from this....
lastRow = ws.UsedRange.SpecialCells(xlCellTypeLastCell).Row

You could use that row number (it should be 247 based on your example) to paste the results.
ws.Range("AT" & lastRow + 3) = "Pass"
ws.Range("AU" & lastRow + 3) = "Fail"

I tried that but it is still entering the data 3 rows after row 235 instead of row 247
 
Upvote 0
Or this could work as well to count the rows of the autofilter range...
ws.Range("AT" & ws.AutoFilter.Range.Rows.Count + 3) = "Pass"
ws.Range("AU" & ws.AutoFilter.Range.Rows.Count + 3) = "Fail"
 
Upvote 0
You already know the last used row from this....
lastRow = ws.UsedRange.SpecialCells(xlCellTypeLastCell).Row

You could use that row number (it should be 247 based on your example) to paste the results.
ws.Range("AT" & lastRow + 3) = "Pass"
ws.Range("AU" & lastRow + 3) = "Fail"


Or this could work as well to count the rows of the autofilter range...
ws.Range("AT" & ws.AutoFilter.Range.Rows.Count + 3) = "Pass"
ws.Range("AU" & ws.AutoFilter.Range.Rows.Count + 3) = "Fail"

The second solution you gave me worked, thanks! Do you know why the other solution didn't work though? I'm new to VBA so I'm trying to understand things as I learn them. This problem was puzzling me for a long time today.
 
Upvote 0
Here are two UDF's (user defined functions) that I have posted in the past, one gets the top visible row in a filtered range and the other (the one you want) gets the bottom visible row in a filtered range...
Code:
Function GetFilteredRangeTopRow() As Long
  Dim HeaderRow As Long, LastFilterRow As Long
  On Error GoTo NoFilterOnSheet
  With ActiveSheet
    HeaderRow = .AutoFilter.Range(1).Row
    LastFilterRow = .Range(Split(.AutoFilter.Range.Address, ":")(1)).Row
    GetFilteredRangeTopRow = .Range(.Rows(HeaderRow + 1), .Rows(Rows.Count)). _
                                    SpecialCells(xlCellTypeVisible)(1).Row
    If GetFilteredRangeTopRow = LastFilterRow + 1 Then GetFilteredRangeTopRow = 0
  End With
NoFilterOnSheet:
End Function

Function GetFilteredRangeBottomRow() As Long
  Dim HeaderRow As Long, LastFilterRow As Long, Addresses() As String
  On Error GoTo NoFilterOnSheet
  With ActiveSheet
    HeaderRow = .AutoFilter.Range(1).Row
    LastFilterRow = .Range(Split(.AutoFilter.Range.Address, ":")(1)).Row
    Addresses = Split(.Range((HeaderRow + 1) & ":" & LastFilterRow). _
                      SpecialCells(xlCellTypeVisible).Address, "$")
    GetFilteredRangeBottomRow = Addresses(UBound(Addresses))
  End With
NoFilterOnSheet:
End Function
 
Upvote 0
The second solution you gave me worked, thanks! Do you know why the other solution didn't work though? I'm new to VBA so I'm trying to understand things as I learn them. This problem was puzzling me for a long time today.

You're welcome.

What is the value of LastRow in the code? I'm not sure why the 1st solution didn't work. That method (.SpecialCells(xlCellTypeLastCell)) can give inaccurate results if you have deleted rows and didn't re-save the file. If that happened, the row count is usually larger than what you want (it's the rows count before you deleted rows). So maybe the results where pasted well below row 248?
 
Upvote 0
You're welcome.

What is the value of LastRow in the code? I'm not sure why the 1st solution didn't work. That method (.SpecialCells(xlCellTypeLastCell)) can give inaccurate results if you have deleted rows and didn't re-save the file. If that happened, the row count is usually larger than what you want (it's the rows count before you deleted rows). So maybe the results where pasted well below row 248?

lastRow returned 247 on the unfiltered data, it returned 235 when I filtered by the 23/01/2015
Is there an alternative to (.SpecialCells(xlCellTypeLastCell)) I could use that wouldn't give inaccurate results?
Thanks for taking the time to answer my questions, sorry for replying with more questions!
 
Upvote 0
lastRow returned 247 on the unfiltered data, it returned 235 when I filtered by the 23/01/2015

Well I just learned something new too.


Is there an alternative to (.SpecialCells(xlCellTypeLastCell)) I could use that wouldn't give inaccurate results?
Thanks for taking the time to answer my questions, sorry for replying with more questions!

There are several methods to find the last row. Each has it's own advantages\disadvantages. Some respect filter\visible rows and others don't. I already gave one alternative. If you do a web search for something like Excel Last used row, you will find other methods.

Here's another method but it's column specific.
lastRow = Application.Match(9.99999999999999E+307, ws.Range("A:A"), 0)
 
Upvote 0
lastRow returned 247 on the unfiltered data, it returned 235 when I filtered by the 23/01/2015
Is there an alternative to (.SpecialCells(xlCellTypeLastCell)) I could use that wouldn't give inaccurate results?
Thanks for taking the time to answer my questions, sorry for replying with more questions!

I am wondering if you saw the code I posted in Message #6 and whether it does what you want or not?
 
Upvote 0

Forum statistics

Threads
1,225,725
Messages
6,186,646
Members
453,367
Latest member
bookiiemonster

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