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

发布于 2025-01-16 15:09:20 字数 201 浏览 7 评论 0 原文

当我想查找最后使用的单元格值时,我使用:

Dim LastRow As Long

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

Debug.Print LastRow

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

When I want to find the last used cell value, I use:

Dim LastRow As Long

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

Debug.Print LastRow

I'm getting the wrong output when I put a single element into a cell. But when I put more than one value into the cell, the output is correct.
What's the reason behind this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

橘和柠 2025-01-23 15:09:20

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


查找最后一行的不可靠方法

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

  1. UsedRange
  2. xlDown
  3. CountA

UsedRange 应该决不用于查找最后一个有数据的单元格。这是非常不可靠的。尝试这个实验。

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

这是一个展示 UsedRange 如何工作的场景。

在此处输入图像描述

xlDown 同样不可靠。

考虑这段代码

lastrow = Range("A1").End(xlDown).Row

如果只有一个单元格 (A1) 有数据,会发生什么情况?您最终将到达工作表中的最后一行!这就像选择单元格A1,然后按End键,然后按向下箭头键。如果范围内存在空白单元格,这也会给您带来不可靠的结果。

CountA 也不可靠,因为如果中间有空白单元格,它会给出错误的结果。

因此,应该避免使用 UsedRangexlDownCountA 来查找最后一个单元格。


查找列中的最后一行

要查找 Col E 中的最后一行,请使用此命令。

With Sheets("Sheet1")
    LastRow = .Range("E" & .Rows.Count).End(xlUp).Row
End With

如果您注意到 Rows.Count 之前有一个 .。我们常常选择忽视这一点。有关您可能遇到的错误,请参阅问题。我总是建议在 Rows.CountColumns.Count 之前使用 .。该问题是一个典型的场景,其中代码将失败,因为 Rows.Count 对于 Excel 2003 及更早版本返回 65536,对于 Excel 2007 和更早版本返回 1048576之后。同样,Columns.Count 分别返回 25616384

上述 Excel 2007+ 有 1048576 行的事实也强调了这样一个事实:我们应该始终将保存行值的变量声明为 Long 而不是 Integer 否则您将收到Overflow 错误。

请注意,此方法将跳过任何隐藏行。回顾一下 我上面 A 列的屏幕截图,如果第 8 行被隐藏,此方法将返回 <代码>5而不是8


查找工作表中的最后一行

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

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

Find Last Row在表 (ListObject) 中也

适用相同的原则,例如获取表第三列中的最后一行:

Sub FindLastRowInExcelTableColAandB()
Dim lastRow As Long
Dim ws As Worksheet, tbl as ListObject
Set ws = Sheets("Sheet1")  'Modify as needed
'Assuming the name of the table is "Table1", modify as needed
Set tbl = ws.ListObjects("Table1")

With tbl.ListColumns(3).Range
    lastrow = .Find(What:="*", _
                After:=.Cells(1), _
                Lookat:=xlPart, _
                LookIn:=xlFormulas, _
                SearchOrder:=xlByRows, _
                SearchDirection:=xlPrevious, _
                MatchCase:=False).Row
End With

End Sub

NOTE: I intend to make this a "one stop post" where you can use the Correct way to find the last row. This will also cover the best practices to follow when finding the last row. And hence I will keep on updating it whenever I come across a new scenario/information.


Unreliable ways of finding the last row

Some of the most common ways of finding last row which are highly unreliable and hence should never be used.

  1. UsedRange
  2. xlDown
  3. CountA

UsedRange should NEVER be used to find the last cell which has data. It is highly unreliable. Try this experiment.

Type something in cell A5. Now when you calculate the last row with any of the methods given below, it will give you 5. Now color the cell A10 red. If you now use the any of the below code, you will still get 5. If you use Usedrange.Rows.Count what do you get? It won't be 5.

Here is a scenario to show how UsedRange works.

enter image description here

xlDown is equally unreliable.

Consider this code

lastrow = Range("A1").End(xlDown).Row

What would happen if there was only one cell (A1) which had data? You will end up reaching the last row in the worksheet! It's like selecting cell A1 and then pressing End key and then pressing Down Arrow key. This will also give you unreliable results if there are blank cells in a range.

CountA is also unreliable because it will give you incorrect result if there are blank cells in between.

And hence one should avoid the use of UsedRange, xlDown and CountA to find the last cell.


Find Last Row in a Column

To find the last Row in Col E use this

With Sheets("Sheet1")
    LastRow = .Range("E" & .Rows.Count).End(xlUp).Row
End With

If you notice that we have a . before Rows.Count. We often chose to ignore that. See THIS question on the possible error that you may get. I always advise using . before Rows.Count and Columns.Count. That question is a classic scenario where the code will fail because the Rows.Count returns 65536 for Excel 2003 and earlier and 1048576 for Excel 2007 and later. Similarly Columns.Count returns 256 and 16384, respectively.

The above fact that Excel 2007+ has 1048576 rows also emphasizes on the fact that we should always declare the variable which will hold the row value as Long instead of Integer else you will get an Overflow error.

Note that this approach will skip any hidden rows. Looking back at my screenshot above for column A, if row 8 were hidden, this approach would return 5 instead of 8.


Find Last Row in a Sheet

To find the Effective last row in the sheet, use this. Notice the use of Application.WorksheetFunction.CountA(.Cells). This is required because if there are no cells with data in the worksheet then .Find will give you Run Time Error 91: Object Variable or With block variable not set

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

Find Last Row in a Table (ListObject)

The same principles apply, for example to get the last row in the third column of a table:

Sub FindLastRowInExcelTableColAandB()
Dim lastRow As Long
Dim ws As Worksheet, tbl as ListObject
Set ws = Sheets("Sheet1")  'Modify as needed
'Assuming the name of the table is "Table1", modify as needed
Set tbl = ws.ListObjects("Table1")

With tbl.ListColumns(3).Range
    lastrow = .Find(What:="*", _
                After:=.Cells(1), _
                Lookat:=xlPart, _
                LookIn:=xlFormulas, _
                SearchOrder:=xlByRows, _
                SearchDirection:=xlPrevious, _
                MatchCase:=False).Row
End With

End Sub
小兔几 2025-01-23 15:09:20

注意:这个答案的动机是

至于找到最后使用的单元格的正确方法,首先要决定考虑什么< em>使用过,然后选择合适的方法。我至少想到了三个含义:

  1. Used=非空白,即有数据

  2. 已使用 =“...正在使用,表示包含数据或格式的部分。”
    根据官方文档,这是Excel在保存时使用的标准。另请参阅此官方文档
    如果没有意识到这一点,该标准可能会产生意想不到的结果,但它也可能被有意利用(当然,不太频繁),例如,突出显示或打印特定区域,这些区域最终可能没有数据。
    当然,最好将其作为保存工作簿时使用的范围的标准,以免丢失部分工作。

  3. Used =“...正在使用,表示包含数据或格式或条件格式的部分。
    与 2. 相同,但还包括作为任何条件格式规则目标的单元格。

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

对于标准 1,我建议阅读此答案
请注意,UsedRange 被认为是不可靠的。我认为这是误导性的(即对 UsedRange 不公平),因为 UsedRange 根本不意味着报告包含数据的最后一个单元格。因此,如该答案所示,在这种情况下不应使用它。另请参阅此评论

对于标准 2,与也为此用途设计的其他选项相比,UsedRange 是最可靠的选项。它甚至不需要保存工作簿来确保更新最后一个单元格。
Ctrl+End 将在保存之前转到错误的单元格
(“在保存工作表之前,最后一个单元格不会重置”,来自
http://msdn.microsoft.com/en -us/library/aa139976%28v=office.10%29.aspx
这是一个古老的参考文献,但在这方面是有效的)。

对于标准 3,我不知道任何内置方法
标准 2 不考虑条件格式。可能有基于公式的格式化单元格,UsedRangeCtrl+End 无法检测到这些单元格。
在图中,最后一个单元格是 B3,因为格式已显式应用于它。单元格 B6:D7 具有源自条件格式规则的格式,即使 UsedRange 也无法检测到这一点。
考虑到这一点需要一些 VBA 编程。

在此处输入图像描述


关于您的具体问题
这背后的原因是什么?

您的代码使用范围 E4:E48 中的第一个单元格作为蹦床,通过 End(xlDown)跳跃 >。

如果您的范围内除了第一个单元格之外没有非空白单元格,则会获得“错误”输出。然后,您在黑暗中跳跃,即沿着工作表向下跳跃
(您应该注意空白空字符串之间的区别!)。

请注意:

  1. 如果您的范围包含不连续的非空白单元格,那么它也会给出错误的结果。

  2. 如果只有一个非空白单元格,但它不是第一个,您的代码仍然会给出正确的结果。

Note: this answer was motivated by this comment. The purpose of UsedRange is different from what is mentioned in the answer above.

As to the correct way of finding the last used cell, one has first to decide what is considered used, and then select a suitable method. I conceive at least three meanings:

  1. Used = non-blank, i.e., having data.

  2. Used = "... in use, meaning the section that contains data or formatting."
    As per official documentation, this is the criterion used by Excel at the time of saving. See also this official documentation.
    If one is not aware of this, the criterion may produce unexpected results, but it may also be intentionally exploited (less often, surely), e.g., to highlight or print specific regions, which may eventually have no data.
    And, of course, it is desirable as a criterion for the range to use when saving a workbook, lest losing part of one's work.

  3. Used = "... in use, meaning the section that contains data or formatting" or conditional formatting.
    Same as 2., but also including cells that are the target for any Conditional Formatting rule.

How to find the last used cell depends on what you want (your criterion).

For criterion 1, I suggest reading this answer.
Note that UsedRange is cited as unreliable. I think that is misleading (i.e., "unfair" to UsedRange), as UsedRange is simply not meant to report the last cell containing data. So it should not be used in this case, as indicated in that answer. See also this comment.

For criterion 2, UsedRange is the most reliable option, as compared to other options also designed for this use. It even makes it unnecessary to save a workbook to make sure that the last cell is updated.
Ctrl+End will go to a wrong cell prior to saving
(“The last cell is not reset until you save the worksheet”, from
http://msdn.microsoft.com/en-us/library/aa139976%28v=office.10%29.aspx.
It is an old reference, but in this respect valid).

For criterion 3, I do not know any built-in method.
Criterion 2 does not account for Conditional Formatting. One may have formatted cells, based on formulas, which are not detected by UsedRange or Ctrl+End.
In the figure, the last cell is B3, since formatting was applied explicitly to it. Cells B6:D7 have a format derived from a Conditional Formatting rule, and this is not detected even by UsedRange.
Accounting for this would require some VBA programming.

enter image description here


As to your specific question:
What's the reason behind this?

Your code uses the first cell in your range E4:E48 as a trampoline, for jumping down with End(xlDown).

The "erroneous" output will obtain if there are no non-blank cells in your range other than perhaps the first. Then, you are leaping in the dark, i.e., down the worksheet
(you should note the difference between blank and empty string!).

Note that:

  1. If your range contains non-contiguous non-blank cells, then it will also give a wrong result.

  2. If there is only one non-blank cell, but it is not the first one, your code will still give you the correct result.

辞取 2025-01-23 15:09:20

我创建了这个一站式函数来确定最后一行、最后一列和单元格,无论是数据、格式化(分组/注释/隐藏)单元格还是条件格式

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

结果如下所示:
确定最后一个单元格

要获得更详细的结果,可以取消注释代码中的某些行:
last column, row

存在一个限制 - 如果工作表中有表格,结果可能会变得不可靠,因此我决定避免在这种情况下运行代码:

If .ListObjects.Count > 0 Then
    MsgBox "Cannot return reliable results, as there is at least one table in the worksheet."
    Exit Sub
End If

I created this one-stop function for determining the last row, column and cell, be it for data, formatted (grouped/commented/hidden) cells or conditional formatting.

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

Results look like this:
determine last cell

For more detailed results, some lines in the code can be uncommented:
last column, row

One limitation exists - if there are tables in the sheet, results can become unreliable, so I decided to avoid running the code in this case:

If .ListObjects.Count > 0 Then
    MsgBox "Cannot return reliable results, as there is at least one table in the worksheet."
    Exit Sub
End If
感情废物 2025-01-23 15:09:20

使用解决方案时要记住的一个重要注意事项......

LastRow = ws.Cells.Find(What:="*", After:=ws.range("a1"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

是确保您的 LastRow 变量是 Long 类型:

Dim LastRow as Long

否则您最终会得到 OVERFLOW .XLSX 工作簿中某些情况下的错误

这是我的封装函数,我将其放入各种代码使用中。

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

One important note to keep in mind when using the solution ...

LastRow = ws.Cells.Find(What:="*", After:=ws.range("a1"), SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row

... is to ensure that your LastRow variable is of Long type:

Dim LastRow as Long

Otherwise you will end up getting OVERFLOW errors in certain situations in .XLSX workbooks

This is my encapsulated function that I drop in to various code uses.

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
如梦 2025-01-23 15:09:20

由于最初的问题是关于查找最后一个单元格的问题在这个答案中我将列出可以获得意外结果的各种方法;请参阅我对“如何使用宏找到 Excel 工作表中包含数据的最后一行?”的回答 我对解决这个问题的看法。

我将首先扩展桑乔的答案。 s 和 GlennFromIowa 的评论,添加了更多详细信息:

[...]首先要决定什么被认为是使用的。我看到至少有6层含义。细胞有:

  • 1) 数据,即公式,可能会产生空白值;
  • 2)一个值,即非空公式或常数;
  • 3)格式化;
  • 4) 条件格式;
  • 5) 与单元格重叠的形状(包括注释);
  • 6) 涉及表(列表对象)。

您想测试哪种组合?有些(例如表格)可能更难以测试,有些可能很少见(例如数据范围之外的形状),但其他可能会根据情况而变化(例如带有空白值的公式)。

您可能需要考虑的其他事项:

  • A) 是否可以有隐藏行(例如自动筛选器)、空白单元格或空白行?
  • B) 什么样的表现是可以接受的?
  • C) VBA 宏是否会以任何方式影响工作簿或应用程序设置?

考虑到这一点,让我们看看获取“最后一个单元格”的常见方法如何产生意想不到的结果:

  • 问题中的.End(xlDown)代码将破坏大多数内容很容易(例如单个非空单元格中间有空白单元格),原因在Siddharth Rout 的答案在这里(搜索 < em>“xlDown 同样不可靠。”)

Since the original question is about problems with finding the last cell, in this answer I will list the various ways you can get unexpected results; see my answer to "How can I find last row that contains data in the Excel sheet with a macro?" for my take on solving this.

I'll start by expanding on the answer by sancho.s and the comment by GlennFromIowa, adding even more detail:

[...] one has first to decide what is considered used. I see at least 6 meanings. Cell has:

  • 1) data, i.e., a formula, possibly resulting in a blank value;
  • 2) a value, i.e., a non-blank formula or constant;
  • 3) formatting;
  • 4) conditional formatting;
  • 5) a shape (including Comment) overlapping the cell;
  • 6) involvement in a Table (List Object).

Which combination do you want to test for? Some (such as Tables) may be more difficult to test for, and some may be rare (such as a shape outside of data range), but others may vary based on the situation (e.g., formulas with blank values).

Other things you might want to consider:

  • A) Can there be hidden rows (e.g. autofilter), blank cells or blank rows?
  • B) What kind of performance is acceptable?
  • C) Can the VBA macro affect the workbook or the application settings in any way?

With that in mind, let's see how the common ways of getting the "last cell" can produce unexpected results:

  • The .End(xlDown) code from the question will break most easily (e.g. with a single non-empty cell or when there are blank cells in between) for the reasons explained in the answer by Siddharth Rout here (search for "xlDown is equally unreliable.") ????
  • Any solution based on Counting (CountA or Cells*.Count) or .CurrentRegion will also break in presence of blank cells or rows ????
  • A solution involving .End(xlUp) to search backwards from the end of a column will, just as CTRL+UP, look for data (formulas producing a blank value are considered "data") in visible rows (so using it with autofilter enabled might produce incorrect results ⚠️).

    You have to take care to avoid the standard pitfalls (for details I'll again refer to the answer by Siddharth Rout here, look for the "Find Last Row in a Column" section), such as hard-coding the last row (Range("A65536").End(xlUp)) instead of relying on sht.Rows.Count.

  • .SpecialCells(xlLastCell) is equivalent to CTRL+END, returning the bottom-most and right-most cell of the "used range", so all caveats that apply to relying on the "used range", apply to this method as well. In addition, the "used range" is only reset when saving the workbook and when accessing worksheet.UsedRange, so xlLastCell might produce stale results⚠️ with unsaved modifications (e.g. after some rows were deleted). See the nearby answer by dotNET.
  • sht.UsedRange (described in detail in the answer by sancho.s here) considers both data and formatting (though not conditional formatting) and resets the "used range" of the worksheet, which may or may not be what you want.

    Note that a common mistake ️is to use .UsedRange.Rows.Count⚠️, which returns the number of rows in the used range, not the last row number (they will be different if the first few rows are blank), for details see newguy's answer to How can I find last row that contains data in the Excel sheet with a macro?

  • .Find allows you to find the last row with any data (including formulas) or a non-blank value in any column. You can choose whether you're interested in formulas or values, but the catch is that it resets the defaults in the Excel's Find dialog ️️⚠️, which can be highly confusing to your users. It also needs to be used carefully, see the answer by Siddharth Rout here (section "Find Last Row in a Sheet")
  • More explicit solutions that check individual Cells' in a loop are generally slower than re-using an Excel function (although can still be performant), but let you specify exactly what you want to find. See my solution based on UsedRange and VBA arrays to find the last cell with data in the given column -- it handles hidden rows, filters, blanks, does not modify the Find defaults and is quite performant.

Whatever solution you pick, be careful

  • to use Long instead of Integer to store the row numbers (to avoid getting Overflow with more than 65k rows) and
  • to always specify the worksheet you're working with (i.e. Dim ws As Worksheet ... ws.Range(...) instead of Range(...))
  • when using .Value (which is a Variant) avoid implicit casts like .Value <> "" as they will fail if the cell contains an error value.
优雅的叶子 2025-01-23 15:09:20

我想知道没有人提到这一点,但获取最后使用的单元格的最简单方法是:

Function GetLastCell(sh as Worksheet) As Range
    GetLastCell = sh.Cells(1,1).SpecialCells(xlLastCell)
End Function

这本质上返回与选择单元格后通过 Ctrl + End 获得的相同单元格A1

警告:Excel 会跟踪工作表中曾经使用过的最右下角的单元格。例如,如果您在 B3 中输入某些内容,在 H8 中输入其他内容,然后删除 H8 的内容,请按 Ctrl + End 仍会将您带到 H8 单元格。上述函数将具有相同的行为。

I wonder that nobody has mentioned this, But the easiest way of getting the last used cell is:

Function GetLastCell(sh as Worksheet) As Range
    GetLastCell = sh.Cells(1,1).SpecialCells(xlLastCell)
End Function

This essentially returns the same cell that you get by Ctrl + End after selecting Cell A1.

A word of caution: Excel keeps track of the most bottom-right cell that was ever used in a worksheet. So if for example you enter something in B3 and something else in H8 and then later on delete the contents of H8, pressing Ctrl + End will still take you to H8 cell. The above function will have the same behavior.

东走西顾 2025-01-23 15:09:20

我想在 Siddarth Rout 给出的答案中添加一点,即可以通过让 Find 返回 Range 对象而不是行号来跳过 CountA 调用,然后测试返回的 Range 对象以查看它是否为 Nothing(空白工作表) 。

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

I would add to the answer given by Siddarth Rout to say that the CountA call can be skipped by having Find return a Range object, instead of a row number, and then test the returned Range object to see if it is Nothing (blank worksheet).

Also, I would have my version of any LastRow procedure return a zero for a blank worksheet, then I can know it is blank.

情深已缘浅 2025-01-23 15:09:20

于 2021 年底更新,

使用 Excel 的新 计算引擎和数组功能,以及 过滤功能,我相信这个现在这个话题的争议应该少得多,并且以下选项提供了速度、可靠性和简单性的最佳组合(正如这里的众多帖子所说明的那样,过去已经证明很难平衡这一点)。

另外,我将最后使用定义为非空白,如isBlank 函数。

Excel 公式

首先,请注意,筛选函数可以更轻松地使用以下公式获取特定行或列的最后一个单元格(在这些情况下为 Column ARow 1):

=MAX(FILTER(ROW(A:A),NOT(ISBLANK(A:A))))
=MAX(FILTER(COLUMN(1:1),NOT(ISBLANK(1:1))))

最后一行特定范围的 VBA 函数

使用上述函数,我们可以将其转换为 VBA 函数,但通过限制范围使其速度更快,同时通过执行多列扩展其功能(感谢 Chris Neilsen 获取即时反馈调整/建议)。我还发现,通过将每一列的范围限定为一个比上一个最后一行更高的行的范围,速度得到了巨大的提高。

Function FindLastRowInRange(someColumns As Range) As Long
Const zFx = "=MAX(FILTER(ROW(????),NOT(ISBLANK(????)),0))"
   
   Dim tRng As Range, i As Long, tRow As Long, pRng As Range
   With someColumns.Worksheet
      Set tRng = Intersect(someColumns.EntireColumn, .UsedRange)
      
      For i = 1 To tRng.Columns.Count
         
         Set pRng = Intersect(tRng.Columns(i), _
         Range(.Rows(FindLastRowInRange + 1), .Rows(.Rows.Count)))
         
         If Not pRng Is Nothing Then
            tRow = .Evaluate(Replace(zFx, "????", _
               pRng.Address, 1, -1))
         
            If tRow > FindLastRowInRange Then _
               FindLastRowInRange = tRow
            
         End If
      Next i
   End With
End Function

工作表中最后一行的 VBA 函数

要考虑整个工作表(所有列),我建议使用引用前一个公式的不同 VBA 公式,但它是一个 易失性函数。这可确保公式随着工作表的任何更改而更新。显然,可以将这两个公式结合起来,但我更喜欢限制易失性函数的使用。

Function FindLastRowInSheet(anywhereInSheet As Range) As Long
      Application.Volatile
      FindLastRowInSheet = FindLastRowInRange(anywhereInSheet.Worksheet.UsedRange)
End Function

与其他选项相比的优点

  • 允许工作表中的部分或全部行/列,而无需更改方法。
  • 不可能像 xlup 那样丢失隐藏行,
  • 忽略格式化/使用范围问题。
  • 不会干扰用户的Find 设置。
  • 使用比 VBA 计算更快的工作表功能。
  • 不计数细胞(性能消耗)。

希望这场辩论就此结束,但如果有人发现其中的弱点,请分享。

Updated at End of 2021

With Excel's new calculation engine and array functionality, and Filter Function, I believe this topic should now be far less contested and that the below options offer the best mix of speed, reliability, and simplicity (which has proven difficult to balance in the past as the numerous posts here illustrate).

Also, I'm defining last used as NOT blank as defined by the isBlank function.

Excel Formula

First, note that the Filter Function makes it much simpler to get a last cell using the below formulas for a specific row or column (in these case Column A or Row 1):

=MAX(FILTER(ROW(A:A),NOT(ISBLANK(A:A))))
=MAX(FILTER(COLUMN(1:1),NOT(ISBLANK(1:1))))

VBA Function For Last Row Specific Range

Using the above function we can convert it into a VBA function, yet make it even faster by limiting the range, while expanding its capabilities by doing multiple columns (thanks to Chris Neilsen for immediate feedback tweeking/suggestions). I also found massive speed improvement by scoping each column to only be a range with a row HIGHER than the previous last row.

Function FindLastRowInRange(someColumns As Range) As Long
Const zFx = "=MAX(FILTER(ROW(????),NOT(ISBLANK(????)),0))"
   
   Dim tRng As Range, i As Long, tRow As Long, pRng As Range
   With someColumns.Worksheet
      Set tRng = Intersect(someColumns.EntireColumn, .UsedRange)
      
      For i = 1 To tRng.Columns.Count
         
         Set pRng = Intersect(tRng.Columns(i), _
         Range(.Rows(FindLastRowInRange + 1), .Rows(.Rows.Count)))
         
         If Not pRng Is Nothing Then
            tRow = .Evaluate(Replace(zFx, "????", _
               pRng.Address, 1, -1))
         
            If tRow > FindLastRowInRange Then _
               FindLastRowInRange = tRow
            
         End If
      Next i
   End With
End Function

VBA Function For Last Row In Worksheet

To consider the entire worksheet (all columns), I would recommend using a different VBA formula that references the prior one, but is a Volatile Function. This ensures that the formula updates with any changes to a worksheet. Obviously, one could combine these two formulas, but I prefer to limit the usage of volatile functions.

Function FindLastRowInSheet(anywhereInSheet As Range) As Long
      Application.Volatile
      FindLastRowInSheet = FindLastRowInRange(anywhereInSheet.Worksheet.UsedRange)
End Function

Advantages Compared To Other Options

  • Allows for some or ALL rows/columns in worksheet without changing approach.
  • No possibility of missing hidden rows as is a risk with xlup
  • Ignores formatted/usedrange issues.
  • Does not interfere with user's Find settings.
  • Uses worksheet functionality which is faster than VBA calcs.
  • No counting cells (performance hog).

Hopefully this ends the debate, but if anyone finds weaknesses in this please share.

海螺姑娘 2025-01-23 15:09:20

我一直在寻找一种模仿 CTRL+Shift+End 的方法,所以 dotNET 解决方案很棒,除了我的 Excel 2010 需要如果我想避免错误,请添加 set

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

I was looking for a way to mimic the CTRL+Shift+End, so dotNET solution is great, except with my Excel 2010 I need to add a set if I want to avoid an error:

Function GetLastCell(sh As Worksheet) As Range
  Set GetLastCell = sh.Cells(1, 1).SpecialCells(xlLastCell)
End Function

and how to check this for yourself:

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
短暂陪伴 2025-01-23 15:09:20
sub last_filled_cell()
msgbox range("A65536").end(xlup).row
end sub

这里,A65536 是 A 列中的最后一个单元格,此代码在 Excel 2003 上进行了测试。

sub last_filled_cell()
msgbox range("A65536").end(xlup).row
end sub

Here, A65536 is the last cell in the Column A this code was tested on excel 2003.

盗心人 2025-01-23 15:09:20

然而,这个问题正在寻求使用 VBA 查找最后一行,我认为最好包含工作表函数的数组公式,因为它会被频繁访问:

{=ADDRESS(MATCH(INDEX(D:D,MAX(IF(D:D<>"",ROW(D:D)-ROW(D1)+1)),1),D:D,0),COLUMN(D:D))}

您需要输入不带括号的公式,然后按 Shift + Ctrl + Enter 使其成为数组公式。

这将为您提供 D 列中最后使用的单元格的地址。


感谢 pgsystemtester,这将为您提供最后使用的单元格的行号:

{=MATCH(INDEX(D:D,MAX(IF(D:D<>"",ROW(D:D)-ROW(D1)+1)),1),D:D,0)}

However this question is seeking to find the last row using VBA, I think it would be good to include an array formula for worksheet function as this gets visited frequently:

{=ADDRESS(MATCH(INDEX(D:D,MAX(IF(D:D<>"",ROW(D:D)-ROW(D1)+1)),1),D:D,0),COLUMN(D:D))}

You need to enter the formula without brackets and then hit Shift + Ctrl + Enter to make it an array formula.

This will give you address of last used cell in the column D.


Thanks to pgsystemtester, this will give you the row number of last used cell:

{=MATCH(INDEX(D:D,MAX(IF(D:D<>"",ROW(D:D)-ROW(D1)+1)),1),D:D,0)}
热鲨 2025-01-23 15:09:20
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
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
偏爱你一生 2025-01-23 15:09:20

在过去的 3 年多里,这些是我用来查找每个定义的列(对于行)和行(对于列)的最后一行和最后一列的函数:

最后一列:

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

对于 OP 的情况,这是获取E列最后一行的方法:

Debug.Print lastRow(columnToCheck:=Range("E4:E48").Column)

Last Row,计算空行有数据:

在这里我们可以使用 众所周知的 Excel 公式,它为我们提供了 Excel 中工作表的最后一行,而不涉及 VBA - =IFERROR(LOOKUP(2,1/(NOT(ISBLANK(A:A))),ROW(A:A)),0)

为了将其放入 VBA 中而不是编写任何内容在 Excel 中,使用后一个函数的参数,可以考虑这样的事情:

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

For the last 3+ years these are the functions that I am using for finding last row and last column per defined column(for row) and row(for column):

Last Column:

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

Last Row:

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

For the case of the OP, this is the way to get the last row in column E:

Debug.Print lastRow(columnToCheck:=Range("E4:E48").Column)

Last Row, counting empty rows with data:

Here we may use the well-known Excel formulas, which give us the last row of a worksheet in Excel, without involving VBA - =IFERROR(LOOKUP(2,1/(NOT(ISBLANK(A:A))),ROW(A:A)),0)

In order to put this in VBA and not to write anything in Excel, using the parameters for the latter functions, something like this could be in mind:

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
对你的占有欲 2025-01-23 15:09:20

常规范围或表(列表对象)中的最后一行

  1. 如果范围是常规范围或表(列表对象),则查找最后一行需要使用不同的方法。
  2. 查找表中的最后一行需要指定其他参数(表名称、列相对于表第一个列的位置)。

无论范围类型如何,我都为最后一行创建了这个通用函数。只要给它任何单元格引用,它就会返回最后一行。
不必知道范围特征,特别是如果您的范围有时是常规范围,有时是 ListObject,则没有麻烦。
在表上使用常规范围方法可能会返回错误的结果。
当然,您可以提前计划并每次都使用正确的方法,但如果您可以利用通用功能,为什么还要麻烦呢?

Sub RunMyLastRow()
结果暗淡只要
结果 = MyLastRow(工作表(1).Range("A1"))
结束子
    Function MyLastRow(RefrenceRange 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 = RefrenceRange.Worksheet
    TableName = GetTableName(RefrenceRange)
    ColNumber = RefrenceRange.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
    
 ''通过单元格范围获取表名称
    函数 GetTableName(RefrenceRange As Range) As String
        如果RefrenceRange.ListObject什么都没有那么
            获取表名称 = vbNullString
        别的
            GetTableName = RefrenceRange.ListObject.Name
        结束如果
    结束功能

Last Row in a regular range or a Table (ListObject)

  1. Finding the last row requires using different methods if the range is a regular range or table (List Object).
  2. Finding the last row in tables requires specifying additional parameters (table name , the column relative position to the first tables column).

I created this universal function for last row, regardless of range type. Just give it any cell reference whatsoever and it will return the last row.
No hassle having to knew range characteristics, especially if your ranges are some times a regular range and sometimes a ListObject.
Using a regular range method on a table might return wrong results.
Sure you can plan ahead of time and use the right method each time, but why bother if you can utilizes a universal function ?

Sub RunMyLastRow()
Dim Result As Long
Result = MyLastRow(Worksheets(1).Range("A1"))
End Sub
    Function MyLastRow(RefrenceRange 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 = RefrenceRange.Worksheet
    TableName = GetTableName(RefrenceRange)
    ColNumber = RefrenceRange.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(RefrenceRange As Range) As String
        If RefrenceRange.ListObject Is Nothing Then
            GetTableName = vbNullString
        Else
            GetTableName = RefrenceRange.ListObject.Name
        End If
    End Function
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文