Excel VBA цикл через сводные элементы, которые отфильтрованы - PullRequest
0 голосов
/ 11 февраля 2019

Я новичок в форуме, поэтому, пожалуйста, побалуйте меня, если мое сообщение не является полным.

У меня есть очень простая сводная таблица с одним полем строки, одним полем столбца, одним полем данных и одним полем фильтра.Поля строк отображаются в зависимости от настроек фильтра.Используя VBA, я собираюсь просмотреть все сводные строки и сводные столбцы столбцов, получить соответствующие имена полей и значения данных и отобразить их в качестве проверки работоспособности.Это начало более крупного проекта.

вот основной цикл (на экране отображается строка):

showstring = ""
For rowFldNo = 1 To pvt.RowFields.Count
  For colFldNo = 1 To pvt.ColumnFields.Count
    For rowItemNo = 1 To pvt.RowFields(rowFldNo).PivotItems.Count
      For colItemNo = 1 To pvt.ColumnFields(colFldNo).PivotItems.Count
        If pvt.RowFields(rowFldNo).PivotItems(rowItemNo).Visible And _
           pvt.ColumnFields(colFldNo).PivotItems(colItemNo).Visible Then
           showstring = showstring & _
           pvt.RowFields(rowFldNo).PivotItems(rowItemNo).Name & ": " & _ 
           pvt.ColumnFields(colFldNo).PivotItems(colItemNo).Name & _
           "= " & MyGetPivotData(pvt, rowFldNo, rowItemNo, colFldNo, _ 
           colItemNo) & vbCrLf
        End If
      Next colItemNo
    Next rowItemNo
  Next colFldNo
Next rowFldNo
MsgBox showstring

MyGetPivotData - это простая подпрограмма, которая скрывает сложность использованияVBA встроенная функция GetPivotData.Вот код:

Function MyGetPivotData(ByRef thisPvt As PivotTable, _
                        ByVal rowFld As Integer, _
                        ByVal rowItem As Integer, _
                        ByVal colFld As Integer, _
                        ByVal colItem As Integer) As Integer

On Error Resume Next
MyGetPivotData = 
  thisPvt.GetPivotData(thisPvt.DataFields(thisPvt.DataFields.Count), _
                thisPvt.RowFields(rowFld).Name, _ 
                thisPvt.RowFields(rowFld).PivotItems(rowItem).Name, _
                thisPvt.ColumnFields(colFld).Name, _ 
                thisPvt.ColumnFields(colFld).PivotItems(colItem).Name).Value

End Function

Код работает нормально, но не выполняет мое намерение.Моя проблема в первом сегменте кода.Я использую свойство Visible перед вызовом MyGetPivotData.Проблема в том, что Visible не меняется с настройкой фильтра - я проверил это, проверив вручную в полях сводной таблицы.Настройка фильтра влияет на то, что видно на экране, но свойство сводного элемента Visible не изменяется и всегда имеет значение True.Следовательно, я перебираю все доступные поля и возвращаю значение GetPivotData 0 для невидимых полей.Это неприемлемо для меня, потому что мои сводные данные могут содержать фактические значения 0.

Мой вопрос: есть ли другие свойства, которые я мог бы использовать, чтобы определить, отфильтрован ли сводный элемент (невидимый и, следовательно, нерелевантный) или нет (видимый)?и актуально).Я попробовал Object Browser в VBA, но ничего не понял.Любые советы будут с благодарностью.

Спасибо

1 Ответ

0 голосов
/ 31 марта 2019

Как вы уже узнали о видимости PivotItems:

Если вы фильтруете PivotTable, то некоторые из PivotItems ваших RowFields или ColumnFields оптически видны или нет,
, но VBA по-прежнему возвращает каждый PivotField.PivotItem как Visible.

Также PivotField.VisibleItems.Count всегда остается максимальным.


Оставшиеся «действительно» видимые PivotItems могут быть адресованы PivotLine.PivotLineCell.PivotItem каждой оси вращения.

LineType расхождение между обычными, пустыми, промежуточными и промежуточными линиями.

showstring = ""
For rowItemNo = 1 To pvt.PivotRowAxis.PivotLines.Count
    If pvt.PivotRowAxis.PivotLines(rowItemNo).LineType = xlPivotLineRegular Then
        For colItemNo = 1 To pvt.PivotColumnAxis.PivotLines.Count
            If pvt.PivotColumnAxis.PivotLines(colItemNo).LineType = xlPivotLineRegular Then
                showstring = showstring & _
                pvt.PivotRowAxis.PivotLines(rowItemNo).PivotLineCells(1).PivotItem.Name & ":" & _
                pvt.PivotColumnAxis.PivotLines(colItemNo).PivotLineCells(1).PivotItem.Name & _
                " = " & pvt.DataBodyRange.Cells(rowItemNo, colItemNo).Value & vbCrLf
            End If
        Next colItemNo
    End If
Next rowItemNo
MsgBox showstring

Если у вас есть более одного поля столбца или строки, то PivotLineCells() может различать их.


... или вы перебираете DataRange каждого PivotField, чтобы пойматьэлементы в видимых ячейках простой сводной таблицы:

For rowFldNo = 1 To pvt.RowFields.Count
    For colFldNo = 1 To pvt.ColumnFields.Count
        For rowItemNo = 1 To pvt.RowFields(rowFldNo).DataRange.Rows.Count
            For colItemNo = 1 To pvt.ColumnFields(colFldNo).DataRange.Columns.Count
                showstring = showstring & ...
            Next colItemNo
        Next rowItemNo
    Next colFldNo
Next rowFldNo
...