自动筛选与 ShowAllData
AutoFilter vs ShowAllData
背景:
最近我知道了一个秘密的命名范围,它是通过使用 AutoFilter
创建的。通常(如果不总是)这称为“_FilterDatabase”。
我想稍微玩一下这个,但后来卡在了它所指的 Range
对象上。让我用下面的例子来解释:
测试数据:
| Header1 | Header2 |
|---------|---------|
| 50 | |
| 10 | |
| 30 | |
| 40 | |
| 20 | |
测试代码:
Sub Test()
With Sheet1
.Range("A1:B1").AutoFilter 1, ">40"
Dim rng As Range: Set rng = .Range("_FilterDatabase")
If rng.SpecialCells(12).Count > 2 Then
rng.Columns(2).Offset(1).Resize(rng.Rows.Count - 1, 1).Value = "Check"
End If
.Range("A1:B1").AutoFilter
End With
End Sub
没有结果
问题:
如果我运行上面的宏不会有结果。
问题:
问题已使用 .ShowAllData
方法而不是 .AutoFilter
解决,并且 运行 两次调用代码:
Sub Test()
With Sheet1
.Range("A1:B1").AutoFilter 1, ">30"
Dim rng As Range: Set rng = .Range("_FilterDatabase")
If rng.SpecialCells(12).Count > 2 Then
rng.Columns(2).Offset(1).Resize(rng.Rows.Count - 1, 1).Value = "Check"
End If
.ShowAllData
End With
End Sub
但是,.AutoFilter
清除过滤器并将其从我们的范围中移除。在这两种情况下,秘密命名范围将保留在名称管理器下的 Formulas
选项卡中。
有人知道为什么 ShowAllData
会影响第二个 运行 返回的命名范围吗?
我找到了我自己问题的答案(事后看来,这似乎与我的发现不符,因此我对其进行了编辑)。
根据我的问题,AutoFilter
将立即在水下创建一个秘密命名范围,通常(如果不总是)称为 "_FilterDatabase"
。我注意到以下内容:
.Range("A1:B1").AutoFilter 1, ">40" '-> Named range will refer to A1:B1
但是:
.Range("A1:B1").AutoFilter '-> Named range will refer to A1:B1
.Range("A1:B1").AutoFilter 1, ">40" '-> Named range will refer to A1:B6
这可以解释为什么我的代码末尾的 AutoFilter
使它第二次也无法正常工作。但是,由于 ShowAllData
NOT 删除实际过滤器(只是标准),它将在第二个 运行 识别范围 A1:B6
。因此,我需要做的是先设置 .AutoFilter
让命名范围选择正确的范围。现在以下工作正常:
Sub Test()
With Sheet1
.Range("A1:B1").AutoFilter
.Range("A1:B1").AutoFilter 1, ">40"
Dim rng As Range: Set rng = .Range("_FilterDatabase")
If rng.SpecialCells(12).Count > rng.Rows(1).Cells.Count Then
rng.Columns(2).Offset(1).Resize(rng.Rows.Count - 1, 1).Value = "Check"
End If
.Range("A1:B1").AutoFilter
End With
End Sub
因此,逻辑上行不通的是:
.Range("A1:B1").AutoFilter '-> Named range will refer to A1:B1
Set rng = Set rng = .Range("_FilterDatabase")
rng.AutoFilter 1, ">40" '-> rng still refers to A1:B1
简历:
AutoFilter
立即在 AutoFilter
方法上创建一个秘密命名范围。您不能直接使用条件初始化过滤器。这样做会混淆命名范围,现在只会引用第一行。它们必须按顺序使用!
有趣的是,这现在不需要知道最后使用的行来预先创建范围对象(但是,人们可能仍然更喜欢这种方法,因为数据中的间隙会导致命名范围失效).
此过滤器在不使用 AutoFilter.Range
的情况下正确过滤:
Sub test2()
Dim var As Range
Dim i As Long
With Sheets("Sheet1").Range("A1:C1")
.Range("B2:B6").Clear
.AutoFilter
.AutoFilter 1, ">50"
Set var = Sheet1.AutoFilter.Range
Set var = Intersect(var.SpecialCells(12), var.Offset(1, 0))
If Not (var Is Nothing) Then
For i = 1 To var.Areas.Count
var.Areas(i).Offset(0, 1).Resize(var.Areas(i).Rows.Count, 1).Value = "Check"
Next i
End If
.AutoFilter
End With
End Sub
背景:
最近我知道了一个秘密的命名范围,它是通过使用 AutoFilter
创建的。通常(如果不总是)这称为“_FilterDatabase”。
我想稍微玩一下这个,但后来卡在了它所指的 Range
对象上。让我用下面的例子来解释:
测试数据:
| Header1 | Header2 |
|---------|---------|
| 50 | |
| 10 | |
| 30 | |
| 40 | |
| 20 | |
测试代码:
Sub Test()
With Sheet1
.Range("A1:B1").AutoFilter 1, ">40"
Dim rng As Range: Set rng = .Range("_FilterDatabase")
If rng.SpecialCells(12).Count > 2 Then
rng.Columns(2).Offset(1).Resize(rng.Rows.Count - 1, 1).Value = "Check"
End If
.Range("A1:B1").AutoFilter
End With
End Sub
没有结果
问题:
如果我运行上面的宏不会有结果。
问题:
问题已使用 .ShowAllData
方法而不是 .AutoFilter
解决,并且 运行 两次调用代码:
Sub Test()
With Sheet1
.Range("A1:B1").AutoFilter 1, ">30"
Dim rng As Range: Set rng = .Range("_FilterDatabase")
If rng.SpecialCells(12).Count > 2 Then
rng.Columns(2).Offset(1).Resize(rng.Rows.Count - 1, 1).Value = "Check"
End If
.ShowAllData
End With
End Sub
但是,.AutoFilter
清除过滤器并将其从我们的范围中移除。在这两种情况下,秘密命名范围将保留在名称管理器下的 Formulas
选项卡中。
有人知道为什么 ShowAllData
会影响第二个 运行 返回的命名范围吗?
我找到了我自己问题的答案(事后看来,这似乎与我的发现不符,因此我对其进行了编辑)。
根据我的问题,AutoFilter
将立即在水下创建一个秘密命名范围,通常(如果不总是)称为 "_FilterDatabase"
。我注意到以下内容:
.Range("A1:B1").AutoFilter 1, ">40" '-> Named range will refer to A1:B1
但是:
.Range("A1:B1").AutoFilter '-> Named range will refer to A1:B1
.Range("A1:B1").AutoFilter 1, ">40" '-> Named range will refer to A1:B6
这可以解释为什么我的代码末尾的 AutoFilter
使它第二次也无法正常工作。但是,由于 ShowAllData
NOT 删除实际过滤器(只是标准),它将在第二个 运行 识别范围 A1:B6
。因此,我需要做的是先设置 .AutoFilter
让命名范围选择正确的范围。现在以下工作正常:
Sub Test()
With Sheet1
.Range("A1:B1").AutoFilter
.Range("A1:B1").AutoFilter 1, ">40"
Dim rng As Range: Set rng = .Range("_FilterDatabase")
If rng.SpecialCells(12).Count > rng.Rows(1).Cells.Count Then
rng.Columns(2).Offset(1).Resize(rng.Rows.Count - 1, 1).Value = "Check"
End If
.Range("A1:B1").AutoFilter
End With
End Sub
因此,逻辑上行不通的是:
.Range("A1:B1").AutoFilter '-> Named range will refer to A1:B1
Set rng = Set rng = .Range("_FilterDatabase")
rng.AutoFilter 1, ">40" '-> rng still refers to A1:B1
简历:
AutoFilter
立即在 AutoFilter
方法上创建一个秘密命名范围。您不能直接使用条件初始化过滤器。这样做会混淆命名范围,现在只会引用第一行。它们必须按顺序使用!
有趣的是,这现在不需要知道最后使用的行来预先创建范围对象(但是,人们可能仍然更喜欢这种方法,因为数据中的间隙会导致命名范围失效).
此过滤器在不使用 AutoFilter.Range
的情况下正确过滤:
Sub test2()
Dim var As Range
Dim i As Long
With Sheets("Sheet1").Range("A1:C1")
.Range("B2:B6").Clear
.AutoFilter
.AutoFilter 1, ">50"
Set var = Sheet1.AutoFilter.Range
Set var = Intersect(var.SpecialCells(12), var.Offset(1, 0))
If Not (var Is Nothing) Then
For i = 1 To var.Areas.Count
var.Areas(i).Offset(0, 1).Resize(var.Areas(i).Rows.Count, 1).Value = "Check"
Next i
End If
.AutoFilter
End With
End Sub