Excel VBA 代码将过滤器设置为一系列选项

Posted

技术标签:

【中文标题】Excel VBA 代码将过滤器设置为一系列选项【英文标题】:Excel VB Code to Set Filter to a range of Options 【发布时间】:2016-03-25 16:26:04 【问题描述】:

我目前有一个从 SharePoint 网站提取数据的数据透视表。有了这个数据透视表,我想使用一个按钮将过滤器设置为某个日期范围。我用这个网站获取过滤器,将Filter值更改为某个日期,代码如下:

Sheets("Sheet2").Select
ActiveSheet.PivotTables("PivotTable1").PivotFields("Date").ClearAllFilters
ActiveSheet.PivotTables("PivotTable1").PivotFields("Date").CurrentPage = Date

这很适合将过滤器重置为当前日期,但我似乎找不到任何方法可以将过滤器设置为过去 5、10 或 15 天的所有日期,甚至将过滤器设置为当月的所有日期。

任何帮助将不胜感激。

【问题讨论】:

你能把示例数据贴出来,用那个更容易测试你的代码 【参考方案1】:

鉴于您正在尝试将日期范围应用于您的 ReportFilter(如 .CurrentPage = Date 所证明的那样,您需要遍历日期 PivotFields 中的所有 PivotItems 并针对您的日期范围进行测试。

如下所示(未经测试):

Dim ws as Worksheet, pt as PivotTable, pf as PivotField, pi as PivotItem
Dim dStart as Date, dEnd as Date

dStart = #1/1/2015#
dEnd = #1/31/2015#

Set ws = Sheets("Sheet2")
Set pt = ws.PivotTables("PivotTable1")
Set pf = pt.PivotFields("Date")

With pf
   .ClearAllFilters
   For each pi in pf.PivotItems
      If pi.Value > = dStart And pi.Value <= dEnd Then 
         pi.Visible = True 'or maybe pi.Selected = True
      Else
         pi.Visible = False 'or maybe pi.Selected = False
      End If
   Next
End With

【讨论】:

Scott:遍历 PivotItems 非常慢:根据我在 dailydoseofexcel.com/archives/2013/11/14/… 的帖子,即使对于小型数据透视表,这也可能需要很多分钟,即使在运行所有数据透视表之前打开 pt.ManualUpdate = True遵循 sn-ps,这样数据透视表就不会在每次更改后都尝试更新。 抱歉,应该是这样的:遍历 PivotItems 非常慢:根据我在 dailydoseofexcel.com/archives/2013/11/14/ 上的帖子,对于中等大小的 PivotField,这可能需要几分钟(例如,字段中有 20,000 个项目)即使您在运行代码时设置 pt.ManualUpdate = True。当然,您不会经常遇到包含数百个离散日期的数据透视表。但总的来说,当您可以使用“介于”过滤器时,避免迭代是值得的。 @jeffreyweir - 请删除您的反对票。在代码中,OP 演示了他正在询问过滤 ReportFilter(参见 .CurrentPage = Date),而不是 ColumnRow Labels 上的过滤器。如果它在Column / Row Labels 中,您的评论将是有意义的,但鉴于您在ReportFilter 部分过滤日期时不能使用Between,您的评论不适用。但是,感谢您的说明,我确实使我的答案更加清晰,这有帮助:) @ScottHoltzman - 谢谢。你提供的效果很好。我什至可以稍微修改一下,让它输入当前日期和当前日期——5、10 或 15 天。我唯一要解决的是过滤完成时发生的类型不匹配错误。有什么建议吗? 斯科特:你是对的。时间线允许您设置介于日期之间,因此我将发布一些使用它们的代码。但是,您的代码可以在相当大的枢轴上显着提高效率。首先,您应该在循环之前将 .ManualUpdate 设置为 TRUE,否则数据透视表将在每个项目被隐藏/取消隐藏后刷新。其次,您应该测试是否需要更改 .visible 状态,因为更改 .visible 状态比读取它需要更长的时间。您的代码可以工作,但两个简单的调整会使其工作效率提高一个数量级。【参考方案2】:

Emmerson:你没有说你有什么版本的 Excel。我正在使用 Excel 360,它为我提供了几种直接在日期范围内过滤数据透视表的方法。

首先,如果您的日期字段恰好位于“行”或“列”区域(但不是在您的特定情况下的“过滤器/页面”区域),则“过滤器”下拉列表中可以使用“日期过滤器”选项:

其次,在 Excel 2013 或更高版本中有时间线:

正如 Scott 在上面的 cmets 中所说的那样,如果您要过滤的 PivotField 不是 PageField,即它不在 PivotTable Fields 列表的 Filters 窗格中,第一个选项仅直接有效。因为如果它在“过滤器”窗格中,那么您将看不到上面显示的任何过滤器选项,如下面的屏幕截图所示:

但有一个简单的解决方法:只需将其完全拖出数据透视表,因为您实际上仍然可以过滤不在数据透视表中的字段:

在我设置“Between”过滤器时启动宏记录器会产生以下代码:

ActiveSheet.PivotTables("PivotTable1").PivotFields("Date").PivotFilters.Add2 _
        Type:=xlDateBetween, Value1:="23/12/2015", Value2:="31/12/2015"

这是一个通用版本,它将任何日期数据透视字段过滤到您想要的任何最后一个 X:

Sub LastXDays(lDays As Long, Optional pf As PivotField)

Dim StartDate As Date
Dim EndDate As Date
EndDate = Date
StartDate = EndDate - lDays + 1
If pf Is Nothing Then
    On Error Resume Next
    Set pf = ActiveCell.PivotField
    If Err.Number <> 0 Then GoTo errhandler

    On Error GoTo errhandler
End If
If Not IsDate(pf.PivotItems(1)) Then GoTo errhandler
pf.ClearAllFilters
pf.PivotFilters.Add2 _
    Type:=xlDateBetween, _
    Value1:=CStr(StartDate), _
    Value2:=CStr(EndDate)

errhandler:

End Sub 

您可以使用以下方式调用该例程:

Sub Last5Days()
LastXDays 5, ActiveSheet.PivotTables("PivotTable1").PivotFields("Date")
End Sub

如果不清楚您是否需要更多帮助来实施此操作,请回复。

【讨论】:

以上是关于Excel VBA 代码将过滤器设置为一系列选项的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Excel 2007 VBA 中使用 Option Strict Off 进行后期绑定

VBA Excel to Word - 对于下一个循环随机跳过数据

Excel VBA打印机API,设置颜色和双工

Excel VBA - 基于活动单元格运行宏

复制自动过滤范围,vba excel

怎么用vba给excel 加密