Excel VBA循环浏览已过滤的枢轴项目

时间:2019-02-11 18:27:02

标签: excel vba filtering pivot-table visible

我是这个论坛的新手,所以如果我的帖子不完整,请纵容我。

我有一个非常简单的数据透视表,其中包含一个行字段,一个列字段,一个数据字段和一个过滤器字段。根据过滤器设置显示行字段。使用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

代码运行正常,但没有实现我的意图。我的问题是在第一个代码段中。在调用MyGetPivotData之前,我正在使用Visible属性。问题是Visible不会随着过滤器设置而更改-我通过在数据透视表字段中手动检查来验证了它。筛选器设置会影响屏幕上可见的内容,但枢轴项目的“可见性”属性不会更改,并且始终为True。因此,我遍历了所有可用字段,并且对于不可见字段,GetPivotData返回值0。如果我的数据透视图数据包含实际的0值,这对我来说是不可接受的。

我的问题是,是否可以使用其他属性来确定是否将ivotitem滤除(不可见,因此不相关)(不可见,不相关)。我在VBA中尝试了对象浏览器,但没有更明智的选择。任何提示将不胜感激。

谢谢

1 个答案:

答案 0 :(得分:1)

您已经发现有关PivotItems的可见性:

如果您过滤PivotTable,则PivotItemsRowFields中的某些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的{​​{1}}上循环以在简单数据透视表的可见单元格中捕获项目:

PivotField