【问题标题】:Select/Deselect all Pivot Items选择/取消选择所有枢轴项目
【发布时间】:2015-02-13 15:37:40
【问题描述】:

我有一个数据透视表,我正在尝试根据数组中的值选择某些数据透视项目。我需要这个过程更快,所以我尝试使用Application.Calculation = xlCalculationManualPivotTables.ManualUpdate = True,但似乎都不起作用;每次更改数据透视表时,数据透视表仍会重新计算。

我可以采取不同的措施来防止 Excel 每次都重新计算吗? 或者有没有办法一次(而不是单独)取消选择所有项目以加快处理速度?

这是我的代码:

Application.Calculation = xlCalculationManual

'code to fill array with list of companies goes here    

Dim PT As Excel.PivotTable
Set PT = Sheets("LE Pivot Table").PivotTables("PivotTable1")

Sheets("LE Pivot Table").PivotTables("PivotTable1").ManualUpdate = True
Dim pivItem As PivotItem

'compare pivot items to array.  
'If pivot item matches an element of the array, make it visible=true, 
'otherwise, make it visible=false
For Each pivItem In PT.PivotFields("company").PivotItems
    pivItem.Visible = False 'initially make item unchecked
    For Each company In ArrayOfCompanies()
        If pivItem.Value = company Then
            pivItem.Visible = True
        End If
    Next company
Next pivItem

【问题讨论】:

  • 尝试只计算公式(pivItem.Formula)然后计算。我有同样的问题,功能非常慢,所以我无法解决。
  • 您只需要数据透视表中的值吗?你能做一个.PasteSpecial xlPasteValues 然后做你的查找数组吗?
  • 哪个版本的 Excel 以及数据透视表中的数据透视字段在哪里? (顺便说一句,你真的应该在pivItem.Visible = True 行之后有一个Exit For
  • -我正在研究 pivItem.Formula 部分。 -我需要数据透视表中的值根据数组中的值进行更改。用户选择他想查看的公司,宏用这些选择填充数组,然后根据数组更新数据透视表 - 我使用的是 Excel 2010。数据透视字段位于行标签部分非常感谢您的帮助和回应!

标签: vba excel pivot-table pivotitem


【解决方案1】:

您似乎真的想尝试一些不同的东西来显着减少在数据透视表中选择所需项目所需的时间。 我建议使用“MirrorField”,即“公司”的副本,用于在数据透视表的源数据中设置您需要隐藏\显示的项目。

首先,您需要手动(或以编程方式)添加“MirrorField”并命名为与源字段相同的名称,开头带有特殊字符,例如“!Company”,该项目必须是源数据的一部分,并且可以放置在它的任何一列(因为这将是一个“程序员”字段,所以我会将它放在最后一列中,并且可能隐藏起来,以免给用户造成任何问题)

请在下面找到更新数据透视表数据源和刷新数据透视表的代码

我还要求更新 PivotField,使其灵活,因为它可以用于任何字段(前提是“FieldMirror”已经创建) 最后:如果您在数据透视表工作表中运行任何事件,它们应该被禁用并启用仅在最后一次数据透视表更新时运行

希望这是您正在寻找的。​​p>

Sub Ptb_ShowPivotItems_MirrorField(vPtbFld As Variant, aPtbItmSelection As Variant)
Dim oPtb As PivotTable
Dim rPtbSrc As Range
Dim iCol(2) As Integer
Dim sRC(2) As String
Dim sFmlR1C1 As String
Dim sPtbSrcDta As String

    Rem Set PivotTable & SourceData
    Set oPtb = ActiveSheet.PivotTables(1)
    sPtbSrcDta = Chr(34) & oPtb.SourceData & Chr(34)
    Set rPtbSrc = Evaluate("=INDIRECT(" & sPtbSrcDta & ",0)")

    Rem Get FieldMirrow Position in Pivottable SourceData (FieldMirrow Already present SourceData)
    With rPtbSrc
        iCol(1) = -1 + .Column + Application.Match(vPtbFld, .Rows(1), 0)
        iCol(2) = Application.Match("!" & vPtbFld, .Rows(1), 0)
    End With

    Rem Set FieldMirror Items PivotTable SourceData as per User Selection
    sRC(1) = """|""&RC" & iCol(1) & "&""|"""
    sRC(2) = """|" & Join(aPtbItmSelection, "|") & "|"""
    sFmlR1C1 = "=IF(ISERROR(SEARCH(" & sRC(1) & "," & sRC(2) & ")),""N/A"",""Show"")"
    With rPtbSrc.Offset(1).Resize(-1 + rPtbSrc.Rows.Count).Columns(iCol(2))
        .Value = "N/A"
        .FormulaR1C1 = sFmlR1C1
        .Value = .Value2
    End With

    Rem Refresh PivotTable & Select FieldMirror Items
    With oPtb

        Rem Optional: Disable Events - In case you are running any events in the pivottable worksheet
        Application.EnableEvents = False

        .ClearAllFilters
        .PivotCache.Refresh
        With .PivotFields("!" & vPtbFld)
            .Orientation = xlPageField
            .EnableMultiplePageItems = False

            Rem Optional: Enable Events - To triggrer the pivottable worksheet events only with last update
            Application.EnableEvents = True
            .CurrentPage = "Show"

    End With: End With

End Sub

【讨论】:

    【解决方案2】:

    每次更新数据透视项时都刷新数据透视表似乎是不可避免的。 但是我尝试从相反的角度解决问题。即:

    1.在更新数据透视表之前验证“要隐藏的数据透视项”

    2.同时使所有项目一次可见,而不是“最初取消选中项目”。

    3.然后隐藏用户未选择的所有项目(要隐藏的PivotItems)

    我对总共 11 家公司中选出的 6 家公司进行了测试,数据透视表更新了 7 次

    在相同情况下也运行了您的原始代码,并且数据透视表更新了 16 次 在下面找到代码

    Sub Ptb_ShowPivotItems(aPtbItmSelection As Variant)
    
    Dim oPtb As PivotTable
    Dim oPtbItm As PivotItem
    Dim aPtbItms() As PivotItem
    Dim vPtbItm As Variant
    Dim bPtbItm As Boolean
    Dim bCnt As Byte
    
        Set oPtb = ActiveSheet.PivotTables(1)
    
        bCnt = 0
        With oPtb.PivotFields("Company")
    
            ReDim Preserve aPtbItms(.PivotItems.Count)
            For Each oPtbItm In .PivotItems
    
                bPtbItm = False
                For Each vPtbItm In aPtbItmSelection
                    If oPtbItm.Name = vPtbItm Then
                        bPtbItm = True
                        Exit For
                End If: Next
    
                If Not (bPtbItm) Then
                    bCnt = 1 + bCnt
                    Set aPtbItms(bCnt) = oPtbItm
                End If
    
            Next
            ReDim Preserve aPtbItms(bCnt)
    
            .ClearAllFilters
            For Each vPtbItm In aPtbItms
                vPtbItm.Visible = False
            Next
    
        End With
    
    End Sub
    

    【讨论】:

      猜你喜欢
      • 2022-10-12
      • 1970-01-01
      • 2018-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多