Excel VBA查找范围中的最后一行

时间:2016-11-17 09:00:30

标签: excel vba excel-vba excel-2010

我找到最后一行时有点麻烦。

我要做的是找到列#34; 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

我正在使用列#34; A"中的最后一行因为来自第29行的数据将始终具有相同的长度,所以在列" B"从第29行可以是不同数量的行。

所以我试图在#34; A"列中使用LR_wbSelect得到我的最后一行,然后在LR_wbSelectNew内使用它作为查找的起点。

当我设置为" A",LR_wbSelectNew的列给出了" 17"的行,但当我更改{{1}中的列时到" B"它没有给出正确的最后一行" 18"。

我可以将列更改为" C,D,E,F"并且代码工作正常,但我可以使用的唯一一列是" B"因为它总是会有数据,其中该行的其余部分可能有一个空白单元格。

在纸张上进行一些测试后,按下CRTL&从LR_wbSelectNew列" B"的拉丝点开始忽略行中的数据并转到它找到数据的行。我无法看到excel不认为这些单元格中有数据的原因吗?

希望我已经解释过,所以你可以关注,如果不是,请问。

如果需要,我可以根据需要上传完整的代码,请告诉我。

任何帮助都将不胜感激。

12 个答案:

答案 0 :(得分:6)

搜索LastRow时有多种结果和方法(在B列中)。

使用Cells(.Rows.Count, "B").End(xlUp).Row时,您将获得包含B列数据的最后一行(它忽略带空格的行,并一直向下)。

使用时:

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

您正在搜索CurrentRegion的B列中的数据的最后一行,该数据从单元格B10开始,直到没有数据的第一行(它在第一行中以空行停止)。

完整代码:

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 :代码搜索包含值的单元格的最后一行(忽略包含公式的空白单元格)。

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

答案 1 :(得分:1)

希望这段代码有所帮助!

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

答案 2 :(得分:1)

如果您的wbshtSelect被定义为工作表,并且您已使用set来定义特定的工作表,则可以使用它。

 Dim LastRow As Long

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

否则请查看http://www.ozgrid.com/VBA/ExcelRanges.htm

答案 3 :(得分:1)

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

你为什么使用&#34; LR_wbSelect&#34;作为行计数器?如果您想知道列的最后一行&#39; B&#39;,您应该使用Rows.count

Rows.count - &gt;返回最大行数(Excel 2007及更高版本为1048576) 结束(xlUp) - &gt;将指针向上移动到最后使用的行

所以,  cell(Rows.count,&#34; A&#34;)。End(xlUp).Row - &gt;如果列“A&#39;”,则会将指针移动到最后一行。 (就像选择A1048576单元格时按Crtl + Up键一样)

因此,使用Rows.count选择列的最后一行&#39; B&#39;同样。如果您有与LR_wbSelect相关的特定要求,请提及。

或者,如果您想知道工作表中使用的最后一行,可以使用以下内容:

mySheet.Cells.SpecialCells(xlCellTypeLastCell).Row

答案 4 :(得分:1)

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

答案 5 :(得分:1)

我来这里是为了寻找一种在非连续范围内找到最后一行的方法。这里的大多数响应一次只能检查一列,因此我创建了一些不同的函数来解决此问题。不过,我将承认Shai Rado的答案与我的.Find()实现基本相同。

实施1-在每一列上使用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

实施2-以相反的顺序使用Range().Find()

Function LastRowInRange_Find(ByVal rng As Range) As Long

    'searches range from bottom up looking for "*" (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

实现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

我尚未测试以下哪种实现对大型数据集最快的运行,但是我可以想象赢家将是_Array,因为它不会单独遍历工作表中的每个单元格而是会遍历数据存储在内存中。但是,我将所有3种都包括在内:)


使用方法

要使用这些功能,请将它们放入代码表/模块中,指定一个范围作为其参数,然后它们将返回该范围内“最低”的填充行。

您可以在其中使用它们中的任何一种来解决最初提出的问题:

Sub answer()

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

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

End Sub

每一个都将返回18

答案 6 :(得分:0)

Range().End会将您带到代码块的末尾。如果起始单元格为空,则会为您显示第一个使用过的单元格或最后一个单元格。细胞不是空的,它会带你到最后一个使用过的细胞。因此,您需要测试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

此代码定义了一个目标范围,该范围从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

答案 7 :(得分:0)

    '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)

答案 8 :(得分:0)

尝试这样做的问题是,如果单元格包含公式,那么即使公式返回空白,excel也会认为它已填充。

答案 9 :(得分:0)

Shai Rado的第一个解决方案是一个很好的解决方案,但对于某些解决方案,可能还需要进一步完善:

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

如果您想知道整个工作表中最后使用的行:

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

如果您认为这有帮助,请对他的回答进行投票。

答案 10 :(得分:-1)

Dim rng As Range
Dim FirstRow, LastRow As long

Set rng = Selection

With rng

 FirstRow = ActiveCell.Row

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

End With

答案 11 :(得分:-1)

在开始复杂的编码之前,为什么不基于以下原理构建一些东西:

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