6

I have tried to define a lastrow code that would return the last row value of the last non empty cell in a excel table. (ITS FORMATTED AS A TABLE)

My exceltable have values in COL A from 1 to 1005, COL B from 1 to 414 and in COL C from 414 to 1005.

What i want is to have one lastrow code that returns 414 and one that returns 1005. The problem i get is that because it is in a table. my codes

        lastrow3 = ThisWorkbook.Worksheets("DataÖnskemål").Range("A" & Rows.Count).End(xlUp).Row
        lastrow2 = ThisWorkbook.Worksheets("DataÖnskemål").Range("B" & Rows.Count).End(xlUp).Row

Both return 1005. Can i get around this with my table or is it a formating issue of some sort?

Best regards and thanks in advance /D

DL1
  • 201
  • 2
  • 5
  • 14
  • What is the name of your `Table` ? – Shai Rado Apr 26 '17 at 10:55
  • Can I ask why you would need to know different "last" rows for a table? If the two columns aren't related, they should really be separate tables. – Rory Apr 26 '17 at 11:00
  • You could loop through the rows in column B, from 1 to lastrow of column A, to find the first row that is blank by either evaluating = "" or using an iferror(1/cell) – Luuklag Apr 26 '17 at 11:22
  • Tempted to close as duplicate of [this](http://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-vba) but it didn't specifically address a Table. The same principles do apply, as @sktneer answers below, though. – David Zemens Apr 26 '17 at 12:12

6 Answers6

13

You will have issue if there is data below the excel table on the sheet. It's always better to refer the table column while finding the last row in an excel table.

Sub FindLastRowInExcelTableColAandB()
Dim lastRow1 As Long, lastRow2 As Long
Dim ws As Worksheet
Set ws = Sheets("DataÖnskemål")
'Assuming the name of the table is "Table1"
lastRow1 = ws.ListObjects("Table1").Range.Columns(1).Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
lastRow2 = ws.ListObjects("Table1").Range.Columns(2).Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
End Sub
Subodh Tiwari sktneer
  • 9,906
  • 2
  • 18
  • 22
3

Finding last rows of tables is a bit fiddly, especially as you often need to cater for the case that a user has filtered the data. A loop with multiple checks might suit you better as you can adjust it to your own needs for the data within the table.

You also don't mention whether you can be certain that the last row is indeed a table.

In view of these points, perhaps the .Find function will suit you as it will find any non-empty cell whether in a table or not and whether hidden or not (though it doesn't cope with a filtered table). (It's not quite true to say "any non-empty cell", as a null string, for example, wouldn't be picked up, but maybe these exceptions won't trouble you). Anyhow your code could be:

With Sheet1
    lastRow1 = .Columns(1).Find(What:="*", _
                                After:=.Columns(1).Cells(1), _
                                LookAt:=xlPart, _
                                LookIn:=xlFormulas, _
                                SearchOrder:=xlByRows, _
                                SearchDirection:=xlPrevious, _
                                MatchCase:=False).Row

    lastRow2 = .Columns(2).Find(What:="*", _
                                After:=.Columns(2).Cells(1), _
                                LookAt:=xlPart, _
                                LookIn:=xlFormulas, _
                                SearchOrder:=xlByRows, _
                                SearchDirection:=xlPrevious, _
                                MatchCase:=False).Row
End With
Ambie
  • 4,872
  • 2
  • 12
  • 26
  • The case of the user filtering the data is fairly easily handled by making sure filters are cleared before doing anything. – Selkie Nov 14 '17 at 21:57
1

Try the code below to get the last row in Column A and Column B from a Table (ListObject):

Option Explicit

Sub LastRowTable()

Dim Tbl As ListObject
Dim LastRow2  As Long, LastRow3 As Long

' modify "Table1" to your table's Name
Set Tbl = ThisWorkbook.Worksheets("DataÖnskemål").ListObjects("Table1")

LastRow3 = Tbl.ListColumns(1).Range.Rows.Count '<-- last row in Column A in your Table
LastRow2 = Tbl.ListColumns(2).Range(LastRow3, 1).End(xlUp).Row '<-- last row  with data in Column B in your Table

End Sub
Shai Rado
  • 33,032
  • 6
  • 29
  • 51
  • 3
    Listcolumns in the same table will always have the same number of rows. – Rory Apr 26 '17 at 11:13
  • 1
    `Tbl.ListColumns(1).Range.Rows.Count` represents the row count but not the last row (except for the case that the table starts in row 1 of the sheet). – Pᴇʜ Apr 26 '17 at 11:22
  • `Range(LastRow3, 1)` looks invalid. Did you mean `Cells`? – BigBen Jul 27 '23 at 13:30
1

I was searching for a similar answer, and ending up coming up with an alternative solution to what's been provided. I found it efficient in test cases. Try this case:

Dim loTable As ListObject
Dim lngRowLast1 As Long
Dim lngRowLast2 As Long

'Set reference to your specific table
Set loTable = ThisWorkbook.Sheets(1).ListObjects("Table1")
With loTable
    'I use the following as a catch in case the table is empty
    If .DataBodyRange Is Nothing Then 
        .ListRows.Add
        lngRowLast1 = 1
        lngRowLast2 = 1
    Else
        lngRowLast1 = .DataBodyRange.Cells(.ListRows.Count, 1).End(xlUp).Row
        lngRowLast2 = .DataBodyRange.Cells(.ListRows.Count, 2).End(xlUp).Row
    End If
End With

What I believe is occurring is that the End command within the worksheet will always stop at the last row of the table body, regardless if there is content in that row or not. Instead by using the End(xlUp) command from within the DataBodyRange, that then behaves as you're expecting to find the last used row.

I'm also swapping your reference from Range to Cell since I find it easier to pass in variables for the column reference.

m_zardos
  • 35
  • 6
0

I use this

'Last Row Table Column
Function LRTC(shtName As String, ColIdx As Long)
Dim ws As Worksheet
Dim x As Long, LR As Long, CN As Long

  Set ws = ThisWorkbook.Sheets(shtName)
  LR = ws.Range("A1").End(xlDown).row

  For x = LR To 1 Step -1
    If ws.Cells(x, ColIdx ).value <> "" Then
      LRTC = x
      Exit Function
    End If
  Next x

End Function
Einarr
  • 214
  • 2
  • 14
-3

try this

 Dim DataRange As Range

Set DataRange = Range("A1:M" & LastRow)
shakespeare
  • 126
  • 11