【问题标题】:Filter while typing in a cell输入单元格时过滤
【发布时间】:2015-03-18 19:39:21
【问题描述】:

是否可以根据我在单元格中键入的值动态过滤行?假设我有一个包含数据A10:A1000 的列范围,并且我根据我在A1 单元格中输入的条件过滤该范围。

我希望过滤器在我输入时在运行时动态地做出反应,而不是在我按下 [Enter] 之后。我找到了一个带有文本框的解决方案。 http://www.vbforums.com/showthread.php?647621-Excel-filtering-while-typing

但是,最好是在一个单元格中输入,而不是在某个文本框中。有可能吗?

【问题讨论】:

  • 我认为这是不可能的。使用单元格,您实际上并没有对单元格进行任何更改,直到您按 Enter 键。但是,对于文本框,每次击键都是一次更改。
  • 您可以通过更改事件触发操作。你有左键单击、右键单击和我猜的其他一些东西的更改事件。得承认我对你的目标有点悲观。如果使用VBA比较单元格和某些标准,我认为只有在按Enter键后才能完成。但我不确定
  • 刚刚想到了什么。您可以将单元格链接到文本框,然后使用 VBA 在选择更改事件中隐藏/显示文本框。您可以将文本框放在单元格上,这样看起来您正在单元格中输入......
  • 从03:40的这个演示开始,有可能youtu.be/mAXiZbhEfr4

标签: vba excel filtering dynamic-typing


【解决方案1】:

@PermaNoob 有最好的解决方案。当您处于“编辑”模式时,Excel 不允许您使用 VBA 检查单元格的值。但是,您可以在 A1 上放置一个文本框,然后使用它来运行“动态”搜索。

Start VBA macro when editing a cell

Private Sub TextBox1_Change()
 Dim searchArea As Range, searchRow As Range, searchCell As Range
 Dim searchString As String
 Dim lastRow As Integer

 Application.ScreenUpdating = False
 searchString = "*" & LCase(TextBox1.Value) & "*"

 ' unhide rows to have the full search field when editing
 Rows.Hidden = False

 lastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
 Set searchArea = Me.Range("A5", "A" & lastRow) 'Me.Range("A5").End(xlDown))
 searchArea.EntireRow.Hidden = True

 For Each searchRow In searchArea.Rows
   For Each searchCell In searchRow.Cells
     If LCase(searchCell) Like searchString Then
       searchRow.Hidden = False
       Exit For
     End If
   Next searchCell
 Next searchRow

 Application.Goto Cells(1), True
 Application.ScreenUpdating = True

End Sub

【讨论】:

    【解决方案2】:

    我已经尝试了上述解决方案,效果很好,但速度极慢。

    在有 950 行的列中,第一个字母过滤需要 13 秒。速度从第二个字母开始提高,但对我来说,最初的等待是不可接受的。

    我最终做了以下事情:

    1. 创建了一个新列 (C) 以根据单元格 I1 的值过滤列 A 中的数据 在单元格C2: =IF(ISERR(FIND(LOWER(I$1);LOWER(A2);1));" ";"F")中输入此内容@

    2. 创建了文本框并将其与单元格 I1 链接

    3. 在 VBA 中添加以下代码:

      Private Sub TextBox1_Change()
          Call Worksheet_SelectionChange(Range("I1"))
      End Sub
      
      Private Sub Worksheet_SelectionChange(ByVal Target As Range)    
        If Not Application.Intersect(Target, Range("I1")) Is Nothing Then    
           Range(Range("C2"), Range("C2").End(xlDown)).AutoFilter Field:=1, Criteria1:="F"    
        End If    
      End Sub
      

    【讨论】:

      【解决方案3】:

      我最终使用了基于数据透视表的解决方案。它过滤文件中的数百个项目,在键入每个字母后缩小结果范围。更重要的是,它允许选择多个项目。

      我将项目列表放入数据透视表的页面过滤器。为了美观,您可以隐藏页面过滤器下方的整行,这样它甚至看起来都不像数据透视表,而只是一个用于类型/下拉选择值的单元格。

      【讨论】:

        猜你喜欢
        • 2021-05-08
        • 1970-01-01
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 2019-10-03
        • 1970-01-01
        • 2011-05-18
        相关资源
        最近更新 更多