在数据透视 + VBA + 动态解决方案中运行所有可能的页面过滤器组合

Posted

技术标签:

【中文标题】在数据透视 + VBA + 动态解决方案中运行所有可能的页面过滤器组合【英文标题】:Run all possible combination of page filters in a pivot + VBA + Dynamic Solution 【发布时间】:2013-04-28 19:50:01 【问题描述】:

我正在尝试创建一个动态的宏并运行所有可能的页面过滤器组合并生成报告。

现在,我只有两个过滤器:AccountManager 和 CostCenter,下面的宏会遍历 AccountManager 的所有值及其对应的 CostCenter 值并准备报告。

Sub Run_All_Reports()
    Dim PT As PivotTable
    Dim PF As PivotField
    Dim PI As PivotItem, PI2 As PivotItem

    Sheets("Pivot").Activate
    Set PT = ActiveSheet.PivotTables("Budget")

    For Each PI In PT.pageFields(1).PivotItems
        PT.pageFields(1).CurrentPage = PI.Name
        For Each PI2 In PT.pageFields(2).PivotItems
            PT.pageFields(2).CurrentPage = PI2.Name
            Call Run_Report
        Next
    Next
End Sub

我不知道如何将此功能扩展为动态的,即它读取存在多少页面过滤器,然后为每个可能的组合准备报告。

比方说,我介绍另一个过滤器 - 区域。然后它应该为所有可能的组合生成报告。下面是一个例子:

John, Marketing, London
John, Marketing, NewYork
John, Sales, London
Sam, Sales, London
Sam, Sales, NewYork

不确定我是否足够清楚。我试图四处寻找,但找不到解决方案。我被问到关于 2 页过滤器的问题,我已经实施了上述解决方案,但从昨天开始我就头疼,因为我希望它在我的脑海中是动态的。

【问题讨论】:

【参考方案1】:

使用递归过程,如下所示

例如

Sub RunForALlItems(PT as pivotTable, count as integer)
numFields= PT.pageFields.count
for each PI in PT.pageFields(num).PivotItems
   PT.pageFields(num).CurrentPage = PI.Name
   if (num=numFields) then
      call run_Report
   elseif (num<numFields) then
      call RunForAllItems(PT, count+1)
   end if
next
end sub

然后调用它

RunForAllItems(PT, 1)

我没有测试过,但它应该 - 稍作调整 - 工作

【讨论】:

【参考方案2】:

这对我有用!

这将遍历所有可能的页面字段组合。我确信存在更优化的版本。但我不是计算机背景,这是我感兴趣的一个问题

Sub All_Comb()
    Dim PT As PivotTable
    Dim PI As PivotItem, PI2 As PivotItem
    Dim totPF As Integer, i As Integer
    Dim elemCountArray() As Integer

    Sheets("Pivot").Activate
    Set PT = ActiveSheet.PivotTables("Budget")
    totPF = PT.PageFields.Count

    ReDim elemCountArray(0 To totPF)
    For i = 1 To totPF
        elemCountArray(i) = PT.PageFields(i).PivotItems.Count
    Next i

    For i = 1 To totPF
        For y = 1 To elemCountArray(i)
            PT.PageFields(i).CurrentPage = PT.PageFields(i).PivotItems(y).Name
            If (i < totPF) Then
                Call SetUpFields(PT, i + 1, elemCountArray(i + 1), totPF, elemCountArray())
            End If
        Next y
    Next i
End Sub

Sub SetUpFields(PT As PivotTable, PFid As Integer, elemCount As Integer, totPF As Integer, elemCountArray() As Integer)
    For y = 1 To elemCount
        PT.PageFields(PFid).CurrentPage = PT.PageFields(PFid).PivotItems(y).Name
        If (PFid < totPF) Then
                Call SetUpFields(PT, PFid + 1, elemCountArray(PFid + 1), totPF, elemCountArray())
        End If
    Next y
End Sub

【讨论】:

以上是关于在数据透视 + VBA + 动态解决方案中运行所有可能的页面过滤器组合的主要内容,如果未能解决你的问题,请参考以下文章

你能在VBA中更改数据透视表的源代码吗?

VBA代码在数据透视表旁边的列中向下拖动公式

使用 VBA 过滤 Excel 数据透视表

同步数据透视表 - VBA 代码不起作用

VBA:根据单元格值过滤数据透视表

加快数据透视表过滤 VBA 代码