【问题标题】:Unfiltering all row data in Pivot Table then filter for specific values取消过滤数据透视表中的所有行数据,然后过滤特定值
【发布时间】:2019-01-15 17:20:22
【问题描述】:

我的组织有大约 100 个部门。这些是我的数据透视表中的行。我每周使用 VBA 在新的数据转储上创建一个新的数据透视表。我的问题是一年几次删除或添加新的部门。我当前的数据透视表仅使用 15 个部门,但我的代码受到所有约 100 个部门的影响。 (我下面的代码只显示了一部分以节省空间)

我已经尝试在网上搜索了几个小时,并使用了比我目前使用的更好的解决方案的宏记录器。

With ActiveSheet.PivotTables("PivotTable1").PivotFields("Flex Division - Text")
.PivotItems("03").Visible = False
.PivotItems("04").Visible = False
.PivotItems("05").Visible = False
.PivotItems("07").Visible = False
.PivotItems("1A").Visible = False
.PivotItems("1B").Visible = False
.PivotItems("1C").Visible = False
.PivotItems("1F").Visible = False
.PivotItems("1G").Visible = False
.PivotItems("1J").Visible = False
.PivotItems("1K").Visible = False
.PivotItems("(blank)").Visible = False
End With

上面的代码过滤掉了不使用的分区。我想做相反的事情。我想取消过滤所有部门,然后重新添加我使用的部门。这将避免将来的代码调整。

【问题讨论】:

  • “unfilter”是什么意思?让它们全部可见还是全部隐藏?
  • 全部隐藏。所以什么都看不到,然后添加回所需的分区。
  • @MattLane 查看我在stackoverflow.com/questions/45718045/… 的答案,它有一个快速高效的代码示例来执行此操作。

标签: excel vba pivot-table


【解决方案1】:

所以这里的第一个问题是,您不能在过滤器中创建一个没有项目的数据透视表 - 相反,创建一个包含您每次要保留的所有项目的数组,并在一个循环中检查该数组 - 如果项目在数组中,它将确保它是可见的。如果它不在那里,它会隐藏它:

Option Explicit
Sub Test()

Dim pf As PivotField
Dim pt As PivotTable
Dim pi As PivotItem
Dim keeparr As Variant

Set pt = ActiveSheet.PivotTables("PivotTable1")

'List all the item names that you want to keep in here
keeparr = Array("test1", "test2", "test3")

pt.PivotFields("Flex Division - Test").CurrentPage = "(All)"

For Each pf In pt.PageFields
    If pf = "Flex Division - Text" Then
        For Each pi In pf.PivotItems
            If IsError(Application.Match(pi, keeparr, 0)) Then
                If pi.Visible = True Then pi.Visible = False
            Else
                if pi.Visible = False Then pi.Visible = True
            End If
        Next pi
        Exit For
    End If
Next pf

End Sub

对于任何可以避免循环遍历所有 PageFields 并仅按名称解决的人,请在下面发表评论 - 我无法弄清楚。

【讨论】:

  • 单个循环的潜在问题:如果当前唯一可见的项目是不想要的项目,并且都发生在循环中任何所需的项目之前;然后,只要将最后一个可见的不想要的设置为False,数据透视表就会重置为默认的“全部”过滤器。
  • 如果速度很重要,Visible 字段的读取速度比写入速度快,因此请检查.Visible 是否应该是正确的,只有在不正确时才设置它。
  • @Mistella 很好 - 我在运行循环之前添加了一行来取消过滤所有值。
  • @Mistella 我添加了一个逻辑测试与项目的Visible 状态。
  • @MattLane 尝试将错误行切换到pt.PivotFields("Flex Division - Test").ClearAllFilters(尽管如果您有任何值过滤器,您可能希望使用.ClearLabelFilters 而不是.ClearAllFilters
【解决方案2】:

此代码应该可以满足您的需求。要了解有关快速过滤数据透视表的更多信息,请查看该主题的 my blogpost

Option Explicit

Sub FilterPivot()
Dim pt As PivotTable
Dim pf As PivotField
Dim pi As PivotItem
Dim i As Long
Dim vItem As Variant
Dim vItems As Variant

Set pt = ActiveSheet.PivotTables("PivotTable1")
Set pf = pt.PivotFields("SomeField")

vItems = Array("Item1", "Item2", "Item3")

pt.ManualUpdate = True 'Stops PivotTable from refreshing after each PivotItem is changed

With pf

    'At least one item must remain visible in the PivotTable at all times, so make the first
    'item visible, and at the end of the routine, check if it actually  *should* be visible        
    .PivotItems(1).Visible = True

    'Hide any other items that aren't already hidden.
    'Note that it is far quicker to check the status than to change it.
    ' So only hide each item if it isn't already hidden
    For i = 2 To .PivotItems.Count
        If .PivotItems(i).Visible Then .PivotItems(i).Visible = False
    Next i

    'Make the PivotItems of interest visible
    On Error Resume Next 'In case one of the items isn't found
    For Each vItem In vItems
        .PivotItems(vItem).Visible = True
    Next vItem
    On Error GoTo 0

    'Hide the first PivotItem, unless it is one of the items of interest
    On Error Resume Next
    If InStr(UCase(Join(vItemss, "|")), UCase(.PivotItems(1))) = 0 Then .PivotItems(1).Visible = False
    If Err.Number <> 0 Then
        .ClearAllFilters
        MsgBox Title:="No Items Found", Prompt:="None of the desired items was found in the Pivot, so I have cleared the filter"
    End If
    On Error GoTo 0

End With

pt.ManualUpdate = False

End Sub

【讨论】:

  • 你成功了。该代码经过一些调整即可完美运行。它找到了我的约 20 个部门,但随后将其删除。我删除了代码“If Err.Number 0 then”到 End If 的部分。感谢您的帮助!
  • 酷。我会再看看那一点的意图。
猜你喜欢
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多