用于筛选表格的search框的VBA代码

我devise了一个search框,当文本input到search框中时,可以过滤我的表格。 问题在于它太慢了,现在几乎不值得在我的工作簿中使用它。

任何人都可以想办法修改/改进这个代码?

这是我的代码目前:

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) & "*" Rows.Hidden = False lastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row Set searchArea = Me.Range("f3:f791", "f3" & lastRow) 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 Range("Z1"), True ActiveWindow.ScrollColumn = 1 Application.ScreenUpdating = True End Sub 

编辑我的代码到这个:

 Private Sub TextBox1_Change() ActiveSheet.ListObjects("states").Range.AutoFilter Field:=1, _ Criteria1:="*" & [G1] & "*", Operator:=xlFilterValues End Sub 

但是,这是行不通的。 字段1中有文本和数字,这只是过滤文本,而不是数字…

这绝对是多余的,因为你的迭代遍布在一个列上:

  For Each searchRow In searchArea.Rows For Each searchCell In searchRow.Cells '### searchRow ONLY HAS ONE CELL! This second/inner loop is totally unnecessary If LCase(searchCell) Like searchString Then searchRow.Hidden = False Exit For End If Next searchCell Next searchRow 

重写为:

 For Each searchCell in searchArea.Cells '## Assumes searchArea is single column searchCell.EntireRow.Hidden = Not (LCase(searchCell) Like searchString) Next 

这本身应该会提高性能,但我认为AutoFilter是一个更好的方法,你应该能够从Macro Recorder中得到基本的代码。

这看起来像这样:

 searchArea.AutoFilter Field:=1, Criteria1:="=" & searchString, _ Operator:=xlAnd, Criteria2:="<>" 

这应该过滤只显示包含您的searchString非空行

也应该注意@Yowe3k关于范围分配的观点,您可以使用TextBox的AfterUpdate事件而不是Change事件。

更新这可能会处理您的混合情况下的数值/文本值。 可能有更好的方法来做到这一点,但我没有看到明显的解决scheme。 AutoFilter是用来处理文字数字,但不能同时使用。 所以这试图将数值转换为string表示。 如果公式中引用了数字值,则可能需要在其他地方进行更改

 Dim arr, v Dim tbl As ListObject Set tbl = ActiveSheet.ListObjects(1) ' ## Disable filter if it's on already If tbl.Range.AutoFilter Then tbl.Range.AutoFilter arr = tbl.DataBodyRange.Columns(1).Value ' ## Convert your range of mixed numeric/string to string For v = LBound(arr, 1) To UBound(arr, 1) If IsNumeric(arr(v, 1)) Then arr(v, 1) = "'" & CStr(arr(v, 1)) End If Next ' ## Put the string data back out to the worksheet tbl.DataBodyRange.Columns(1).Value = arr tbl.Range.AutoFilter Field:=1, _ Criteria1:="*" & CStr([G1]) & "*", Operator:=xlFilterValues