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
,那么您的 RowFields
或 ColumnFields
中的某些 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()
可以区分它们。
... 或者您遍历每个 PivotField
的 DataRange
以捕获简单枢轴 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
我是论坛新手,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
,那么您的 RowFields
或 ColumnFields
中的某些 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()
可以区分它们。
... 或者您遍历每个 PivotField
的 DataRange
以捕获简单枢轴 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