Last row in a column

tiredofit

Well-known Member
Joined
Apr 11, 2013
Messages
1,832
Office Version
  1. 365
  2. 2019
Platform
  1. Windows
I have this function which calculates the last row in a column of a particular worksheet:

Rich (BB code):
Public Function LRowInCol(ByRef wks As Worksheet, ByRef Col As Integer) As Long
    
    With wks
    
        LRowInCol = .Cells(.Rows.Count, Col).End(xlUp).Row
    
    End With
    
End Function

so if I put a value in cell E10 and then write in the immediate window:

Rich (BB code):
? LRowInCol(Sheet1, 5)

I get 10 returned, which is correct.

Assume now I put a value in cell E1048676, ie the last row in column E.

This still returns 10:

Rich (BB code):
Rich (BB code):
Rich (BB code):
? LRowInCol(Sheet1, 5)

it's as if it ignores the "real" last row and returns the next one, which is the row of the value in cell E10.

What is wrong with function?

Thanks
 

Excel Facts

Fastest way to copy a worksheet?
Hold down the Ctrl key while dragging tab for Sheet1 to the right. Excel will make a copy of the worksheet.
The code is the equivalent of selecting the last cell in the column and then pressing Ctrl+up arrow. It never actually checks to see if the last cell in the column is populated.
 
Upvote 0
That's the corner case that's not covered. You could do this:

Code:
Public Function LRowInCol(ByRef wks As Worksheet, ByRef Col As Integer) As Long
    
    With wks
        If .Cells(.Rows.Count, Col).Value <> "" Then
            LRowInCol = .Rows.Count
        Else
            LRowInCol = .Cells(.Rows.Count, Col).End(xlUp).Row
        End If
    End With
    
End Function

WBD
 
Upvote 0
Most of us never encounter a situation where the last row of a post-xl2003 worksheet is used so we find the last used row in the way your function does. But for completeness to include the possibility that the real last row is the last row on the sheet you can write your function like this:
Code:
Public Function LRowInCol(ByRef wks As Worksheet, ByRef Col As Integer) As Long
    With wks
        If IsEmpty(.Cells(.Rows.Count, Col)) Then
            LRowInCol = .Cells(.Rows.Count, Col).End(xlUp).Row
        Else
            LRowInCol = .Rows.Count
        End If
    End With
End Function
 
Upvote 0
In addition to the code JoeMo posted, here is another way to write your function...
Code:
[table="width: 500"]
[tr]
	[td]Public Function LRowInCol(ByRef wks As Variant, ByRef Col As Variant) As Long
  On Error GoTo NothingInColumn
  If TypeName(wks) = "String" Then Set wks = Sheets(wks)
  With wks
    LRowInCol = Columns(Col).Find("*", , xlValues, , xlRows, xlPrevious, , , False).Row
  End With
NothingInColumn:
End Function
[/td]
[/tr]
[/table]
Three things to note with my function...

1) You can specify the worksheet as a worksheet object or by its name as a quoted string

2) You can specify the Col by its number or its letter designation.

3) If the column has no values in any of its cells, the function returns 0.
 
Upvote 0
On a similar note, I have this function to return the last row and it DOES work:

Code:
Public Function LRow(ByRef wks As Worksheet) As Long
    On Error GoTo Correction
        With wks
        
            LRow = .Cells.Find(What:="*", _
                               After:=.Cells(Rows.Count, Columns.Count), _
                               SearchDirection:=xlPrevious, _
                               SearchOrder:=xlByRows).Row
            
        End With
    
        GoTo Exitpoint
    
Correction:
        LRow = 1
Exitpoint:
    On Error GoTo 0
End Function

so I adapted it for columns as follows but it fails:

Code:
Public Function LCol(ByRef wks As Worksheet) As Long
    On Error GoTo Correction
        With wks
        
            LCol = .Cells.Find(What:="*", _
                               After:=.Cells(Rows.Count, Columns.Count), _
                               SearchDirection:=xlPrevious, _
                               SearchOrder:=xlByColumns).Column
            
        End With
    
        GoTo Exitpoint
    
Correction:
        LCol = 1
Exitpoint:
    On Error GoTo 0
End Function

in that if I put a value in cell E1048675, it returns 5 (ie column E) but if there's also a value in cell H1048676, it still returns 5.

Given the LRow function works, why does this fail?


 
Last edited:
Upvote 0
In addition to the code JoeMo posted, here is another way to write your function...
Code:
[TABLE="width: 500"]
<tbody>[TR]
[TD]Public Function LRowInCol(ByRef wks As Variant, ByRef Col As Variant) As Long
  On Error GoTo NothingInColumn
  If TypeName(wks) = "String" Then Set wks = Sheets(wks)
  With wks
    LRowInCol = Columns(Col).Find("*", , [COLOR=#ff0000][B]xlValues[/B][/COLOR], , xlRows, xlPrevious, , , False).Row
  End With
NothingInColumn:
End Function
[/TD]
[/TR]
</tbody>[/TABLE]
Three things to note with my function...

1) You can specify the worksheet as a worksheet object or by its name as a quoted string

2) You can specify the Col by its number or its letter designation.

3) If the column has no values in any of its cells, the function returns 0.
Rick, your function will not pick up a formula in the last row that returns "". That can be fixed by changing xlValues to xlFormulas.
 
Upvote 0
Rick, your function will not pick up a formula in the last row that returns "". That can be fixed by changing xlValues to xlFormulas.
:oops: I copied/modified the wrong code line from my storehouse of routines I have posted in the past.

Thanks for catching that.
 
Last edited:
Upvote 0
On a similar note, I have this function to return the last row and it DOES work:

Code:
Public Function LRow(ByRef wks As Worksheet) As Long
    On Error GoTo Correction
        With wks
        
            LRow = .Cells.Find(What:="*", _
                               After:=.Cells(Rows.Count, Columns.Count), _
                               SearchDirection:=xlPrevious, _
                               SearchOrder:=xlByRows).Row
            
        End With
    
        GoTo Exitpoint
    
Correction:
        LRow = 1
Exitpoint:
    On Error GoTo 0
End Function

so I adapted it for columns as follows but it fails:

Code:
Public Function LCol(ByRef wks As Worksheet) As Long
    On Error GoTo Correction
        With wks
        
            LCol = .Cells.Find(What:="*", _
                               After:=.Cells(Rows.Count, Columns.Count), _
                               SearchDirection:=xlPrevious, _
                               SearchOrder:=xlByColumns).Column
            
        End With
    
        GoTo Exitpoint
    
Correction:
        LCol = 1
Exitpoint:
    On Error GoTo 0
End Function

in that if I put a value in cell E1048675, it returns 5 (ie column E) but if there's also a value in cell H1048676, it still returns 5.

Given the LRow function works, why does this fail?


Works fine for me when there's something in E1048675 and H1048675, returning 8.
 
Upvote 0

Forum statistics

Threads
1,214,641
Messages
6,120,695
Members
448,979
Latest member
DET4492

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