【问题标题】:VBA LastRow calculation not workingVBA LastRow 计算不起作用
【发布时间】:2019-07-15 21:28:02
【问题描述】:

我有一个自动过滤范围的工作表,该范围从单元格 B3 开始。 A 列包含一些宏按钮,但实际上是空白的。前两行包含有关主范围内数据的信息。

在 VBA 中,我使用我认为是确定工作表中最后一行的标准方法(在这种情况下,我不能在单个列上依赖 .End 方法):

LastRow = Activesheet.Cells.Find("*",SearchOrder:=xlByRows,SearchDirection:=xlPrevious).Row

但是,有时即使我有数千行数据,它也会返回一个值。似乎只有在设置了过滤器时才会这样做(但仍有可见的行中包含数据),但即便如此它并不总是发生,我也看不到它的模式。

我知道还有其他解决方案 - 我已改为使用 UsedRange 技术,但令人沮丧的是,这个特定的解决方案失败了,因为在这种情况下它本来是最有效的解决方案。

有人知道为什么会这样吗?

【问题讨论】:

  • 我发现 Find 方法有时很奇怪。您是否尝试过在 Find 调用中指定 Lookin:=xlValues(或者如果所有公式都切换到 xlFormulas)?

标签: vba excel autofilter


【解决方案1】:

您是否考虑过使用 Greg 的答案,但循环查找所有列的最高行?比如:

LastRow = 1
With ActiveSheet
   For i = 1 to .UsedRange.Columns.Count
      If .Cells(.Rows.Count, i).End(xlUp).Row > LastRow Then
         LastRow = .Cells(.Rows.Count, i).End(xlUp).Row
      EndIf
   Next i
End With

此解决方案将允许在底部行中随机填充空白值。 UsedRange 很棘手,因为它会返回曾经被编辑过的最远的行/列(即使它当前是空白的)。根据我的经验,如果您在工作表中按下 Ctrl-Up,则 Range.End(xlUp) 的行为与您预期的一样。这有点更可预测。

如果您打算使用 .Find,请尝试查看 After:=[A1] 参数。我还没有探索过这个函数的特殊之处,但考虑到这个问题,我会从那里开始。

【讨论】:

    【解决方案2】:

    试试这个...

    Dim LastRow as long
    
    With ActiveSheet
        LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With
    

    这将获得 A 列中的最后一行。

    【讨论】:

    • 谢谢,但我已经知道其他解决方案,在这种情况下我不能依赖单个列。如果在这种情况下工作,.find 方法将是最有效的。我已经相应地更新了问题。
    【解决方案3】:

    建议您尝试使用Find 指定查看XlFormulas,与XlValues 不同,使用此参数将检测隐藏单元格(但不是过滤单元格)。

    Sub Test()
    Dim rng1 As Range
    Set rng1 = ActiveSheet.Cells.Find("*", [a1], xlFormulas, , xlByRows, xlPrevious)
    If Not rng1 Is Nothing Then MsgBox rng1.Row
    End Sub
    

    【讨论】:

      【解决方案4】:

      今天早上我遇到了完全相同的问题。

      起初,我确信“.find”功能不稳定。

      但是,在摆弄了一段时间之后,我发现我的工作表中的行号太深了一个非空单元格,认为它是 1,000 或 10,000 或类似的。我删除了它,“.find”又可以工作了。可能是某些内部 VBA 变量的限制不够大。

      这样做:

      1) 按 CTRL + END

      2) 识别非空单元格,假设这是无意中填写的,然后将其删除。

      【讨论】:

        【解决方案5】:

        试试下面的代码:

        Sub GetColA_LastRow()
            Dim ws As Worksheet
            Dim lRow As Long
        
            Set ws = ThisWorkbook.Sheets("Sheet1")
        
            With ws
                lRow = .Range("A" & .Rows.Count).End(xlUp).Row
            End With
        
            MsgBox "The last row which has data in Col A of Sheet1 is " & lRow
        End Sub
        

        sub getLastRow()
         dim lastRow as long
         lastRow = Sheets("sheet1").Range("A65000").End(xlUp).Row
        
        end sub
        

        您也可以访问链接了解更多详情 http://www.siddharthrout.com/2012/10/02/find-last-row-in-an-excel-sheetvbavb-net/

        更新cmets后的代码:

        Sub getLastRow()
        
            Dim rng As Range, lastRow As Long
            Set rng = Cells.Find("mango") ' here you enter whatever you want to find
        
            If Not rng Is Nothing Then
                lastRow = Sheets("sheet1").Cells(65000, rng.Column).End(xlUp).Row
            End If
        
        End Sub
        

        【讨论】:

        • 谢谢,但我已经知道其他解决方案,在这种情况下我不能依赖单个列。如果在这种情况下工作,.find 方法将是最有效的。我已经相应地更新了问题。
        • 看看我的解决方案,然后使用 UsedRange 对象。
        【解决方案6】:

        怎么样:

        with activesheet.usedrange
            LastRow = .rows.count
        end with
        

        hth 菲利普

        【讨论】:

          【解决方案7】:

          我的类似问题是使用或不使用过滤之前的空单元格,最后一行和 col 是什么。我从我能找到的点点滴滴拼凑起来,它做了我认为你和我想要的,至少对于填充数据的单元格。

          Function FindLastUsedRowAndCol(ByVal ws As Worksheet) As Variant()
          
          Dim LastColRange As Range
          Dim LastCol As Integer
          Dim LastRow As Long
          Dim LastRowTmp As Long
          Dim RowXCol(2) As Variant
          
          
          Set LastColRange = ws.Cells.Find(What:="*", After:=ws.Cells(1, 1), LookIn:=xlFormulas, LookAt:= _
              xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
          LastCol = LastColRange.Column
          
          LastRow = 1
          
          For i = 1 To LastCol Step 1
              If ws.FilterMode Then
                  LastRow = ws.AutoFilter.Range.Rows.Count
                  LastRowTmp = Cells(ws.Rows.Count, i).End(xlUp).row
                  If LastRowTmp > LastRow Then LastRow = LastRowTmp
              Else
                  LastRowTmp = Cells(ws.Rows.Count, i).End(xlUp).row
                  If LastRowTmp > LastRow Then LastRow = LastRowTmp
              End If
          Next i
          
          RowXCol(1) = LastRow
          RowXCol(2) = LastCol
          FindLastUsedRowAndCol = RowXCol
          
          End Function
          

          然后进行测试:

          Sub testit()
          Dim ws As Worksheet
          Set ws = Application.Worksheets("Sheet1")
          cr = FindLastUsedRowAndCol(ws)
          MsgBox "row: " & cr(1) & " col: " & cr(2)
          End Sub
          

          【讨论】:

          • 从头开始。它并非在所有情况下都有效
          【解决方案8】:

          我知道这是一篇旧帖子,但我已经看到了这个问题,但没有看到任何解决这个问题的答案。它似乎有时会发生在最后一行之后立即隐藏行的数据集上。无论您是设置为查看 xlformulas 还是 xlvalues 都没有关系,我已经尝试了我能找到的 find 命令的所有排列,它始终返回值 1。(正如 OP 所说)上面的解决方案不能解决这个问题。在这种情况下,我必须创建一个迭代查找最后一行的函数(下面的关键代码位 - 在我的情况下,我需要在各种数据表的前两列中找到 lastrow):

          On Error GoTo ExitLoop
          StartRow = 1
          LastRow = .Columns("A:B").Find(What:="*", SearchDirection:=xlNormal, LookIn:=xlValues, SearchOrder:=xlByRows).Row
          StartRow = LastRow + 1
          Do Until WorksheetFunction.CountA(.Range(.Cells(StartRow, 1), .Cells(1048576, 2))) = 0
              FindLastRow = .Range(.Cells(StartRow, 1), .Cells(1048576, 2)).Find(What:="*", SearchDirection:=xlNormal, LookIn:=xlValues, SearchOrder:=xlByRows).Row
              StartRow = LastRow + 1
          Loop
          ExitLoop:
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-13
            • 1970-01-01
            • 1970-01-01
            • 2015-08-19
            • 2014-10-04
            • 1970-01-01
            相关资源
            最近更新 更多