简体   繁体   English

查找范围内的最后一行

[英]Find last row in range

I'm having a little trouble with finding the last row.我在查找最后一行时遇到了一些麻烦。

What I am trying to do is find the last row in column "A", then use that to find the last row within a range.我想要做的是找到“A”列中的最后一行,然后使用它来查找范围内的最后一行。

Example of Data:数据示例:

数据示例

 1) LR_wbSelect = wbshtSelect.cells(Rows.count, "A").End(xlUp).Row - 22

 2) LR_wbSelectNew = wbshtSelect.cells(LR_wbSelect, "A").End(xlUp).Row

I am using the last row in column "A" as the data from row 29 down will always be the same length, the rows used in column "B" from row 29 can be a varying number of rows.我使用“A”列中的最后一行,因为从第 29 行向下的数据将始终具有相同的长度,第 29 行“B”列中使用的行可以是不同的行数。

So I am trying to use LR_wbSelect in column "A" to get my starting last Row, then within LR_wbSelectNew using it as the starting point to look up from.所以我试图在“A”列中使用LR_wbSelect来获取我的起始最后LR_wbSelectNew ,然后在LR_wbSelectNew使用它作为查找的起点。

This works when the column I set to "A", LR_wbSelectNew gives me the row of "17", but when I change the column in LR_wbSelectNew to "B" it doesn't give the correct last row of "18".当我设置为“A”的列时,这有效, LR_wbSelectNew为我提供了“17”行,但是当我将LR_wbSelectNew的列LR_wbSelectNew为“B”时,它没有给出正确的最后一行“18”。

I can change the column to "C, D, E, F" and the code works fine, but the only column that I can use is "B" because it will always have data in it, where the rest of that row could have a blank cell.我可以将列更改为“C、D、E、F”并且代码工作正常,但我可以使用的唯一列是“B”,因为它始终包含数据,而该行的其余部分可能有一个空白单元格。

After doing some testing on the sheet, by pressing CRTL & Up from the lastring point of LR_wbSelect column "B" ignores the data in the rows and go to the row where it find data.在对工作表进行一些测试后,通过从LR_wbSelect列“B”的最后一个点按 CRTL & Up 忽略行中的数据并转到查找数据的行。 I can't see a reason why Excel doesn't think there is data in these cells?我看不出 Excel 认为这些单元格中没有数据的原因?

There are mulitple results and methods when searching for the LastRow (in Column B).搜索 LastRow(在 B 列中)时有多种结果和方法。

When using Cells(.Rows.Count, "B").End(xlUp).Row you will get the last row with data in Column B (it ignores rows with spaces, and goes all the way down).使用Cells(.Rows.Count, "B").End(xlUp).Row您将获得 B 列中包含数据的最后一行(它忽略带有空格的行,并一直向下)。

When using:使用时:

 With wbshtSelect.Range("B10").CurrentRegion
     LR_wbSelectNew = .Rows(.Rows.Count).Row
 End With

You are searching for the last row with data in Column B of the CurrentRegion , that starts from cell B10, untill the first line without data (it stops on the first row with empty row).您正在搜索CurrentRegion B 列中包含数据的最后一行,该行从单元格 B10 开始,直到没有数据的第一行(它停止在具有空行的第一行)。

Full Code:完整代码:

Sub GetLastRow()

Dim wbshtSelect         As Worksheet
Dim LR_wbSelectNew      As Long

' modify "Sheet2" to your sheet's name
Set wbshtSelect = Sheets("Sheet2")

' find last row with data in Column B
With wbshtSelect
    LR_wbSelectNew = .Cells(.Rows.Count, "B").End(xlUp).Row
End With
' for debug only
Debug.Print LR_wbSelectNew ' >>result 31

' find last row with data in Column B at current regioun starting at cell B10
With wbshtSelect.Range("B10").CurrentRegion
    LR_wbSelectNew = .Rows(.Rows.Count).Row
End With
' for debug only
Debug.Print LR_wbSelectNew ' >> result 18

End Sub

Edit1 : code searches for last row for cells with values (it ignores blank cells with formulas inside). Edit1 :代码搜索具有值的单元格的最后一行(它忽略内部带有公式的空白单元格)。

Sub GetLastRow()

Dim wbshtSelect         As Worksheet
Dim LR_wbSelectNew      As Long

' modify "Sheet2" to your sheet's name
Set wbshtSelect = Sheets("Sheet2")

' find last row with data in Column B at current regioun starting at cell B10
With wbshtSelect.Range("B10").CurrentRegion
    LR_wbSelectNew = .Rows(.Rows.Count).Row
End With

Dim Rng         As Range    
Set Rng = wbshtSelect.Range("B10:B" & LR_wbSelectNew)

' find last row inside the range, ignore values inside formulas
LR_wbSelectNew = Rng.Find(What:="*", _
                    After:=Range("B10"), _
                    LookAt:=xlPart, _
                    LookIn:=xlValues, _
                    SearchOrder:=xlByRows, _
                    SearchDirection:=xlPrevious, _
                    MatchCase:=False).Row

' for debug
Debug.Print LR_wbSelectNew  ' << result 18 (with formulas in the range)

End Sub

Hope this piece of code helps !希望这段代码有帮助!

Sub LastRowInOneColumn()
'Find the last used row in a Column: column A in this example
    Dim LastRow As Long
    With ActiveSheet
        LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With
    MsgBox LastRow
End Sub

I came here looking for a way to find the last row in a non-contiguous range.我来这里是为了寻找一种在非连续范围内找到最后一行的方法。 Most responses here only check one column at a time so I created a few different functions to solve this problem.这里的大多数回复一次只检查一列,所以我创建了几个不同的函数来解决这个问题。 I will admit, though, that my .Find() implementation is essentially the same as Shai Rado's answer.不过,我承认,我的.Find()实现与 Shai Rado 的回答基本相同。

Implementation 1 - Uses Range().Find() in reverse order实现 1 - 以相反的顺序使用Range().Find()

Function LastRowInRange_Find(ByVal rng As Range) As Long

    'searches range from bottom up stopping when it finds anything (*)
    Dim rngFind As Range
    Set rngFind = rng.Find( What:="*", _
                            After:=Cells(rng.row, rng.Column), _
                            LookAt:=xlWhole, _
                            LookIn:=xlValues, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlPrevious)

    If Not rngFind Is Nothing Then
        LastRowInRange_Find = rngFind.row
    Else
        LastRowInRange_Find = rng.row
    End If

End Function

Implementation 2 - Uses Range().End(xlUp) on each column实现 2 - 在每列上使用Range().End(xlUp)

Function LastRowInRange_xlUp(ByVal rng As Range) As Long

    Dim lastRowCurrent As Long
    Dim lastRowBest As Long

    'loop through columns in range
    Dim i As Long
    For i = rng.Column To rng.Column + rng.Columns.count - 1
        If rng.Rows.count < Rows.count Then
            lastRowCurrent = Cells(rng.row + rng.Rows.count, i).End(xlUp).row
        Else
            lastRowCurrent = Cells(rng.Rows.count, i).End(xlUp).row
        End If

        If lastRowCurrent > lastRowBest Then
            lastRowBest = lastRowCurrent
        End If
    Next i

    If lastRowBest < rng.row Then
        LastRowInRange_xlUp = rng.row
    Else
        LastRowInRange_xlUp = lastRowBest
    End If

End Function

Implementation 3 - Loops through an Array in reverse order实现 3 - 以相反的顺序循环遍历数组

Function LastRowInRange_Array(ByVal rng As Range) As Long

    'store range's data as an array
    Dim rngValues As Variant
    rngValues = rng.Value2

    Dim lastRow As Long

    Dim i As Long
    Dim j As Long

    'loop through range from left to right and from bottom upwards
    For i = LBound(rngValues, 2) To UBound(rngValues, 2)                'columns
        For j = UBound(rngValues, 1) To LBound(rngValues, 1) Step -1    'rows

            'if cell is not empty
            If Len(Trim(rngValues(j, i))) > 0 Then
                If j > lastRow Then lastRow = j

                Exit For
            End If

        Next j
    Next i

    If lastRow = 0 Then
        LastRowInRange_Array = rng.row
    Else
        LastRowInRange_Array = lastRow + rng.row - 1
    End If

End Function

I have not tested which of these implementations works fastest on large sets of data, but I would imagine that the winner would be _Array since it is not looping through each cell on the sheet individually but instead loops through the data stored in memory.我还没有测试过这些实现中的哪一个在大数据集上运行最快,但我想获胜者将是_Array因为它不是单独循环遍历工作表上的每个单元格,而是循环遍历存储在内存中的数据。 However, I have included all 3 for variety :)但是,我已将所有 3 种都包括在内 :)


How to use使用方法

To use these functions, you drop them into your code sheet/module, specify a range as their parameter, and then they will return the "lowest" filled row within that range.要使用这些函数,请将它们放入代码表/模块中,指定一个范围作为它们的参数,然后它们将返回该范围内的“最低”填充行。

Here's how you can use any of them to solve the initial problem that was asked:以下是如何使用它们中的任何一个来解决最初提出的问题:

Sub answer()

    Dim testRange As Range
    Set testRange = Range("A1:F28")

    MsgBox LastRowInRange_Find(testRange)
    MsgBox LastRowInRange_xlUp(testRange)
    MsgBox LastRowInRange_Array(testRange)

End Sub

Each of these will return 18 .这些中的每一个都将返回18

If your wbshtSelect is defined as worksheet and you have used set to define the specific worksheet, you can use this.如果您的 wbshtSelect 被定义为工作表并且您已经使用 set 来定义特定的工作表,则可以使用它。

 Dim LastRow As Long

 wbshtSelect.UsedRange ' Refresh UsedRange
 LastRow = wbshtSelect.UsedRange.Rows(wbshtSelect.UsedRange.Rows.Count).Row

Otherwise take a look here http://www.ozgrid.com/VBA/ExcelRanges.htm否则看看这里http://www.ozgrid.com/VBA/ExcelRanges.htm

LR_wbSelectNew = wbshtSelect.cells(LR_wbSelect, "B").End(xlUp).Row

Why are you using "LR_wbSelect" as the row counter?为什么使用“LR_wbSelect”作为行计数器? If you want to know the last row of column 'B', you should use Rows.count如果你想知道'B'列的最后一行,你应该使用Rows.count

Rows.count --> Returns maximum number of rows (which is 1048576 for Excel 2007 and up) End(xlUp) --> Moves the pointer upward to the last used row Rows.count --> 返回最大行数(对于 Excel 2007 及更高版本为 1048576) End(xlUp) --> 将指针向上移动到最后使用的行

So, cells(Rows.count, "A").End(xlUp).Row --> This moves the pointer to the last row if the column 'A' (as if you are pressing Crtl+Up keys when A1048576 cell is selected)因此,cells(Rows.count, "A").End(xlUp).Row --> 如果列 'A',这会将指针移动到最后一行(就像当 A1048576 单元格为已选择)

So, use Rows.count to select the last row for column 'B' as well.因此,也使用 Rows.count 选择列 'B' 的最后一行。 If you have some specific requirement related to LR_wbSelect, please mention it.如果您有一些与 LR_wbSelect 相关的特定要求,请提及。

Alternatively, if you want to know the last row used in a sheet, you may use the below:或者,如果您想知道工作表中使用的最后一行,您可以使用以下内容:

mySheet.Cells.SpecialCells(xlCellTypeLastCell).Row
LR_wbSelect = ThisWorkbook.Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row

Range().End will bring you to the end of a code block. Range().End将带您到代码块的末尾。 If the starting cell is empty, it brings you the the first used cell or the last cell.如果起始单元格为空,它会为您提供第一个使用的单元格或最后一个单元格。 It the cells is not empty it brings you to the last used cell.如果单元格不是空的,它会将您带到最后使用的单元格。 For this reason, you need to test whether or not the cell in column B is to determine whether to use LR_wbSelectNew as the last row.为此,需要测试B列的单元格是否确定是否使用LR_wbSelectNew作为最后一行。

With wbshtSelect
    LR_wbSelect = .Cells(Rows.Count, "A").End(xlUp).Row - 22

    If .Cells(LR_wbSelect, "B") <> "" Then
        LR_wbSelectNew = LR_wbSelect
    Else
        LR_wbSelectNew = .Cells(LR_wbSelect, "B").End(xlUp).Row
    End If
End With

This code defines a Target range that extends from A1 to the last row in column a - 22 and extends 10 columns.此代码定义了一个目标范围,该范围从 A1 扩展到 a - 22 列中的最后一行并扩展了 10 列。

Dim Target As Range
With wbshtSelect
    Set Target = .Range("A1", .Cells(Rows.Count, "A").End(xlUp).Offset(-22)).Resize(, 10)
End With
    'This is sure method to find or catch last row in any column even   'if  some cell are blank in-between. (Excel-2007)` 
'This works even if sheet is not active

    'mycol is the column you want to get last row number

for n=1048575 to 1 step -1
myval=cells(n,mycol)
if myval<>"" then
mylastrow=n 'this is last row in the column
exit for
end if
next

ret=msgbox("Last row in column-" & mycol & "is=" & mylastrow)

尝试执行此操作的问题是,如果单元格包含一个公式,则excel会认为它已填充,即使该公式返回一个空白也是如此。

Shai Rado's first solution is a great one , but for some it might need a bit more elaboration: Shai Rado 的第一个解决方案是一个很好的解决方案,但对于某些人来说可能需要更多的阐述:

 Dim rngCurr, lastRow
 rngCurr = wbshtSelect.Range("B10").CurrentRegion
 lastRow = rngCurr.Rows(rngCurr.Rows.Count).Row

If you want to know the last used row in the entire worksheet:如果您想知道整个工作表中最后使用的行:

 Dim rngCurr, lastRow
 rngCurr = Range("A1").CurrentRegion
 lastRow = rngCurr.Rows(rngCurr.Rows.Count).Row
Dim rng As Range
Dim FirstRow, LastRow As long

Set rng = Selection

With rng

 FirstRow = ActiveCell.Row

 LastRow = .Rows(.Rows.Count).Row

End With

Simple function that return last row no.返回最后一行的简单函数。 in specific sheet.在特定的工作表中。 It takes the last address in UsedRange and retrieve last row number.它获取 UsedRange 中的最后一个地址并检索最后一个行号。 Feel to free change the code and use standard range insead of UsedRange.随意更改代码并使用 UsedRange 的标准范围。

Function FindLastRow(wsToCheck As Worksheet) As Long
    Dim str As String
    str = wsToCheck.UsedRange.AddressLocal()
    FindLastRow = Right(str, InStr(1, StrReverse(str), "$") - 1)
End Function

Backing off from the range to the worksheet will get you the whole sheet extents of the range used on the sheet (which may be smaller than you expect if the sheet doesn't have data in the top rows; but it does include internal blanks)从范围退回到工作表将为您提供工作表上使用的范围的整个工作表范围(如果工作表顶行没有数据,它可能比您预期的要小;但它确实包括内部空白)

TheRange.Worksheet.UsedRange.Rows.Count TheRange.Worksheet.UsedRange.Rows.Count

If there is no data in the top rows, the following will get you the first row which you need to add to the above to get the highest row number如果顶行中没有数据,以下将获得第一行,您需要将其添加到上面以获得最高行号

TheRange.End(xlDown).Row TheRange.End(xlDown).Row

So Dim TheRange as Range Dim MaxRow as Long MaxRow = TheRange.Worksheet.UsedRange.Rows.Count + TheRange.End(xlDown).Row所以Dim TheRange 作为 Range Dim MaxRow 作为 Long MaxRow = TheRange.Worksheet.UsedRange.Rows.Count + TheRange.End(xlDown).Row

Will get the highest row number with data (but not the whole sheet)将获得包含数据的最高行号(但不是整个工作表)

Before getting into complex coding why not build something on the below principle:在进入复杂的编码之前,为什么不根据以下原则构建一些东西:

MaxRow = Application.Evaluate("MIN(ROW(A10:C29)) + ROWS(A10:C29) - 1") MaxRow = Application.Evaluate("MIN(ROW(A10:C29)) + ROWS(A10:C29) - 1")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM