【问题标题】:VBA Code to return pivot table cell's row, column, and page fields and itemsVBA 代码返回数据透视表单元格的行、列和页面字段和项目
【发布时间】:2016-01-15 04:10:28
【问题描述】:

我正在尝试编写一些代码,这些代码将在我突出显示数据透视表的值区域中的一个单元格后返回行、列和页面字段和项。例如,如果我选择一个包含 1000 美元值的单元格,我想使用代码来拉取行字段和项目(例如,字段是部门,项目是财务)、列字段和项目(例如,字段为客户,项目为广告)和页面字段和项目(例如,字段为公司,项目为 XYZ, Inc.)。

这看起来应该很简单,因为当您将鼠标悬停在数据透视表中的任何单元格上时,它会在上下文框中显示向下钻取信息,但是,我很难操作数据透视表对象因为在网上或微软似乎没有太多关于它们的文章。

看起来我正在寻找一个或多个 pivotline 对象,但我不知道如何使用它。

我最初采用这种方法并且效果很好,直到我意识到行字段的索引不一定是它在行字段中的位置,所以我不得不放弃它。

Sub ActualDetailDrill()
'after sub is completed, make this sub called when a cell in a pivot table is double-clicked.

Dim NumOfRowItems As Integer
Dim NumOfColItems As Integer
Dim NumOfPageFields As Integer
Dim Field As PivotField
Dim ActualDrillActiveCell As Range

Set ActualDrillActiveCell = Sheets("ActualDrill SQL Build").Range("A1")
NumOfRowItems = ActiveCell.PivotCell.RowItems.Count
i = 1

Do Until i > NumOfRowItems
    ActualDrillActiveCell.Value = ActiveCell.PivotTable.RowFields(i).Name
    ActualDrillActiveCell.Offset(0, 1).Value =    ActiveCell.PivotCell.RowItems(i).Name
    ActualDrillActiveCell = ActualDrillActiveCell.Offset(1, 0)
    i = i + 1
Loop

End Sub

任何帮助将非常非常感激。这是我正在进行的一个大型项目的最后一步之一,这将对我工作的公司非常有帮助。

【问题讨论】:

  • 这是此类代码的必读帖子:peltiertech.com/referencing-pivot-table-ranges-in-vba
  • 谢谢道格。这非常有帮助,但我正在尝试与此链接中讨论的相反。本文假设您知道要为其拉回数据的字段和项目名称。我已经知道数据范围(一个单元格而不是多个单元格)并且想要该数据范围的字段(列、行和页面)和项目。由于作者 Jon 似乎熟悉数据透视表的代码,因此他会是一个很好的人问这个问题吗?谢谢!

标签: excel pivot-table vba


【解决方案1】:

现在是周末,我有时间深入研究这个有趣的问题。我认为您使用RowItemsColumnItems 非常接近。 PivotTable.RowFields 更通用,但不适用于 PivotCell 级别。

我讨厌使用页面字段,但认为这是正确的逻辑:

Sub GetValueFieldStuff()
Dim pvtCell As Excel.PivotCell
Dim pvtTable As Excel.PivotTable
Dim pvtField As Excel.PivotField
Dim pvtItem As Excel.PivotItem
Dim pvtParentItem As Excel.PivotField
Dim i As Long

On Error Resume Next
Set pvtCell = ActiveCell.PivotCell
If Err.Number <> 0 Then
    MsgBox "The cursor needs to be in a pivot table"
    Exit Sub
End If
On Error GoTo 0

If pvtCell.PivotCellType <> xlPivotCellValue Then
    MsgBox "The cursor needs to be in a Value field cell"
    Exit Sub
End If

Set pvtTable = pvtCell.PivotTable
For Each pvtField In pvtTable.PageFields
    i = 0
    For Each pvtItem In pvtField.PivotItems
        If pvtItem.Visible Then
            i = i + 1
            Debug.Print "PageField " & pvtField.Name & " - Pivot Item " & i & " is " & pvtItem.Name
        End If
    Next pvtItem
Next pvtField

Debug.Print "Value Field Name is " & pvtCell.PivotField.Name
Debug.Print "Value Field Source is " & pvtCell.PivotField.SourceName

For i = 1 To pvtCell.RowItems.Count
    Set pvtParentItem = pvtCell.RowItems(i).Parent
    Debug.Print "Row Item " & i & " is " & pvtCell.RowItems(i).Name & ". It's parent Row Field is: " & pvtParentItem.Name
Next i

For i = 1 To pvtCell.ColumnItems.Count
    Set pvtParentItem = pvtCell.ColumnItems(i).Parent
    Debug.Print "Column Item " & i & " is " & pvtCell.ColumnItems(i).Name; ". It's parent Column Field is: " & pvtParentItem.Name
Next i
End Sub

如果您还没有,请考虑使用 VBE 的本地窗口。它非常适合在数据透视表的对象模型中向下钻取(和备份)。这就是我看到ColumnItemPivotItem,其ParentPivotField的原因。

【讨论】:

  • 感谢您的回复,道格!这个周末我有同伴,还不能调查这个,但希望我今晚有时间。我只是不想认为我忽略了你的回复——我真的很感激你为此付出的努力! ....希望我不会因为发布这个大声笑而被否决。 @Doug Glancy
  • 感谢您告诉我。是的,希望我们能与这些轻浮但友好的 cmets 一起在雷达下飞行。
  • 再次感谢您的评论,道格。我今天有时间尝试一下,我喜欢它在每个可见层返回枢轴项的方式,但这只是我正在寻找的一半。我还想要与每个项目关联的行字段、列字段、页字段和数据字段。如果我说我想用这段代码整体做什么,可能会更有意义。我正在尝试提取这些字段的字段名称和项目,以便我可以编写更多代码来将字段名称和项目编译为 SQL 语句,以便在另一个数据库上查询该行后面的详细信息。这有助于澄清吗?
  • 我刚刚编辑并添加了 ColumnItemRowitemPivotField 逻辑。在我看来,数据字段已经由vtCell.PivotField.SourceName 处理。我不知道您还想要什么页面字段。似乎 SQL 类似于 WHERE PageField_1 IN (PagePvtItem1, PagePvtItem2, etc)
  • 完美!我绝对可以调整它来制作一条 SQL 语句。我绝对记得尝试过 Parent 和 Child 属性,但由于某种原因总是出错 - 也许我当时太沮丧了哈哈。
猜你喜欢
  • 2015-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 2021-02-12
  • 1970-01-01
相关资源
最近更新 更多