Excel vba:隐藏数据透视表中的计算字段的错误

时间:2009-09-07 08:38:59

标签: excel vba excel-vba pivot-table

我在数据透视表中写了几个Subs来显示/隐藏字段。 现在我尝试使用计算字段执行相同操作,但是在隐藏它时会出错。 我从录音机中取出了我的代码,录音机的代码也在最后一行停了下来。 我搜索了错误信息,没有严重的结果。

Sub PrRemove()
    'remove PR
    Dim pt As PivotTable
    Set pt = ActiveSheet.PivotTables("MyPivot")
    pt.PivotFields("MyField").Orientation = xlHidden   '<- here is the error
End Sub

如果MyField是普通字段(不是计算字段),则相同的代码可以正常工作 我正在使用Excel 2007 SP2 任何线索?

2010年6月17日编辑:我也尝试使用pt.DataFields而不是pt.PivotFields,行为完全相同。错误消息显示“无法设置PivotField类的方向”。

14 个答案:

答案 0 :(得分:5)

拉了很多头发之后,我找到了一个解决方法。 如果添加多个数据透视表字段(计算或其他),则Excel会创建一个名为“值”的分组字段。您可以将PivotField的方向属性(“值”)设置为xlHidden,并为两个字段添加项目符号。因此,如果你想删除一个计算字段,只需添加一个非计算字段,设置PivotField(“Values”)。orientation to xlHidden,你就完成了。

没有人说会很漂亮......

答案 1 :(得分:4)

With ActiveSheet.PivotTables("PivottableName").PivotFields("Values")
    .PivotItems("CalcFieldName").Visible = False
End With

答案 2 :(得分:2)

我想轻松删除数据字段(计算字段与否),就像手动完成一样。

我终于找到了这个解决方案(Excel 2010):

Set pt = ActiveSheet.PivotTables("mypivottable")
For Each pi In pt.DataPivotField.PivotItems
    pi.Visible = False
Next

答案 3 :(得分:1)

好吧,我会给你所需要的确认。似乎在“Calulated Field”上使用Orientation属性只是不起作用,我不得不同意这是一个错误而不是常见的“使用”错误。我能够复制“隐藏/显示”字段而无需删除(“删除”)计算字段。这允许用户在以编程方式“隐藏”字段后从字段列表中物理拖动计算字段。这不是一个糟糕的解决方案,因为它复制了用户界面。 (使用Excel 2003。)

'2009.09.25 AMJ
'work around for
'   1004, Unable to set the Orientation property of the PivotField class
'when setting orientation property to hidden of calculated field, as in
'   ActiveSheet.PivotTables("PivotTable1").PivotFields("Sum of Field1").Orientation = xlHidden

Public Sub Hide()
'hide the data without removing the calculated field
'   this allows the user to physically drag the
'       calculated field from the field list once we
'       have "hidden" it programmatically.
'   if we use the "delete" method, the field is removed
'       from the pivot table and the field list

    Dim oWS As Worksheet
    Dim oPT As PivotTable
    Dim oPF As PivotField
    Dim oPI As PivotItem

    Set oWS = ActiveSheet
    Set oPT = oWS.PivotTables(1)

    For Each oPF In oPT.DataFields
        If oPF.SourceName = "Field1" Then
            'Stop
            Exit For
        End If
    Next

    Set oPI = oPF.DataRange.Cells(1, 1).PivotItem
    'oPI.DataRange.Select
    oPI.Visible = False

End Sub

Public Sub Show()
'show just reads the pivot field to the data fields

    Dim oWS As Worksheet
    Dim oPT As PivotTable
    Dim oPF As PivotField

    Set oWS = ActiveSheet
    Set oPT = oWS.PivotTables(1)

    For Each oPF In oPT.PivotFields
        If oPF.SourceName = "Field1" Then
            'Stop
            Exit For
        End If
    Next

    oPT.AddDataField oPF

End Sub

[原始答案] 您很可能无法隐藏此项目,因为它是最后一个可见项目。相反,请尝试将其删除。

答案 4 :(得分:0)

您是否更改了计算字段的名称?它原来是'MyField的总和'吗?尝试查看SourceName属性,如果使用它属性不同。

您是否尝试过pt.CalculatedFields("MyField").Orientation = xlHidden

答案 5 :(得分:0)

我不认为这是一个excel bug,我认为这是一个'功能'。 ; - )

Re:@AMissico,excel隐藏了数据透视表中的所有字段没有问题,但他可能正在讨论项目 - 你无法隐藏数据透视字段中的最后一项。

这是我经常用来做你想做的事情的代码。这些宏是在Excel 2002和Excel上开发的。 2003.我不隐藏CalculatedFields,我删除它们。

' Hide all fields.
' @param ThePivotTable to operate upon.
Sub HidePivotFields(ByVal ThePivotTable As PivotTable)
    Dim pField As PivotField
    For Each pField In ThePivotTable.CalculatedFields
        pField.Delete
    Next pField
    For Each pField In ThePivotTable.PivotFields
        pField.Orientation = xlHidden
    Next pField

    Set pField = Nothing
End Sub

' Removes FieldName data from ThePivotTable
Sub HideField(ByVal ThePivotTable As PivotTable, _
              ByVal FieldName As String)
    If FieldExists(ThePivotTable, FieldName) = True And _
       CalculatedFieldExists(ThePivotTable, FieldName) = False Then
        ThePivotTable.PivotFields(FieldName).Orientation = xlHidden
    End If
End Sub

' Returns True if FieldName exists in ThePivotTable
'
' @param ThePivotTable to operate upon.
' @param FieldName the name of the specific pivot field.
Function FieldExists(ByVal ThePivotTable As PivotTable, _
                     ByVal FieldName As String) As Boolean
    Dim pField As PivotField

    For Each pField In ThePivotTable.PivotFields
        If pField.SourceName = FieldName Then
            FieldExists = True
            Exit For
        End If
    Next pField

    Set pField = Nothing
End Function

' Checks if the field FieldName is currently a member of the
' CalculatedFields Collection in ThePivotTable.
' @return True if a CalculatedField has a SourceName matching the FieldName
' @return False otherwise
Function CalculatedFieldExists(ByVal ThePivotTable As PivotTable, _
                               ByVal FieldName As String) As Boolean
    Dim pField As PivotField

    CalculatedFieldExists = False

    For Each pField In ThePivotTable.CalculatedFields
        If pField.SourceName = FieldName Then
            CalculatedFieldExists = True
        End If
    Next pField
    Set pField = Nothing
End Function

' Returns a Pivot Field reference by searching through the source names.
'
' This function is a guard against the user having changed a field name on me.
' @param ThePivotTable to operate upon.
' @param FieldName the name of the specific pivot field.
Function GetField(ByVal ThePivotTable As PivotTable, _
                  ByVal FieldName As String) As PivotField
    Dim pField As PivotField

    For Each pField In ThePivotTable.PivotFields
        If pField.Name <> "Data" Then
            If pField.SourceName = FieldName Then
                Set GetField = pField
                Exit For
            End If
        End If
    Next pField

    Set pField = Nothing
End Function

' Counts the number of currently visible pivot items in a field.
' @param ThePivotItems the collection of pivot itemns in a field.
' @return the count of the visible items.
Function PivotItemCount(ByVal ThePivotItems As PivotItems) As Long
    Dim pItem As PivotItem
    Dim c As Long

    For Each pItem In ThePivotItems
        If pItem.Visible = True Then c = c + 1
    Next pItem
    PivotItemCount = c
    Set pItem = Nothing
End Function

' Hides a single pivot item in a pivot field, unless it's the last one.
' @param FieldName pivot field containing the pivot item.
' @param ItemName pivot item to hide.
Sub HidePivotItem(ByVal ThePivotTable As PivotTable, _
                  ByVal FieldName As String, _
                  ByVal ItemName As String)
    Dim pField As PivotField

    Set pField = GetField(ThePivotTable, FieldName)
    If Not pField Is Nothing Then
        If PivotItemCount(pField.PivotItems) > 1 Then
            pField.PivotItems(ItemName).Visible = False
        End If
    End If

    Set pField = Nothing
End Sub

答案 6 :(得分:0)

我遇到与你完全相同的问题。 看起来我将不得不删除计算字段并读取它而不是隐藏/显示它。

答案 7 :(得分:0)

第一次尝试隐藏计算字段时,我意外地发现了一种解决方法,所以我想在此处分享一下:

您可以改为指向代码,而不是修改方向属性,而是指示代码选择数据透视表中包含要隐藏的计算字段标题的单元格,然后删除选择。只要表中已有另一个数据字段,这就可以工作。示例如下:

场景:数据透视表涵盖范围A1:G10。计算字段“Margin”已经在表格中,您想要添加数据字段“Sales”并删除“Margin”计算字段。

执行代码:

'Add Sales data field
 ActiveSheet.PivotTables(Pname).AddDataField ActiveSheet.PivotTables( _
    Pname).PivotFields("SALES"), "Sum of SALES", xlSum

 'At this point, the datafield titles are in vertically adjacent rows, named "Sum
 'of Margin" and "Sum of Sales" at locations B3 and B4 respectively.

 'Remove the "Sum of Margin" calculated field
  Range("B3").Delete

不确定为什么会这样,但我很高兴我们至少可以使用它!

答案 8 :(得分:0)

幸运的是,隐藏数据字段的方法很简单。你错误地使用数据域的pivotfields你是错误的。无论最初在枢轴中有多少个数据透视字段/数据字段,我都会提供一段清空数据透视表的代码:

Sub Macro1()

Dim p As PivotTable
Dim f As PivotField

Set p = ActiveSheet.PivotTables(1)

For Each f In p.PivotFields

If f.Orientation <> xlHidden Then
    f.Orientation = xlHidden
End If

Next f

For Each f In p.DataFields

If f.Orientation <> xlHidden Then
    f.Orientation = xlHidden
End If

Next f

End Sub

答案 9 :(得分:0)

这是我今天发现的一个小解决方法,同样不是很优雅,但至少它不需要太多代码,它会隐藏所有字段,你需要重新显示你想要的那些:

objTable.DataPivotField.Orientation = xlHidden

如果excel由于某种原因认为datapivotfield为空,则可能会遇到错误,但为了解决此问题,只需在上述语句之前添加另一个字段作为数据字段。还要确保字母l不是xlHidden vba默认字体中的数字1,它们看起来非常相似。

快乐编码

答案 10 :(得分:0)

似乎要隐藏计算字段,您需要先隐藏名为“值”的数据透视字段。

PivotTable(1).PivotFields("Values").Orientation = xlHidden
For Each PF In PT.DataFields
    PF.Orientation = xlHidden
Next PF

我假设如果您的xlDataField位置有两个或更多字段,那么该字段似乎只存在。

感谢Alinboss指出我正确的方向。我确信我之前尝试过你的方法并且失败了 - 结果是顺序很重要!

P.S。您的代码仍然无法仅使用一个计算数据字段

答案 11 :(得分:0)

Laurent Bosc的代码检查出来,所以我投票了。我的完整代码包括在隐藏全部数据后添加数据。代码放在Sheet1(Sheet1)上。

Private Sub Refresh_Pivot()

    Dim NewMetric As String
    Dim pt As PivotTable, objDataField As Object
    NewMetric = "your_custom_metric"

'-------update pivot table 1, hide all elements including calculated field----

    Application.EnableEvents = False
    Set pt = Sheet1.PivotTables("PivotTable1")

    For Each Pi In pt.DataPivotField.PivotItems
        Pi.Visible = False
    Next

'--------add a new data field to the pivot table----------------------------

    With pt
        .AddDataField.PivotFields(NewMetric), "Sum of " & NewMetric, xlSum
    End With

    Application.EnableEvents = True

End Sub

答案 12 :(得分:0)

我知道这有点晚了,但是我看到这个问题尚未得到有把握的回答,我也面临着同样的问题,很难找到有用的信息。所以,我希望这篇文章可以对某人有所帮助...

如果您将数据存储在数据模型中,请使用CubeFields代替PivotFields。 我遇到了同样的问题,我尝试了一个没有数据模型的简单工作簿,并且我的代码运行完美(使用PivotFields)。 它仅在工作簿中使用数据模型返回错误。 所以,我做了这个改变和繁荣!有效! 我的建议是使用以下代码:

Sub PrRemove()
'remove PR
Dim pt As PivotTable
Set pt = ActiveSheet.PivotTables("MyPivot")
pt.CubeFields("MyField").Orientation = xlHidden   '<- here is the error
End Sub

答案 13 :(得分:0)

感谢@user4709164 的回答,我得到了这个代码,它非常适合我:

我的枢轴列都以 X 或 Y 结尾来表示轴,所以我使用最后一个字符作为字段标题。

having()