Как пройти через OLAP Pivot таблицу Фильтры в VBA - PullRequest
1 голос
/ 04 июля 2019

Я новичок в 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 голосов
/ 04 июля 2019

Поля фильтра над сводной таблицей также PivotFields, которые используются как PageField.

Поскольку термин «фильтр» является чем-то другим (например, дополнительная фильтрация каждого сводного поля), я предлагаю использовать другоеимя для него, например, "pvtPageField".

Вы можете ссылаться на него либо как PivotTable.PageField, либо как PivotTable.CubeField, когда его Orientation равно xlPageField:

' 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 каждой переменной, например,

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
...