【问题标题】:Get the Row Positions without Looping在不循环的情况下获取行位置
【发布时间】:2021-05-12 08:52:09
【问题描述】:

是否可以在不执行循环的情况下在 excel 中获取大表中的行位置? 我要做的是点击一个特定的 ID,然后来自同一 ID 的最后 3 条记录将显示在 UI 中。

我是编程初学者,除了循环方法之外不知道如何执行此操作(考虑到我们在用户的每次单击中循环一个包含 100k 行的大型且不断增长的表,这是非常资源和内存密集型的)。

例如:如果用户点击“A123”,那么我们知道他们的行位置是:5、8、10

【问题讨论】:

  • 如果你有 100k 行,你应该考虑使用 SQL 数据库,这很容易实现。 • 在 Excel 中,您可以使用过滤器来过滤 A123,但如果不循环,您仍然无法获得前 3 个。
  • @PEH - 不幸的是,我们没有使用 SQL 数据库的选项...对于您使用过滤器的建议,是否可以循环过滤表?您能否展示一些有关如何执行此操作的示例代码?谢谢!
  • 那么过滤器、循环或电源查询是您的选择,我猜。看看它并尝试一下。
  • 不完全相同,但也许可以接受的折衷方案是添加一个带有“=row()”的辅助 col 并使用切片器在数据透视表中显示信息。甚至可以通过将源添加到数据模型来提高性能。

标签: excel vba loops search match


【解决方案1】:

与发布的 CDP1802 相同,但查找最后 3 行的速度更快。

Sub FilteredAdvanced()
    Const nValues As Long = 3 'amount of rows you want to find from the end
    
    Dim ar() As Long
    ReDim ar(nValues - 1) As Long
    
    ' apply filter
    With Sheet1
        .AutoFilterMode = False
        .UsedRange.AutoFilter 1, "A123"
        Dim rng As Range
        Set rng = .UsedRange.Columns(1).SpecialCells(xlCellTypeVisible)
        .UsedRange.AutoFilter 'remove filter
    End With
    
    Dim n As Long
    n = nValues - 1

    Dim iArea As Long
    For iArea = rng.Areas.Count To 1 Step -1
        Dim iRow As Long
        For iRow = rng.Areas(iArea).Rows.Count To 1 Step -1
            ar(n) = rng.Areas(iArea).Rows(iRow).Row
            n = n - 1
            If n < 0 Then Exit For
        Next iRow
        If n < 0 Then Exit For
    Next iArea

    Dim j As Long
    For j = 0 To nValues - 1
        Debug.Print ar(j)
    Next
End Sub

【讨论】:

    【解决方案2】:

    循环过滤列表

    Option Explicit
    Sub Filtered()
    
        Dim rng as Range, ID As Range, a As Range
        Dim ar(2) As Long, i As Integer, j As Integer
        
        ' apply filter
        With Sheet1
            .AutoFilterMode = False
            .UsedRange.AutoFilter 1, "A123"
            Set rng = .UsedRange.Columns(1).SpecialCells(xlCellTypeVisible)
        End With
    
        ' count
        For Each a In rng.Areas
            For Each ID In a.Cells
                If ID.Row > 1 Then
                    i = (i + 1) Mod 3
                    ar(i) = ID.Row
                End If
            Next
        Next
        For j = 1 To 3
            Debug.Print ar((j + i) Mod 3)
        Next
    End Sub
    

    【讨论】:

    • 不错的解决方案。请注意,您的 area 和 id 循环从第一个可见行循环到最后一个可见行。所以它实际上会遍历 all 可见行,而它只需要遍历最后 3 行。如果将其从最后可见行转到第一个可见行,则可以更快地找到最后 3 行(尤其是如果找到很多行)。看我的回答。
    • 感谢@CDP1802!你的方法也很有帮助并影响了我的工作。
    猜你喜欢
    • 2016-07-26
    • 2013-05-19
    • 2012-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 2021-11-06
    相关资源
    最近更新 更多