标签:VBA,自动筛选,Autofilter方法
本文前面的内容参见:VBA自动筛选完全指南(上)
示例:使用AutoFilter方法筛选前10条记录
数据集同上。下面的代码提供前10条记录(基于“数量”列):
代码语言:javascript复制Sub FilterRowsTop10()
ActiveSheet.Range("A1").AutoFilter Field:=4, _
Criteria1:="10", _
Operator:=xlTop10Items
End Sub
如果想获取前5条记录,只需要将Criteria1:=”10”中的10修改为5。
因此,获取前5条记录的代码为:
代码语言:javascript复制Sub FilterRowsTop5()
ActiveSheet.Range("A1").AutoFilter Field:=4, _
Criteria1:="5", _
Operator:=xlTop10Items
End Sub
这可能看起来很奇怪,但无论想要多少个前面的条目,运算符值始终为xlTop10Items。
相似地,下面的代码获取后10条记录:
代码语言:javascript复制Sub FilterRowsBottom10()
ActiveSheet.Range("A1").AutoFilter Field:=4, _
Criteria1:="10", _
Operator:=xlBottom10Items
End Sub
如果想要获取后5条记录,只需将上述代码Criteria1:="10"中的10修改为5。
示例:使用AutoFilter方法筛选前10%
数据集同上。下面的代码将提供前10%的记录(基于“数量”列):
代码语言:javascript复制Sub FilterRowsTop10Percent()
ActiveSheet.Range("A1").AutoFilter Field:=4, _
Criteria1:="10", _
Operator:=xlTop10Percent
End Sub
在我们的数据集中,由于只有16条记录,它将返回前2条记录(约占总记录的10%)。
示例:在自动筛选中使用通配符
数据集同上。假设想要筛选文本中包含有“机”的所有记录,可使用下面的代码:
代码语言:javascript复制Sub FilterRowsWildcard()
Worksheets("Sheet1").Range("A1").AutoFilter Field:=2, _
Criteria1:="*机"
End Sub
星号(*)可以表示任意数量的字符。因此,这将筛选出任何包含“机”的项目。
示例:复制筛选出的行到新工作表
如果不仅要根据条件筛选记录,而且要复制筛选的行,那么可以使用下面的宏。它复制筛选的行,添加新工作表,然后将这些复制的行粘贴到新工作表中。
代码语言:javascript复制Sub CopyFilteredRows()
Dim rng As Range
Dim wks As Worksheet
If Worksheets("Sheet1").AutoFilterMode = False Then
MsgBox "没有筛选行"
Exit Sub
End If
Set rng = Worksheets("Sheet1").AutoFilter.Range
Set wks = Worksheets.Add
rng.Copy Range("A1")
End Sub
上面的代码检查工作表Sheet1中是否有筛选。如果没有筛选行,显示一条消息并退出程序。如果有筛选行,则复制筛选的数据,插入新工作表,然后粘贴这些数据到新插入的工作表中。
示例:基于单元格值筛选数据
VBA自动筛选与下拉列表配合,当从下拉列表中选择项目时,会自动筛选该项目的所有记录,如下图3所示。
图3
在数据集所在的工作表代码模块中,输入下面的事件代码:
代码语言:javascript复制Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$2" Then
If Range("B2") = "全部" Then
Range("A5").AutoFilter
Else
Range("A5").AutoFilter Field:=2, Criteria1:=Range("B2")
End If
End If
End Sub
使用VBA打开/关闭自动筛选
在应用自动筛选时,可能已经存在筛选了。使用下面的代码关闭任何先前已应用的自动筛选:
代码语言:javascript复制Sub TurnOffAutoFilter()
Worksheets("Sheet1").AutoFilterMode = False
End Sub
这段代码检查整个工作表,删除已经应用的任何筛选。
如果不想关闭整个工作表中的筛选,只想关闭特定数据集中的筛选,可以使用下面的代码:
代码语言:javascript复制Sub TurnOffAutoFilter1()
If Worksheets("Sheet1").Range("A1").AutoFilter Then
Worksheets("Sheet1").Range("A1").AutoFilter
End If
End Sub
上面的代码检查是否已经存在筛选。如果筛选已经应用,它会删除它,否则它什么也不做。
类似地,如果要启用自动筛选,使用以下代码:
代码语言:javascript复制Sub TurnOnAutoFilter()
If Not Worksheets("Sheet1").Range("A4").AutoFilter Then
Worksheets("Sheet1").Range("A1").AutoFilter
End If
End Sub
实际上,上述代码会自动开关自动筛选,也就是说,当已经应用了自动筛选时会删除,而没有应用时会应用自动筛选。
检查是否已应用自动筛选
如果有一个包含多个数据集的工作表,并且希望确保知道没有筛选已经就位,则可以使用以下代码:
代码语言:javascript复制Sub CheckforFilters()
If ActiveSheet.AutoFilterMode = True Then
MsgBox "已经应用自动筛选"
Else
MsgBox "还没有应用筛选"
End If
End Sub
显示所有数据
如果已将筛选应用于数据集,并且希望显示所有数据,使用以下代码:
代码语言:javascript复制Sub ShowAllData()
If ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
End If
End Sub
上面的代码检查FilterMode属性是否为TRUE或FALSE。如果为TRUE,则表示已应用筛选,并使用ShowAllData方法显示所有数据。注意,这不会删除筛选,筛选图标仍然可用。
在受保护的工作表中使用自动筛选
默认情况下,当工作表受保护时,不能应用筛选。然而,如果已经设置了筛选,则可以启用自动筛选,以确保即使在受保护的工作表上也可以使用。
要执行此操作,选中“在保护工作表时使用自动筛选”选项,如下图4所示。
图4
虽然这在已设置了筛选时有效,但如果尝试使用VBA代码添加自动筛选,它将不起作用。由于工作表受到保护,因此不允许运行任何宏并对自动筛选进行更改。因此,需要使用代码来保护工作表,并确保在其中启用了自动筛选。这在创建动态筛选时是有用的。
下面的代码保护工作表,同时允许在其中使用筛选和VBA宏。
代码语言:javascript复制Private Sub Workbook_Open()
With Worksheets("Sheet1")
.EnableAutoFilter = True
.Protect Password:="123", Contents:=True, _
UserInterfaceOnly:=True
End With
End Sub
注意,这段代码放置在ThisWorkbook代码模块中,因此当工作簿打开时就会自动执行。
代码指定“EnableAutoFilter=True”,意味着筛选也将在受保护的工作表中工作。此外,它将“UserInterfaceOnly”参数设置为“True”,意味着当工作表受到保护时,VBA宏代码将继续工作。
结语
自动筛选功能非常简单,使用内置筛选功能可轻松完成。然而,为什么需要使用VBA代码来执行此操作?因为将其与其它代码结合起来,可以创建更加强大的自动化工作。
注:本文学习整理自trumpexcel.com,略有修改。
文章中所使用的示例数据和代码可到知识星球App完美Excel社群下载。