我正在尝试创建一个宏,它将允许我连续取消选择/选择特定的过滤器选项。
因此在下面的例子中,如果我单击“取消选择类型 1”,那么“类型 1”将从过滤器中删除。
如果我随后单击“取消选择类型 2”,则“类型 2”将从过滤器中取消选择,但“类型 1”也仍将被取消选择。
如果我单击“选择类型 1”,则“类型 1”将被重新选择,而“类型 2”将保持未选择状态。
我尝试使用记录宏功能,但它不适用于后续的取消选择/选择。记录宏功能与 AutoFilter 配合使用的方式是,它会识别仍处于勾选状态的选项并将其添加到数组中,而这不适用于其他按钮的后续录制。以下是录制时取消选择类型 1 时的代码,如您所见,它会将其从勾选的选项数组中删除。
'
' DeselectType1 Macro
'
'
ActiveSheet.Range("$A$1:$B$25").AutoFilter Field:=1, Criteria1:=Array( _
"Type 2", "Type 3", "Type 4"), Operator:=xlFilterValues
End Sub
有没有办法编写代码,以便从过滤器中删除特定选项?并允许删除后续选项,如我上面所述?
答案1
你问的问题并不那么简单。你不能为它录制宏,因为宏只记录你设置的最终状态,而不是你实现它的方式。其次,宏不会创建变量来存储过滤器的初始状态。
在这里,你必须先读取初始过滤器设置,然后应用所需的更改。另一个问题是,读取过滤器设置时,其内容取决于条件的数量。1、2 或 3+ 个条件有所不同。幸运的是,当你设置条件时,你可以对许多条件应用 1 个模型,当条件少于 3 个时,Excel 会在内部进行转换。
这是我的建议:
Sub Sel(item As String)
Dim Crit1, Crit2, Oper As Long
If Left(item, 1) <> "=" Then item = "=" & item
ReadFilter Crit1, Crit2, Oper
If Not ActiveSheet.AutoFilterMode Then
Selection.AutoFilter Field:=1, Criteria1:=item
Else
Select Case Oper
Case 0, 1
If Crit1 = item Then Exit Sub
Crit1 = Array(Crit1, item)
Oper = 7
Case 2
If Crit1 = item Or Crit2 = item Then Exit Sub
Crit1 = Array(Crit1, Crit2, item)
Oper = 7
Case 7
Dim d As Long
d = UBound(Crit1)
ReDim Preserve Crit1(d + 1)
Crit1(d + 1) = item
End Select
Selection.AutoFilter Field:=1, Criteria1:=Crit1, _
Operator:=Oper, Criteria2:=Crit2
End If
End Sub
Sub DeSel(item As String)
Dim Crit1, Crit2, Oper As Long
If Left(item, 1) <> "=" Then item = "=" & item
ReadFilter Crit1, Crit2, Oper
If Not ActiveSheet.AutoFilterMode Then Exit Sub
Select Case Oper
Case 0
If Crit1 = Empty Then
Crit1 = Filter(AllItems, item, False)
Oper = 7
End If
Case 1
If Crit1 = item Then
Selection.AutoFilter Field:=1
End If
Exit Sub
Case 2
If Crit1 <> item And Crit2 <> item Then Exit Sub
If item = Crit1 Then Crit1 = Crit2
Crit2 = Empty
Case 7
Crit1 = Filter(Crit1, item, False)
End Select
Selection.AutoFilter Field:=1, Criteria1:=Crit1, _
Operator:=Oper, Criteria2:=Crit2
End Sub
Private Sub ReadFilter(Crit1, Crit2, Oper As Long)
If ActiveSheet.AutoFilterMode Then
If Intersect(ActiveSheet.AutoFilter.Range.Columns(1), _
Selection.CurrentRegion.Columns(1)) Is Nothing Then
ActiveSheet.AutoFilterMode = False
End If
End If
If ActiveSheet.AutoFilterMode Then
If ActiveSheet.AutoFilter.Filters(1).On Then
On Error Resume Next
With ActiveSheet.AutoFilter.Filters(1)
Crit1 = .Criteria1
Oper = .Operator
Crit2 = .Criteria2
End With
On Error GoTo 0
End If
End If
End Sub
Private Function AllItems()
Dim rng As Range, arr
Set rng = ActiveSheet.AutoFilter.Range.Columns(1)
Set rng = rng.Offset(1).Resize(rng.Rows.Count - 1) 'without header
arr = rng.Parent.Evaluate(""" ="" & " & rng.Address)
AllItems = Application.Transpose(arr)
End Function
选择或取消选择项目的过程需要参数。当您将宏分配给按钮时,您必须提供此参数,例如对于选择类型 1,您应该使用:
'Sel "Type 1"'
对于取消选择类型 2:
'DeSel "Type 2"'
整个短语必须用单引号括起来(由于参数的原因)。
要使其工作,您必须将光标放在数据区域中,自动过滤应打开,并且您应用过滤器的列应为过滤区域中的第一列。