Excel VBA 遍历已过滤的数据透视表

Excel VBA loop through pivotitems that are filtered

我是论坛新手,post不全还望大家多多包涵

我有一个非常简单的数据透视表 table,其中包含一行字段、一列字段、一个数据字段和一个筛选字段。行字段根据过滤器设置显示。使用 VBA,我的目的是遍历所有行数据透视项和列数据透视项并获取相应的字段名称和数据值并将它们显示为完整性检查。这是一个更大项目的开始。

这里是主循环(showstring 显示在屏幕上):

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 不会随着过滤器设置而改变——我通过在 pivot table 字段中手动检查来验证它。过滤器设置会影响屏幕上的可见内容,但枢轴项 Visible 属性 不会改变并且始终为 True。因此,我循环遍历所有可用字段,并为不可见字段设置 GetPivotData return 值 0。这对我来说是不可接受的table,因为我的数据透视表包含实际的 0 值。

我的问题是是否有其他属性可以用来确定数据透视表是否被过滤掉(不可见因此不相关)或不过滤(可见且相关)。我在 VBA 中尝试了对象浏览器,但没有变得更聪明。任何提示将不胜感激。

谢谢

您已经了解了 PivotItems 的可见性:

如果您过滤 PivotTable,那么您的 RowFieldsColumnFields 中的某些 PivotItems 是否可见,
但 VBA 仍然 returns 每个 PivotField.PivotItem 作为 Visible.

另外PivotField.VisibleItems.Count始终保持最大值。


剩余的 "really" 可见 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()可以区分它们。


... 或者您遍历每个 PivotFieldDataRange 以捕获简单枢轴 table:

的可见单元格中的项目
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