如何在vba中遍历OLAP数据透视表过滤器

时间:2019-07-04 09:01:37

标签: excel vba pivot-table

我是VBA的新手。我有Excel文件,其中有一些通过连接到OLAP多维数据集创建的数据透视表。

我需要有关如何在数据透视表中循环通过过滤器列的帮助,如下面的代码中所述,我如何在“行字段”,“列字段”和“数据字段”之间进行循环。

Private Sub CommandButton1_Click()    
    Dim wb As Workbook
    Dim wsheet As Worksheet
    Dim PvtTbl As PivotTable
    Dim pvtFld As PivotField
    Dim wsmapping As Worksheet

    ' Set the Variable Values
    Set wb = ActiveWorkbook
    Set wsmapping = Worksheets("Mapping")

    'WorkBook Active sheets
    For Each wsheet In wb.Worksheets
        'Current Worksheet Pivot Table
        For Each PvtTbl In wsheet.PivotTables

            'Current Pivot Table Row Fields
            For Each PvtRowFld In PvtTbl.RowFields
                PvtRowFldName = PvtRowFld.Name
                RowFldPos = PvtRowFld.Position
                RowField = Left(PvtRowFldName, InStrRev(PvtRowFldName, ".") - 1)

                NewRowField = Application.WorksheetFunction.IfError(Application.WorksheetFunction.VLookup(RowField, wsmapping.Range("A2:B10"), 2, False), "No Mapping")
                'MsgBox NewPvtfld

                If NewRowField <> "No Mapping" Then
                    PvtTbl.CubeFields(RowField).Orientation = xlHidden

                    With PvtTbl.CubeFields(NewRowField)
                        .Orientation = xlRowField
                        .Position = RowFldPos
                    End With
                End If
            Next PvtRowFld

            'Current Pivot Table Column Fields
            For Each PvtColFld In PvtTbl.ColumnFields
                PvtColFldName = PvtColFld.Name
                ColFldPos = PvtColFld.Position
                ColField = Left(PvtColFldName, InStrRev(PvtColFldName, ".") - 1)
                NewColField = Application.WorksheetFunction.IfError(Application.WorksheetFunction.VLookup(ColField, wsmapping.Range("A2:B10"), 2, False), "No Mapping")
                MsgBox NewColField

                If NewColField <> "No Mapping" Then
                    PvtTbl.CubeFields(ColField).Orientation = xlHidden

                    With PvtTbl.CubeFields(NewColField)
                        .Orientation = xlColumnField
                        .Position = ColFldPos
                    End With
                End If
            Next PvtColFld

            'Current Pivot Table Measure
            For Each PvtMeasure In PvtTbl.DataFields
                PvtMeasureName = PvtMeasure.Name
                PvtMeasurePos = PvtMeasure.Position

                NewMeasureName = Application.WorksheetFunction.IfError(Application.WorksheetFunction.VLookup(PvtMeasureName, wsmapping.Range("A2:B10"), 2, False), "No Mapping")
                MsgBox NewMeasureName

                If NewColField <> "No Mapping" Then
                    PvtTbl.CubeFields(PvtMeasureName).Orientation = xlHidden

                    With PvtTbl.CubeFields(NewMeasureName)
                        .Orientation = xlDataField
                        .Position = PvtMeasurePos
                    End With
                End If
            Next PvtMeasure

            'Current Pivot Table Active Filters
            For Each pvtFilter In PvtTbl.ActiveFilters
                MsgBox pvtFilter.Name
            Next pvtFilter
        Next PvtTbl  
    Next wsheet
End Sub

在上面的代码PvtTbl.ActiveFilters中,尽管我在数据透视表上有很多活动过滤器,但对于每个循环来说,并不是“循环数据透视表”过滤器字段。

我看到一些对PvtTbl.PivotFields的引用,该引用也遍历行,列,度量和过滤器之类的所有字段。使用此方法,我无法确定字段来自哪里,是否来自列/行/过滤器?

1 个答案:

答案 0 :(得分:0)

数据透视表上方的过滤器字段也是PivotFields,它们用作PageField

由于术语“过滤器”是不同的(例如,另外过滤每个枢轴场),因此我建议为其使用另一个名称,例如。 G。 “ pvtPageField”。

当其PivotTable.PageFieldPivotTable.CubeField时,您可以将其引用为OrientationxlPageField

' simple approach:
Dim pvtPagefield As PivotField
For Each pvtPagefield In PvtTbl.PageFields
    Debug.Print pvtPagefield.Name
    Debug.Print pvtPagefield.Value
    Debug.Print pvtPagefield.SourceName
    Debug.Print pvtPagefield.Caption
Next pvtPagefield

' better approach:
Dim pvtCubeField As CubeField
For Each pvtCubeField In PvtTbl.CubeFields
    If pvtCubeField.Orientation = xlPageField Then
        Debug.Print pvtCubeField.Position
        Debug.Print pvtCubeField.Name
        Debug.Print pvtCubeField.Value
        Debug.Print pvtCubeField.Caption
        For Each pvtPagefield In pvtCubeField.PivotFields
            Debug.Print pvtPagefield.Name
            Debug.Print pvtPagefield.Value
            Debug.Print pvtPagefield.SourceName
            Debug.Print pvtPagefield.Caption
        Next pvtPagefield
    End If
Next pvtCubeField

我还建议使用Option Explicit作为 每个 模块的第一行代码。
这将强制每个变量Dim,例如e。 g。

Dim pvtFld As PivotField, PvtRowFld As PivotField, PvtColFld As PivotField
Dim PvtRowFldName As String, RowField As String, RowFldPos As Variant, NewRowField As String
Dim PvtColFldName As String, ColField As String, ColFldPos As Variant, NewColField As String