使用 Excel VBA 自动筛选时如何删除空白行
我编写了一个宏,可以搜索工作簿并将自动筛选器应用于具有名为“Code”列的任何列表对象。但是,当我应用过滤器时,它不会过滤掉空白行。知道如何过滤掉这些吗?
下面是应用过滤器的代码:
Public Sub ApplyFilter(filter As Variant)
Dim wb As Workbook
Dim ws As Worksheet
Dim lo As ListObject
Set wb = ActiveWorkbook
' Loop through each sheet in the workbook
For Each ws In wb.Sheets
' Find any listobjects within the sheet
For Each lo In ws.ListObjects
Dim r As Integer
' Find the column named Code and filter on this column
r = lo.Range.Rows(1).Find("Code").Column
' Clear any existing filter
lo.Range.AutoFilter Field:=r
' If the filter code is not "All Categories", 999, apply the filter
If filter(0) <> 999 Then
lo.Range.AutoFilter Field:=r, Criteria1:=filter, Operator:=xlFilterValues
End If
Next
Next
End Sub
传入的过滤器是一个数组,可能只有一个条件,也可能有多个条件。我也尝试添加 criteria2:="",但这并没有改变任何东西。
如果您有任何想法,请告诉我。谢谢!
这是其他相关代码:
Public Sub FilterInvoice(filter As Range)
Me.ApplyFilter Me.BuildFilter(filter)
End Sub
Public Function BuildFilter(filter As Range) As Variant
Dim r As Range
Dim arFilter() As String
' Get the cell of the current category
Set r = Range("Categories").Find(filter.Value)
' Set the initial filter value to the category id
ReDim Preserve arFilter(1)
arFilter(0) = r.Offset(0, -1).Value
' Find any child categories, add child id's to filter array
For c = 1 To Application.CountIf(Range("Categories").Columns(3), arFilter(0))
Dim PrevChild As Range
' Expand the filter array
ReDim Preserve arFilter(c + 1)
If c = 1 Then
Set PrevChild = Range("Categories").Columns(3).Find(arFilter(0))
Else
' If it is not the first time through the loop, look for the next child after PrevChild
Set PrevChild = Range("Categories").Columns(3).Find(arFilter(0), PrevChild)
End If
' Offset the found child to get its code, add it to the filter array
arFilter(c) = PrevChild.Offset(, -2)
Next
' Add "<>" and "<900" to the criteria list to hide blank rows
'ReDim Preserve arFilter(UBound(arFilter) + 2)
'arFilter(UBound(arFilter) - 1) = "<>"
'arFilter(UBound(arFilter)) = "<900"
'Return the filter array
BuildFilter = arFilter
End Function
I have written a macro that searches through workbook and applies an autofilter to any listobjects which have a column named "Code". However, when I apply the filter, it does not filter out the blank rows. Any idea on how I can filter these out?
Here is the code which applies the filter:
Public Sub ApplyFilter(filter As Variant)
Dim wb As Workbook
Dim ws As Worksheet
Dim lo As ListObject
Set wb = ActiveWorkbook
' Loop through each sheet in the workbook
For Each ws In wb.Sheets
' Find any listobjects within the sheet
For Each lo In ws.ListObjects
Dim r As Integer
' Find the column named Code and filter on this column
r = lo.Range.Rows(1).Find("Code").Column
' Clear any existing filter
lo.Range.AutoFilter Field:=r
' If the filter code is not "All Categories", 999, apply the filter
If filter(0) <> 999 Then
lo.Range.AutoFilter Field:=r, Criteria1:=filter, Operator:=xlFilterValues
End If
Next
Next
End Sub
The filter that is passed in is an array which may just have one criteria, or many. I have also tried adding criteria2:="", but that did not change anything.
Let me know if you have any ideas. Thanks!
Here is the other related code:
Public Sub FilterInvoice(filter As Range)
Me.ApplyFilter Me.BuildFilter(filter)
End Sub
Public Function BuildFilter(filter As Range) As Variant
Dim r As Range
Dim arFilter() As String
' Get the cell of the current category
Set r = Range("Categories").Find(filter.Value)
' Set the initial filter value to the category id
ReDim Preserve arFilter(1)
arFilter(0) = r.Offset(0, -1).Value
' Find any child categories, add child id's to filter array
For c = 1 To Application.CountIf(Range("Categories").Columns(3), arFilter(0))
Dim PrevChild As Range
' Expand the filter array
ReDim Preserve arFilter(c + 1)
If c = 1 Then
Set PrevChild = Range("Categories").Columns(3).Find(arFilter(0))
Else
' If it is not the first time through the loop, look for the next child after PrevChild
Set PrevChild = Range("Categories").Columns(3).Find(arFilter(0), PrevChild)
End If
' Offset the found child to get its code, add it to the filter array
arFilter(c) = PrevChild.Offset(, -2)
Next
' Add "<>" and "<900" to the criteria list to hide blank rows
'ReDim Preserve arFilter(UBound(arFilter) + 2)
'arFilter(UBound(arFilter) - 1) = "<>"
'arFilter(UBound(arFilter)) = "<900"
'Return the filter array
BuildFilter = arFilter
End Function
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您使用数组按多个条件进行过滤,则通过不包含“=”,自动过滤器应该过滤空白。例如,这不会过滤空白:
如果失败,您可能需要使用特殊单元格(xlcelltypeblanks)手动隐藏它们。
编辑:
好吧,我想我可能让你对我的第一个解决方案感到困惑。我已经把它删除了。
现在我可以看到您的代码,我认为可能发生的情况是,当您循环遍历范围并添加条件时,您可能会添加一个空白单元格。一次一个地执行循环并确保情况并非如此。您可以添加此内容以显示过滤器并确保它不包含空格:
Debug.Print Join(arfilter, ",")
If you are filtering by multiple criteria using an array then by not including "=" the autofilter should filter the blanks. For example this will NOT filter blanks:
Failing that you may need to hide them manually using specialcells(xlcelltypeblanks).
EDIT:
Okay I think I might have confused you there with my first solution. I have removed it.
Now that I can see your code I think what might be happening is that as you are looping through the range and adding your criteria you are probably adding a blank cell. Step through the loop one at a time and make sure this is not the case. You could add this to display the filter and make sure it does not contain blanks:
Debug.Print Join(arfilter, ",")
我知道这是一个老问题,但我在互联网上找不到任何令人满意的答案
所以我想分享一个似乎效果很好的解决方案:
空白单元格仍然存在,所以我们不需要将它们过滤掉
当然因为它使用 xlFilterValues,所以您也可以使用数组过滤器
希望您喜欢!
I know this is an old question but I coudln't find any satisfying answer anywhere on the Internet
So I'd like to share a solution which seems to work pretty well:
blank cells are still present so we need no filter them out
Of course because it uses xlFilterValues you can use an Array filter as well
Hope you enjoy!