4

如果我在输入表上应用自动过滤器,然后运行 ​​VBA 代码,则代码不关心自动过滤器。

但是,有时在自动过滤的工作表上运行 VBA 代码会弄乱程序的结果。

所以,我的问题是;VBA 关心自动过滤器吗?

例如:

Sub check()
    Dim rng as range
    Set rng = Sheets("input").Range("A1")
    row = 0
    Do until rng.offset(row,0) = ""
        row = row + 1
    Loop
End Sub

在上面的代码中,VBA 并不关心是否在 A 列上应用了自动过滤器,它仍然会遍历所有行。但是,如果我尝试在有自动过滤器的单元格上书写它就会搞砸。

4

1 回答 1

8

VBA 不关心自动过滤器,除非您“告诉它”或尝试执行可能受自动过滤器影响的操作。

上面的代码将适用于任何工作表,而不仅仅是“输入”工作表。

这是另一种效果很好的方法(实际上我一直都在使用它)

'~~> Remove any filters
ActiveSheet.AutoFilterMode = False

'~~> Filter, offset(to exclude headers) and delete visible rows   
With rRange 
  .AutoFilter Field:=1, Criteria1:=strCriteria
  .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With

'~~> Remove any filters
ActiveSheet.AutoFilterMode = False

这是一个不起作用的场景。

图表不显示自动过滤器过滤的数据。但是图表也没有显示隐藏行中存在的数据。这适用于在图表中显示数据的 VBA 和非 VBA 方法

但是如果我尝试在应用了自动过滤器的特定单元格上写,它就会搞砸。

这取决于您编写它的方式和位置。

这很好用。请注意,在下面的代码中,行已被过滤并且不可见。但是,我们仍然可以写入它。

Option Explicit

Sub Sample()
    Dim rng As Range

    Set rng = Sheets("Sheet1").Range("A1")

    rng.AutoFilter Field:=1, Criteria1:="<>1", Operator:=xlAnd

    rng.Offset(1, 0).Value = "Sidd"
End Sub

在此处输入图像描述

现在让我们来看另一个案例。这行不通。假设您有一个 A2 到 A10 的范围(A1 有 Header),它具有从 1 到 3 的各种值。现在您想用 1000 替换 A2:A10 中的所有值。如果出现此代码,则此代码不会给您预期的输出有一个自动过滤器。它不会改变所有的细胞。

Option Explicit

Sub Sample()
    Dim rng As Range

    Set rng = Sheets("Sheet1").Range("A1:A10")

    rng.AutoFilter Field:=1, Criteria1:="<>1", Operator:=xlAnd

    rng.Value = "1000"
End Sub

为什么它会忽略具有“1”的单元格(即被过滤掉的行)并写入其余行?实际上它也与标题混淆了???

在此处输入图像描述

这很简单。拥有 Autofilter 的想法是根据我们的要求获取相关数据(目前它是 <> 1 的数据)。当您写入该范围rng时,它将写入该范围内所有可见的单元格(包括具有标题的单元格)。

那么在这种情况下我们该怎么办呢?

你有两个选择

1)移除自动过滤器 - 执行必要的操作 - 将过滤器放回原处

Sub Sample()
    Dim rng As Range

    Set rng = Sheets("Sheet1").Range("A1:A10")

    '~~> Put Filter
    rng.AutoFilter Field:=1, Criteria1:="<>1", Operator:=xlAnd

    '~~> Remove Filter
    ActiveSheet.AutoFilterMode = False

    '~~> Write value to the cells (See how we ignore the header)
    Sheets("Sheet1").Range("A2:A10").Value = "1000"

    '~~> Put Filter back
    rng.AutoFilter Field:=1, Criteria1:="<>1", Operator:=xlAnd
End Sub

2)像您在问题中所做的那样循环范围

Sub Sample()
    Dim rng As Range, cl As Range

    Set rng = Sheets("Sheet2").Range("A1:A10")

    rng.AutoFilter Field:=1, Criteria1:="<>1", Operator:=xlAnd

    For Each cl In rng
        '~~> Ignoring the Header
        If cl.Row <> 1 then _
        cl.Value = "1000"
    Next
End Sub

当您运行上述代码时,它会写入除标题之外的所有单元格。

我建议您阅读 Excel 的内置帮助,以了解自动筛选器的实际工作原理。这将帮助您了解它们,进而帮助您处理已打开自动过滤器的工作表。

高温高压

于 2012-04-24T06:51:11.590 回答