Vba AddDataField从“中删除字段”;“报告过滤器”;

Vba AddDataField从“中删除字段”;“报告过滤器”;,vba,excel,macros,excel-2010,Vba,Excel,Macros,Excel 2010,为什么pivot表的AddDataField()方法会从“报表过滤器”中删除该字段?我使用GUI创建了一个新的透视表,并录制了一个宏。一切进展顺利,只是宏本身不工作。如何使用VBA(我只能使用GUI)向“报表过滤器”和值添加字段 这是我录制的宏。您可以在A1激活的空白工作表上测试运行此功能。最后一个命令从“报告过滤器”中删除该字段,即使在录制宏和使用GUI时一切正常。这真让我受不了 Option Explicit Sub Macro8() ' ' Macro8 Macro ' ' A

为什么pivot表的AddDataField()方法会从“报表过滤器”中删除该字段?我使用GUI创建了一个新的透视表,并录制了一个宏。一切进展顺利,只是宏本身不工作。如何使用VBA(我只能使用GUI)向“报表过滤器”和值添加字段

这是我录制的宏。您可以在A1激活的空白工作表上测试运行此功能。最后一个命令从“报告过滤器”中删除该字段,即使在录制宏和使用GUI时一切正常。这真让我受不了

Option Explicit

Sub Macro8()
'
' Macro8 Macro
'

'
    ActiveCell.FormulaR1C1 = "foo"
    Range("A2").Select
    ActiveCell.FormulaR1C1 = "1"
    Range("A3").Select
    Selection.End(xlUp).Select
    Range(Selection, Selection.End(xlUp)).Select
    ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
        "Sheet1!R1C1:R2C1", Version:=xlPivotTableVersion14).CreatePivotTable _
        TableDestination:="Sheet1!R1C3", TableName:="PivotTable2", DefaultVersion _
        :=xlPivotTableVersion14
    Sheets("Sheet1").Select
    Cells(1, 3).Select
    With ActiveSheet.PivotTables("PivotTable2").PivotFields("foo")
        .Orientation = xlPageField
        .Position = 1
    End With
    ActiveSheet.PivotTables("PivotTable2").AddDataField ActiveSheet.PivotTables( _
        "PivotTable2").PivotFields("foo"), "Sum of foo", xlSum
End Sub
编辑:

我错了。打开一个新工作簿,在A1单元格中的活页2中,类型为“标签”,在B1单元格中,类型为“值”。然后,我将A列的前50行填入“A”、“b”或“c”,统称为我的标签。在标签旁边,我做了一个
randbween(1,50)
。下面的代码将在表1的单元格A1中输出数据透视表。我建议玩这个游戏来了解添加不同字段是如何工作的

Option Explicit

Sub pt()
Dim pc As PivotCache
Dim pt As PivotTable
Dim wb As Workbook

Set wb = ThisWorkbook

With wb
    Set pc = .PivotCaches.Create(xlDatabase,     .Sheets("Sheet2").Range("a2").CurrentRegion)
End With

With pc
    Set pt = .CreatePivotTable(ThisWorkbook.Sheets("Sheet1").Range("a1"))
End With

With pt
    .AddDataField .PivotFields("label")
    .AddDataField .PivotFields("value"),,xlSum
    .AddFields RowFields:="label", PageFields:="value"
End With


End Sub

我不明白为什么AddDataField()会从“报表过滤器”中删除该字段,但我发现了以下几种解决方法:

  • 使用GUI添加字段
  • 首先将字段添加到“值”,然后再添加到“报告过滤器”:

  • 使用此子项,在AddDataField()删除字段后,将其读取到“报告筛选器”

    因此,示例的最后一个命令应更改为:

    'ActiveSheet.PivotTables("PivotTable2").addDataField ActiveSheet.PivotTables( _
    '    "PivotTable2").PivotFields("foo"), "Sum of foo", xlSum
    addDataField ActiveSheet.PivotTables("PivotTable2"), ActiveSheet.PivotTables("PivotTable2").PivotFields("foo"), "Sum of foo", xlSum
    

  • @jumxozizi,您还需要设置第三个解决方案

    Sub addDataField(pv, ByVal field, Optional func, Optional caption)
        'Adds a data field to a PivotTable report preserving field's .Orientation and .Position
        'pv - PivotTable object, field - source field name
        'func - the function performed in the added data field
        'caption - the label used in the PivotTable report to identify this data field
        Set field = pv.PivotFields(field)
        orient = field.Orientation
        pos = field.Position
        If orient = xlPageField And Not field.EnableMultiplePageItems Then _
            current_page = field.CurrentPage
        pv.addDataField field, caption, func
        If orient = xlHidden Or field.Orientation <> xlHidden Then Exit Sub
    
        Dim lower_fields() As String
        ReDim Preserve lower_fields(pos To pos)
        lower_fields(pos) = field.Name
        'Temporarly hide group fields
        For Each f In pv.PivotFields
            If f.Orientation = orient Then
                f_pos = f.Position + 1 '-1 position after the `field` was hidden
                If f_pos > pos Then
                    If UBound(lower_fields) < f_pos Then _
                        ReDim Preserve lower_fields(pos To f_pos)
                    lower_fields(f_pos) = f.Name
                    f.Orientation = xlHidden
                End If
            End If
        Next f
        'Add group fields back in right order
        For Each f_name In lower_fields
            pv.PivotFields(f_name).Orientation = orient
        Next f_name
        If orient = xlPageField And Not field.EnableMultiplePageItems Then _
            field.CurrentPage = current_page
    End Sub
    
    子添加数据字段(pv、ByVal字段、可选函数、可选标题)
    '将数据字段添加到数据透视表中,保留字段的.Orientation和.Position
    'pv-数据透视表对象,字段-源字段名
    'func-在添加的数据字段中执行的函数
    '标题-数据透视表中用于标识此数据字段的标签
    设置字段=pv.PivotFields(字段)
    方向=字段。方向
    位置=字段位置
    如果orient=xlPageField而非field.EnableMultiplePageItems,则_
    当前页面=field.CurrentPage
    pv.addDataField字段,标题,函数
    如果orient=xlHidden或field.Orientation xlHidden,则退出Sub
    将低位字段()变暗为字符串
    ReDim保留下_字段(pos到pos)
    下_字段(位置)=字段名称
    '临时隐藏组字段
    对于pv.PivotFields中的每个f
    如果f.方向=方向,则
    f_pos=f.位置+1'-1隐藏“字段”后的位置
    如果f_pos>pos,则
    如果UBound(下_字段)
    但是,由于您首先设置了
    .Orientation
    ,因此默认的
    .Position
    是最后一个。此行为可能导致数据透视表与工作表上的其他内容重叠。因此,在上述函数中,我临时删除了
    字段
    下的分组字段。然后我把它们按正确的顺序加回去


    更新2020-04-08:如果字段的
    EnableMultiplePageItems=False
    ,则调用
    addDataField
    重置当前选定的项目(
    CurrentPage
    )。

    添加数据字段将删除所有先前添加的字段,并将其替换为
    .addDataField
    方法中列出的字段。您必须在
    AddDataField
    方法中列出所需的所有数据字段。您在这里丢失了我。您能给我一个使用AddDataField()将同一字段添加到“报表过滤器”和“值”(求和函数)的工作示例吗?一个解决方案似乎是先将字段添加到“值”,然后再将其添加到“报表过滤器”。我只是不明白为什么将字段添加到“报告过滤器”会将其从“值”中删除。如果我使用GUI,我可以按任意顺序执行,但在VBA中,我必须按特定顺序执行,才能使其正常工作。。。
    'ActiveSheet.PivotTables("PivotTable2").addDataField ActiveSheet.PivotTables( _
    '    "PivotTable2").PivotFields("foo"), "Sum of foo", xlSum
    addDataField ActiveSheet.PivotTables("PivotTable2"), ActiveSheet.PivotTables("PivotTable2").PivotFields("foo"), "Sum of foo", xlSum
    
    Sub addDataField(pv, ByVal field, Optional func, Optional caption)
        'Adds a data field to a PivotTable report preserving field's .Orientation and .Position
        'pv - PivotTable object, field - source field name
        'func - the function performed in the added data field
        'caption - the label used in the PivotTable report to identify this data field
        Set field = pv.PivotFields(field)
        orient = field.Orientation
        pos = field.Position
        If orient = xlPageField And Not field.EnableMultiplePageItems Then _
            current_page = field.CurrentPage
        pv.addDataField field, caption, func
        If orient = xlHidden Or field.Orientation <> xlHidden Then Exit Sub
    
        Dim lower_fields() As String
        ReDim Preserve lower_fields(pos To pos)
        lower_fields(pos) = field.Name
        'Temporarly hide group fields
        For Each f In pv.PivotFields
            If f.Orientation = orient Then
                f_pos = f.Position + 1 '-1 position after the `field` was hidden
                If f_pos > pos Then
                    If UBound(lower_fields) < f_pos Then _
                        ReDim Preserve lower_fields(pos To f_pos)
                    lower_fields(f_pos) = f.Name
                    f.Orientation = xlHidden
                End If
            End If
        Next f
        'Add group fields back in right order
        For Each f_name In lower_fields
            pv.PivotFields(f_name).Orientation = orient
        Next f_name
        If orient = xlPageField And Not field.EnableMultiplePageItems Then _
            field.CurrentPage = current_page
    End Sub