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
),而不是 Column
或 Row 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 进行后期绑定