使用VBA在Excel中查找上次使用的单元格时出错

使用VBA在Excel中查找上次使用的单元格时出错,excel,vba,excel-formula,Excel,Vba,Excel Formula,当我想查找上次使用的单元格值时,我使用: Dim LastRow As Long LastRow = Range("E4:E48").End(xlDown).Row Debug.Print LastRow 当我将单个元素放入单元格时,我得到了错误的输出。但当我在单元格中输入多个值时,输出是正确的。 这背后的原因是什么?注意:我打算让这成为一个“一站式帖子”,您可以使用正确的方法找到最后一行。这还将包括查找最后一行时要遵循的最佳实践。因此,每当我遇到新的场景/信息时,我都

当我想查找上次使用的单元格值时,我使用:

Dim LastRow As Long

LastRow = Range("E4:E48").End(xlDown).Row

Debug.Print LastRow
当我将单个元素放入单元格时,我得到了错误的输出。但当我在单元格中输入多个值时,输出是正确的。
这背后的原因是什么?

注意:我打算让这成为一个“一站式帖子”,您可以使用
正确的方法找到最后一行。这还将包括查找最后一行时要遵循的最佳实践。因此,每当我遇到新的场景/信息时,我都会不断更新它


查找最后一行的不可靠方法 查找最后一行的一些最常见的方法非常不可靠,因此不应使用

  • UsedRange
  • xlDown
  • 伯爵
  • UsedRange
    永不使用查找最后一个包含数据的单元格。这是非常不可靠的。试试这个实验

    在单元格
    A5
    中键入内容。现在,当您使用下面给出的任何方法计算最后一行时,它将为您提供5。现在将单元格
    A10
    涂成红色。如果你现在使用下面的任何代码,你仍然会得到5。如果你使用
    Usedrange.Rows.Count
    你会得到什么?不会是5点

    下面是一个演示
    UsedRange
    如何工作的场景

    xlDown
    同样不可靠

    考虑一下这个代码

    lastrow = Range("A1").End(xlDown).Row
    
    如果只有一个单元格(
    A1
    )有数据,会发生什么情况?您将到达工作表中的最后一行!这就像选择单元格
    A1
    ,然后按结束键,然后按向下箭头键一样。如果在某个范围内有空白单元格,这也会导致不可靠的结果

    CountA
    也不可靠,因为如果中间有空白单元格,它将给出不正确的结果

    因此,应避免使用
    UsedRange
    xlDown
    CountA
    查找最后一个单元格


    查找列中的最后一行 要查找列E中的最后一行,请使用

    With Sheets("Sheet1")
        LastRow = .Range("E" & .Rows.Count).End(xlUp).Row
    End With
    
    如果您注意到在
    行之前有一个
    。请计数。我们常常选择忽略这一点。请参阅关于可能出现的错误的问题。我总是建议在
    行.计数
    列.计数之前使用
    。这个问题是一个典型的场景,其中代码将失败,因为对于Excel 2003及更早版本,
    Rows.Count
    返回
    65536
    ,对于Excel 2007及更高版本返回
    1048576
    。类似地,
    Columns.Count
    分别返回
    256
    16384

    Excel 2007+具有
    1048576
    行的上述事实也强调了这样一个事实,即我们应该始终将保存行值的变量声明为
    Long
    ,而不是
    Integer
    ,否则会出现
    溢出
    错误

    请注意,此方法将跳过任何隐藏行。回顾一下,如果第8行被隐藏,这种方法将返回
    5
    ,而不是
    8


    查找工作表中的最后一行 要查找工作表中的
    有效
    最后一行,请使用此选项。注意
    Application.WorksheetFunction.CountA(.Cells)
    的用法。这是必需的,因为如果工作表中没有包含数据的单元格,则
    .Find
    将给出
    运行时错误91:对象变量或未设置块变量

    With Sheets("Sheet1")
        If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
            lastrow = .Cells.Find(What:="*", _
                          After:=.Range("A1"), _
                          Lookat:=xlPart, _
                          LookIn:=xlFormulas, _
                          SearchOrder:=xlByRows, _
                          SearchDirection:=xlPrevious, _
                          MatchCase:=False).Row
        Else
            lastrow = 1
        End If
    End With
    

    对于Siddarth Rout给出的答案,我想补充一点,让Find返回一个范围对象而不是一个行号,可以跳过CountA调用,然后测试返回的范围对象是否为空(空白工作表)


    另外,我会让我版本的任何LastRow过程为空白工作表返回零,这样我就可以知道它是空白的。

    注意:这个答案的动机是。
    UsedRange
    的目的与上述答案中提到的不同。

    至于找到最后使用的单元格的正确方法,首先要确定使用了什么,然后选择合适的方法。我认为至少有三种含义:

  • 使用=非空白,即具有数据

  • Sub LastCellMsg()
        Dim strResult As String
        Dim lngDataRow As Long
        Dim lngDataCol As Long
        Dim strDataCell As String
        Dim strDataFormatRow As String
        Dim lngDataFormatCol As Long
        Dim strDataFormatCell As String
        Dim oFormatCond As FormatCondition
        Dim lngTempRow As Long
        Dim lngTempCol As Long
        Dim lngCFRow As Long
        Dim lngCFCol As Long
        Dim strCFCell As String
        Dim lngOverallRow As Long
        Dim lngOverallCol As Long
        Dim strOverallCell As String
    
        With ActiveSheet
    
            If .ListObjects.Count > 0 Then
                MsgBox "Cannot return reliable results, as there is at least one table in the worksheet."
                Exit Sub
            End If
    
            strResult = "Workbook name: " & .Parent.Name & vbCrLf
            strResult = strResult & "Sheet name: " & .Name & vbCrLf
    
            'DATA:
            'last data row
            If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
                lngDataRow = .Cells.Find(What:="*", _
                 After:=.Range("A1"), _
                 Lookat:=xlPart, _
                 LookIn:=xlFormulas, _
                 SearchOrder:=xlByRows, _
                 SearchDirection:=xlPrevious, _
                 MatchCase:=False).Row
            Else
                lngDataRow = 1
            End If
            'strResult = strResult & "Last data row: " & lngDataRow & vbCrLf
    
            'last data column
            If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
                lngDataCol = .Cells.Find(What:="*", _
                 After:=.Range("A1"), _
                 Lookat:=xlPart, _
                 LookIn:=xlFormulas, _
                 SearchOrder:=xlByColumns, _
                 SearchDirection:=xlPrevious, _
                 MatchCase:=False).Column
            Else
                lngDataCol = 1
            End If
            'strResult = strResult & "Last data column: " & lngDataCol & vbCrLf
    
            'last data cell
            strDataCell = Replace(Cells(lngDataRow, lngDataCol).Address, "$", vbNullString)
            strResult = strResult & "Last data cell: " & strDataCell & vbCrLf
    
            'FORMATS:
            'last data/formatted/grouped/commented/hidden row
            strDataFormatRow = StrReverse(Split(StrReverse(.UsedRange.Address), "$")(0))
            'strResult = strResult & "Last data/formatted row: " & strDataFormatRow & vbCrLf
    
            'last data/formatted/grouped/commented/hidden column
            lngDataFormatCol = Range(StrReverse(Split(StrReverse(.UsedRange.Address), "$")(1)) & "1").Column
            'strResult = strResult & "Last data/formatted column: " & lngDataFormatCol & vbCrLf
    
            'last data/formatted/grouped/commented/hidden cell
            strDataFormatCell = Replace(Cells(strDataFormatRow, lngDataFormatCol).Address, "$", vbNullString)
            strResult = strResult & "Last data/formatted cell: " & strDataFormatCell & vbCrLf
    
            'CONDITIONAL FORMATS:
            For Each oFormatCond In .Cells.FormatConditions
    
                'last conditionally-formatted row
                lngTempRow = CLng(StrReverse(Split(StrReverse(oFormatCond.AppliesTo.Address), "$")(0)))
                If lngTempRow > lngCFRow Then lngCFRow = lngTempRow
    
                'last conditionally-formatted column
                lngTempCol = Range(StrReverse(Split(StrReverse(oFormatCond.AppliesTo.Address), "$")(1)) & "1").Column
                If lngTempCol > lngCFCol Then lngCFCol = lngTempCol
            Next
            'no results are returned for Conditional Format if there is no such
            If lngCFRow <> 0 Then
                'strResult = strResult & "Last cond-formatted row: " & lngCFRow & vbCrLf
                'strResult = strResult & "Last cond-formatted column: " & lngCFCol & vbCrLf
    
                'last conditionally-formatted cell
                strCFCell = Replace(Cells(lngCFRow, lngCFCol).Address, "$", vbNullString)
                strResult = strResult & "Last cond-formatted cell: " & strCFCell & vbCrLf
            End If
    
            'OVERALL:
            lngOverallRow = Application.WorksheetFunction.Max(lngDataRow, strDataFormatRow, lngCFRow)
            'strResult = strResult & "Last overall row: " & lngOverallRow & vbCrLf
            lngOverallCol = Application.WorksheetFunction.Max(lngDataCol, lngDataFormatCol, lngCFCol)
            'strResult = strResult & "Last overall column: " & lngOverallCol & vbCrLf
            strOverallCell = Replace(.Cells(lngOverallRow, lngOverallCol).Address, "$", vbNullString)
            strResult = strResult & "Last overall cell: " & strOverallCell & vbCrLf
    
            MsgBox strResult
            Debug.Print strResult
    
        End With
    
    End Sub
    
  • Used=“…正在使用中,表示包含数据或格式的节” ,这是Excel在保存时使用的标准。另见。 如果没有意识到这一点,标准可能会产生意想不到的结果,但也可能被有意利用(当然不太经常),例如,突出显示或打印最终可能没有数据的特定区域。 当然,这也是保存工作簿时使用范围的标准,以免丢失部分工作

  • Used=“…正在使用中,表示包含数据或格式的节”或条件格式。 与2相同,但也包括作为任何条件格式规则目标的单元格

  • 如何查找上次使用的单元格取决于您想要什么(您的标准)

    Sub LastCellMsg()
        Dim strResult As String
        Dim lngDataRow As Long
        Dim lngDataCol As Long
        Dim strDataCell As String
        Dim strDataFormatRow As String
        Dim lngDataFormatCol As Long
        Dim strDataFormatCell As String
        Dim oFormatCond As FormatCondition
        Dim lngTempRow As Long
        Dim lngTempCol As Long
        Dim lngCFRow As Long
        Dim lngCFCol As Long
        Dim strCFCell As String
        Dim lngOverallRow As Long
        Dim lngOverallCol As Long
        Dim strOverallCell As String
    
        With ActiveSheet
    
            If .ListObjects.Count > 0 Then
                MsgBox "Cannot return reliable results, as there is at least one table in the worksheet."
                Exit Sub
            End If
    
            strResult = "Workbook name: " & .Parent.Name & vbCrLf
            strResult = strResult & "Sheet name: " & .Name & vbCrLf
    
            'DATA:
            'last data row
            If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
                lngDataRow = .Cells.Find(What:="*", _
                 After:=.Range("A1"), _
                 Lookat:=xlPart, _
                 LookIn:=xlFormulas, _
                 SearchOrder:=xlByRows, _
                 SearchDirection:=xlPrevious, _
                 MatchCase:=False).Row
            Else
                lngDataRow = 1
            End If
            'strResult = strResult & "Last data row: " & lngDataRow & vbCrLf
    
            'last data column
            If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
                lngDataCol = .Cells.Find(What:="*", _
                 After:=.Range("A1"), _
                 Lookat:=xlPart, _
                 LookIn:=xlFormulas, _
                 SearchOrder:=xlByColumns, _
                 SearchDirection:=xlPrevious, _
                 MatchCase:=False).Column
            Else
                lngDataCol = 1
            End If
            'strResult = strResult & "Last data column: " & lngDataCol & vbCrLf
    
            'last data cell
            strDataCell = Replace(Cells(lngDataRow, lngDataCol).Address, "$", vbNullString)
            strResult = strResult & "Last data cell: " & strDataCell & vbCrLf
    
            'FORMATS:
            'last data/formatted/grouped/commented/hidden row
            strDataFormatRow = StrReverse(Split(StrReverse(.UsedRange.Address), "$")(0))
            'strResult = strResult & "Last data/formatted row: " & strDataFormatRow & vbCrLf
    
            'last data/formatted/grouped/commented/hidden column
            lngDataFormatCol = Range(StrReverse(Split(StrReverse(.UsedRange.Address), "$")(1)) & "1").Column
            'strResult = strResult & "Last data/formatted column: " & lngDataFormatCol & vbCrLf
    
            'last data/formatted/grouped/commented/hidden cell
            strDataFormatCell = Replace(Cells(strDataFormatRow, lngDataFormatCol).Address, "$", vbNullString)
            strResult = strResult & "Last data/formatted cell: " & strDataFormatCell & vbCrLf
    
            'CONDITIONAL FORMATS:
            For Each oFormatCond In .Cells.FormatConditions
    
                'last conditionally-formatted row
                lngTempRow = CLng(StrReverse(Split(StrReverse(oFormatCond.AppliesTo.Address), "$")(0)))
                If lngTempRow > lngCFRow Then lngCFRow = lngTempRow
    
                'last conditionally-formatted column
                lngTempCol = Range(StrReverse(Split(StrReverse(oFormatCond.AppliesTo.Address), "$")(1)) & "1").Column
                If lngTempCol > lngCFCol Then lngCFCol = lngTempCol
            Next
            'no results are returned for Conditional Format if there is no such
            If lngCFRow <> 0 Then
                'strResult = strResult & "Last cond-formatted row: " & lngCFRow & vbCrLf
                'strResult = strResult & "Last cond-formatted column: " & lngCFCol & vbCrLf
    
                'last conditionally-formatted cell
                strCFCell = Replace(Cells(lngCFRow, lngCFCol).Address, "$", vbNullString)
                strResult = strResult & "Last cond-formatted cell: " & strCFCell & vbCrLf
            End If
    
            'OVERALL:
            lngOverallRow = Application.WorksheetFunction.Max(lngDataRow, strDataFormatRow, lngCFRow)
            'strResult = strResult & "Last overall row: " & lngOverallRow & vbCrLf
            lngOverallCol = Application.WorksheetFunction.Max(lngDataCol, lngDataFormatCol, lngCFCol)
            'strResult = strResult & "Last overall column: " & lngOverallCol & vbCrLf
            strOverallCell = Replace(.Cells(lngOverallRow, lngOverallCol).Address, "$", vbNullString)
            strResult = strResult & "Last overall cell: " & strOverallCell & vbCrLf
    
            MsgBox strResult
            Debug.Print strResult
    
        End With
    
    End Sub
    
    对于标准1,我建议阅读。 请注意,
    UsedRange
    被引用为不可靠。我认为这是误导性的(即对
    UsedRange
    “不公平”),因为
    UsedRange
    并不意味着报告包含数据的最后一个单元格。因此,在这种情况下不应使用它,如该答案所示。另见

    对于标准2,
    UsedRange
    是最可靠的选项,与其他也为此用途设计的选项相比。它甚至不需要保存工作簿以确保最后一个单元格已更新。 Ctrl+End在保存之前将转到错误的单元格 (“保存工作表之前,不会重置最后一个单元格”,从 . 这是一个古老的参考,但在这方面是有效的)

    对于准则3,我不知道任何内置方法。 准则2不考虑条件形式
    Dim LastRow as Long
    
    Private Function FindLastRow(ws As Worksheet) As Long
        ' --------------------------------------------------------------------------------
        ' Find the last used Row on a Worksheet
        ' --------------------------------------------------------------------------------
        If WorksheetFunction.CountA(ws.Cells) > 0 Then
            ' Search for any entry, by searching backwards by Rows.
            FindLastRow = ws.Cells.Find(What:="*", After:=ws.range("a1"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
        End If
    End Function
    
    Function GetLastCell(sh as Worksheet) As Range
        GetLastCell = sh.Cells(1,1).SpecialCells(xlLastCell)
    End Function
    
    sub last_filled_cell()
    msgbox range("A65536").end(xlup).row
    end sub
    
    Sub LastCellMsg()
        Dim strResult As String
        Dim lngDataRow As Long
        Dim lngDataCol As Long
        Dim strDataCell As String
        Dim strDataFormatRow As String
        Dim lngDataFormatCol As Long
        Dim strDataFormatCell As String
        Dim oFormatCond As FormatCondition
        Dim lngTempRow As Long
        Dim lngTempCol As Long
        Dim lngCFRow As Long
        Dim lngCFCol As Long
        Dim strCFCell As String
        Dim lngOverallRow As Long
        Dim lngOverallCol As Long
        Dim strOverallCell As String
    
        With ActiveSheet
    
            If .ListObjects.Count > 0 Then
                MsgBox "Cannot return reliable results, as there is at least one table in the worksheet."
                Exit Sub
            End If
    
            strResult = "Workbook name: " & .Parent.Name & vbCrLf
            strResult = strResult & "Sheet name: " & .Name & vbCrLf
    
            'DATA:
            'last data row
            If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
                lngDataRow = .Cells.Find(What:="*", _
                 After:=.Range("A1"), _
                 Lookat:=xlPart, _
                 LookIn:=xlFormulas, _
                 SearchOrder:=xlByRows, _
                 SearchDirection:=xlPrevious, _
                 MatchCase:=False).Row
            Else
                lngDataRow = 1
            End If
            'strResult = strResult & "Last data row: " & lngDataRow & vbCrLf
    
            'last data column
            If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
                lngDataCol = .Cells.Find(What:="*", _
                 After:=.Range("A1"), _
                 Lookat:=xlPart, _
                 LookIn:=xlFormulas, _
                 SearchOrder:=xlByColumns, _
                 SearchDirection:=xlPrevious, _
                 MatchCase:=False).Column
            Else
                lngDataCol = 1
            End If
            'strResult = strResult & "Last data column: " & lngDataCol & vbCrLf
    
            'last data cell
            strDataCell = Replace(Cells(lngDataRow, lngDataCol).Address, "$", vbNullString)
            strResult = strResult & "Last data cell: " & strDataCell & vbCrLf
    
            'FORMATS:
            'last data/formatted/grouped/commented/hidden row
            strDataFormatRow = StrReverse(Split(StrReverse(.UsedRange.Address), "$")(0))
            'strResult = strResult & "Last data/formatted row: " & strDataFormatRow & vbCrLf
    
            'last data/formatted/grouped/commented/hidden column
            lngDataFormatCol = Range(StrReverse(Split(StrReverse(.UsedRange.Address), "$")(1)) & "1").Column
            'strResult = strResult & "Last data/formatted column: " & lngDataFormatCol & vbCrLf
    
            'last data/formatted/grouped/commented/hidden cell
            strDataFormatCell = Replace(Cells(strDataFormatRow, lngDataFormatCol).Address, "$", vbNullString)
            strResult = strResult & "Last data/formatted cell: " & strDataFormatCell & vbCrLf
    
            'CONDITIONAL FORMATS:
            For Each oFormatCond In .Cells.FormatConditions
    
                'last conditionally-formatted row
                lngTempRow = CLng(StrReverse(Split(StrReverse(oFormatCond.AppliesTo.Address), "$")(0)))
                If lngTempRow > lngCFRow Then lngCFRow = lngTempRow
    
                'last conditionally-formatted column
                lngTempCol = Range(StrReverse(Split(StrReverse(oFormatCond.AppliesTo.Address), "$")(1)) & "1").Column
                If lngTempCol > lngCFCol Then lngCFCol = lngTempCol
            Next
            'no results are returned for Conditional Format if there is no such
            If lngCFRow <> 0 Then
                'strResult = strResult & "Last cond-formatted row: " & lngCFRow & vbCrLf
                'strResult = strResult & "Last cond-formatted column: " & lngCFCol & vbCrLf
    
                'last conditionally-formatted cell
                strCFCell = Replace(Cells(lngCFRow, lngCFCol).Address, "$", vbNullString)
                strResult = strResult & "Last cond-formatted cell: " & strCFCell & vbCrLf
            End If
    
            'OVERALL:
            lngOverallRow = Application.WorksheetFunction.Max(lngDataRow, strDataFormatRow, lngCFRow)
            'strResult = strResult & "Last overall row: " & lngOverallRow & vbCrLf
            lngOverallCol = Application.WorksheetFunction.Max(lngDataCol, lngDataFormatCol, lngCFCol)
            'strResult = strResult & "Last overall column: " & lngOverallCol & vbCrLf
            strOverallCell = Replace(.Cells(lngOverallRow, lngOverallCol).Address, "$", vbNullString)
            strResult = strResult & "Last overall cell: " & strOverallCell & vbCrLf
    
            MsgBox strResult
            Debug.Print strResult
    
        End With
    
    End Sub
    
    If .ListObjects.Count > 0 Then
        MsgBox "Cannot return reliable results, as there is at least one table in the worksheet."
        Exit Sub
    End If
    
    Sub lastRow()
    
        Dim i As Long
            i = Cells(Rows.Count, 1).End(xlUp).Row
                MsgBox i
    
    End Sub
    
    sub LastRow()
    
    'Paste & for better understanding of the working use F8 Key to run the code .
    
    dim WS as worksheet
    dim i as long
    
    set ws = thisworkbook("SheetName")
    
    ws.activate
    
    ws.range("a1").select
    
    ws.range("a1048576").select
    
    activecell.end(xlup).select
    
    i= activecell.row
    
    msgbox "My Last Row Is " & i
    
    End sub
    
    {=ADDRESS(MATCH(INDEX(D:D,MAX(IF(D:D<>"",ROW(D:D)-ROW(D1)+1)),1),D:D,0),COLUMN(D:D))}
    
    Function GetLastCell(sh As Worksheet) As Range
      Set GetLastCell = sh.Cells(1, 1).SpecialCells(xlLastCell)
    End Function
    
    Sub test()
      Dim ws As Worksheet, r As Range
      Set ws = ActiveWorkbook.Sheets("Sheet1")
      Set r = GetLastCell(ws)
      MsgBox r.Column & "-" & r.Row
    End Sub
    
    Function lastCol(Optional wsName As String, Optional rowToCheck As Long = 1) As Long
    
        Dim ws  As Worksheet
    
        If wsName = vbNullString Then
            Set ws = ActiveSheet
        Else
            Set ws = Worksheets(wsName)
        End If
    
        lastCol = ws.Cells(rowToCheck, ws.Columns.Count).End(xlToLeft).Column
    
    End Function
    
    Function lastRow(Optional wsName As String, Optional columnToCheck As Long = 1) As Long
    
        Dim ws As Worksheet
    
        If wsName = vbNullString Then
            Set ws = ActiveSheet
        Else
            Set ws = Worksheets(wsName)
        End If
    
        lastRow = ws.Cells(ws.Rows.Count, columnToCheck).End(xlUp).Row
    
    End Function
    
    Public Function LastRowWithHidden(Optional wsName As String, Optional columnToCheck As Long = 1) As Long
    
        Dim ws As Worksheet
    
        If wsName = vbNullString Then
            Set ws = ActiveSheet
        Else
            Set ws = Worksheets(wsName)
        End If
    
        Dim letters As String
        letters = ColLettersGenerator(columnToCheck)
        LastRowWithHidden = ws.Evaluate("=IFERROR(LOOKUP(2,1/(NOT(ISBLANK(" & letters & "))),ROW(" & letters & " )),0)")
    
    End Function
    
    Function ColLettersGenerator(col As Long) As String
    
        Dim result As Variant
        result = Split(Cells(1, col).Address(True, False), "$")
        ColLettersGenerator = result(0) & ":" & result(0)
    
    End Function
    
    Function LastRowNumber(Optional rng As Range) As Long
    
    If rng Is Nothing Then
        Set rng = ActiveSheet.UsedRange
    Else
        Set rng = Intersect(rng.Parent.UsedRange, rng.EntireColumn)
        If rng Is Nothing Then
            LastRowNumber = 1
            Exit Function
        ElseIf isE = 0 Then
            LastRowNumber = 1
            Exit Function
        
        End If
    
    End If
    
    LastRowNumber = rng.Cells(rng.Rows.Count, 1).Row
    
    Do While IsEmpty(Intersect(rng, _
        rng.Parent.Rows(LastRowNumber)))
    
        LastRowNumber = LastRowNumber - 1
    Loop
    
    End Function
    
    Sub test()
    Dim rng As Range
    Dim Result As Long
    Set rng = Worksheets(1).Range("D4")
    Result = MyLastRow(rng)
    End Sub
    
        Function MyLastRow(FirstRow As Range) As Long
        Dim WS As Worksheet
        Dim TableName As String
        Dim ColNumber As Long
        Dim LastRow As Long
        Dim FirstColumnTable As Long
        Dim ColNumberTable As Long
        Set WS = FirstRow.Worksheet
        TableName = GetTableName(FirstRow)
        ColNumber = FirstRow.Column
        
        ''If the table (ListObject) does not start in column "A" we need to calculate the 
        ''first Column table and how many Columns from its beginning the Column is located.
        If TableName <> vbNullString Then
         FirstColumnTable = WS.ListObjects(TableName).ListColumns(1).Range.Column
         ColNumberTable = ColNumber - FirstColumnTable + 1
        End If 
    
        If TableName = vbNullString Then
        LastRow = WS.Cells(WS.Rows.Count, ColNumber).End(xlUp).Row
        Else
        LastRow = WS.ListObjects(TableName).ListColumns(ColNumberTable).Range.Find( _
                   What:="*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
        End If
        MyLastRow = LastRow
        End Function
        
        ''Get Table Name by Cell Range
        Function GetTableName(CellRange As Range) As String
            If CellRange.ListObject Is Nothing Then
                GetTableName = vbNullString
            Else
                GetTableName = CellRange.ListObject.Name
            End If
        End Function