9

我正在尝试在 A 列中找到包含具有以下代码的值的最后一行:

LastRow = DataWorksheet.Range("A:A").Find(What:="*", SearchOrder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).Row

这适用于大多数情况,除非最后几行被过滤掉。例如,假设我们有 30 行数据。如果 1-10 行可见,11-20 行被过滤掉,21-30 行可见,则成功找到最后一行:返回 30。当所有内容可见且过滤掉 21-30 行时,LastRow 返回 1。

请注意,如果我手动隐藏而不是过滤掉第 21-30 行,它会告诉我最后一行是 20。

是什么赋予了?如果最后一行被过滤,我怎样才能让它确定最后一行是什么?

编辑:现在似乎 LastRow 正在挑选最后一个未过滤的行,这与其之前的行为明显不同。一旦我能够更好地隔离我遇到的错误/不一致,我将更新这篇文章。

4

7 回答 7

3

这些应该忽略过滤/可见性并为您提供最后使用的行号:

DataWorksheet.UsedRange.Rows.Count

-或者-

DataWorksheet.Range("A1").SpecialCells(xlCellTypeLastCell).Row

两者都不会在 A 列中找到最后使用的单元格,但是……这是您需要的吗?

于 2013-01-07T17:01:36.860 回答
1

这个怎么样(作为一种解决 XL 限制的工作)。循环有点长/笨重,但至少循环从第一个可见的最后一个单元格开始。

LastRow = DataWorksheet.Range("A:A").Find(What:="*", SearchOrder:=xlRows, SearchDirection:=xlPrevious, LookIn:=xlValues).Row


If LastRow <> DataWorksheet.UsedRange.Rows.Count 'assumes data starts in A1, if not adjust acoordingly

'now check if there is anything below

    Dim rngSearch as Range
    rngSearch = DataWorksheet.Range("A" & LastRow & ":A" & DataWorksheet.UsedRange.Rows.Count)

    Dim lngRows as Long, lngCnt as Long
    lngRows = rngSearch.Rows.Count

    For lngCnt = lngRows to 1 Step -1

        If DataWorksheet.Range("A" & lngCnt) = vbNullString And DataWorksheet.Range("A" & lngCnt -1) <> vbNullString Then

            LastRow = DataWorksheet.Range("A" & lngCnt-1).Row
        End If

    Next

End If
于 2013-01-07T18:04:33.857 回答
1

这适用于具有隐藏行和自动过滤器的工作表。如果最后一个具有值的单元格下方的单元格已被格式化(这将导致 usedrange 大于您正在查找的行),它也不会为您提供不正确的行。

Sub FindLastRowWithValue()
    Dim ws As Worksheet
    Dim temp As Worksheet
    Dim lastrow As Long

    ' copy the sheet that may have hidden rows
    Set ws = Sheets("Sheet1")
    ws.Copy Before:=Sheets(1)
    Set temp = ActiveSheet

    ' turn off autofiltering if need be
    If temp.AutoFilterMode Then temp.AutoFilterMode = False

    ' unhide all rows
    temp.Columns("A:A").EntireRow.Hidden = False

    ' get the last row with a value now that all rows are unhidden
    lastrow = temp.Range("A" & temp.Rows.Count).End(xlUp).Row

    ' delete the temporary sheet
    Application.DisplayAlerts = False
    temp.Delete
    Application.DisplayAlerts = True

    MsgBox lastrow
End Sub
于 2013-01-09T02:34:34.113 回答
1

在经历了很多挫折之后,“vba built-in”方法似乎总是存在问题。例如,列“A”和“WS”是工作表对象:

  • « Ws.Cells(WS.Rows.Count,1).End(xlUp) » 因隐藏行而失败
  • « WS.Range("A1").Find(...) » 在组中隐藏行时失败(可能还有其他情况)
  • « UsedRange » 和 « .SpecialCells(xlLastCell) » 可以返回高于预期的结果

我的解决方案是使用带有“WorkSheet.Evaluate”的 excel 公式。

检查非空值(即不考虑结果为空的公式):

Function FindLastRow(R as Range) As Long
    Const NotFoundResult = 1 ' If all cells have an empty value, this value is returned
    FindLastRow = R.Worksheet.Evaluate("IFERROR(LARGE(ROW('" & R.Worksheet.Name & "'!" & R.Address & ")*--('" & R.Worksheet.Name & "'!" & R.Address & " <> """"),1)," & NotFoundResult & ")")
End Function

要使用公式或值检查最后一个单元格(即使结果为空):

Function FindLastRow(R as Range) As Long
    Const NotFoundResult = 1 ' If all cells are empty (no value, no formula), this value is returned
    FindLastRow = R.Worksheet.Evaluate("IFERROR(LARGE(ROW('" & R.Worksheet.name & "'!" & R.Address & ")*--(NOT(ISBLANK('" & R.Worksheet.name & "'!" & R.Address & "))),1)," & NotFoundResult & ")")
End Function
于 2017-09-19T17:59:16.873 回答
1

我假设 Slothario 的工作表结构简单,具有以下主要特点:

  • A 列中最后一个填充的单元格也是工作表的最后一个填充行(至少在没有隐藏或过滤掉任何行时)。
  • 第 1 行有东西

在这种情况下,这里有两种简单的方法来识别不同类型的“最后一行”:

Cells.SpecialCells(xlLastCell).Row 'Last row that is not hidden or filtered out

Activesheet.UsedRange.Rows.Count 'Last row with a value in it (even if the row is hidden; only gives right answer if row 1 is nonblank)

如果顶行/行可能为空白,则需要将第二个选项修改为:

Activesheet.UsedRange.Rows.Count + Activesheet.UsedRange.Row -1 'Last row with a value in it (even if the row is hidden)
于 2021-07-05T20:03:56.530 回答
0

我一直使用它来获取最后一行,但不是 100% 确定它适用于隐藏单元格:)

PS 确保在测试时更改工作表名称

'VBA to find last row
lngLastRow = ThisWorkbook.Worksheets("Data").Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
于 2016-04-20T10:34:36.303 回答
0
Public Function lr(ByVal source As Worksheet, colu As Long) As Long
Dim tmp As Long
tmp = source.Cells(source.Rows.Count, colu).End(xlUp).Row

While source.Cells(tmp + 1, colu).EntireRow.Hidden = True
tmp = tmp + 1
Wend
lr = tmp
End Function
于 2020-03-16T12:15:44.540 回答