这是一个有时会出现的问题(例如:参见here和here)并且几乎总是根据一些循环给出解决方案(使用AutoFilter()
本身或数组)
由于某些原因,Excel开发人员将AutoFilter
自定义数组标准限制为最多两个,因此以下操作无效:
Dim filterNotCriteria = Array("<>A","<>B","<>C")
someRange.AutoFilter field:=1, Criteria1:=filterNotCriteria, Operator:=xlFilterValues
虽然我认为将AutoFilter()
功能完全提供是非常有用的,因为它的“非定制”对应物
所以,在等待Excel开发人员添加它(或修复它,因为它看起来更像是一个bug)时,我会把这个问题作为一个公共调查开始(不确定这是否是合适的方式)从性能和可用性的角度来看,最好的VBA修复
我正在添加第一个回答来开始滚球
我的第一个想法是坚持使用AutoFilter()
,从中受益
使用一些反向思想,步骤将是:
如下:
Option Explicit
Function AutoFilterNot(rngToFilter As Range, fieldToFilterOn As Long, filterNotCriteria As Variant) As Range
Dim notRng As Range ' helper range variable
With rngToFilter ' reference wanted range to filter, headers row included
.AutoFilter field:=fieldToFilterOn, Criteria1:=filterNotCriteria, Operator:=xlFilterValues ' filter on "not wanted" values
If Application.Subtotal(103, .Resize(, 1)) > 1 Then ' if any filtered cell other than header row
Set notRng = .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible) ' temporarily set 'myRng' to "not wanted" rows
.Parent.AutoFilterMode = False ' remove filters and show all rows
notRng.EntireRow.Hidden = True ' leave "wanted" rows only visible
Set AutoFilterNot = .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible) ' get referenced range "wanted" rows
.EntireRow.Hidden = False ' unhide all referenced range rows
Else
.Parent.AutoFilterMode = False ' remove filters
End If
End With
End Function
并且可以在一些“主要”代码中使用,如下所示:
Dim filteredRng As Range
Set filteredRng = AutoFilterNot(Range("A1:C200"), 2, Array("B102", "A107"))