[英]Excel vba: error hiding calculated field in 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 是普通字段(不是计算字段),则相同的代码可以正常工作。
我正在使用带有 SP2 的 Excel 2007。
有什么线索吗?
2010 年 6 月 17 日编辑:我也尝试使用 pt.DataFields 而不是 pt.PivotFields,具有完全相同的行为。 错误消息显示“无法设置 PivotField 类的方向”。
With ActiveSheet.PivotTables("PivottableName").PivotFields("Values")
.PivotItems("CalcFieldName").Visible = False
End With
经过多次拉头发后,我找到了解决方法。 如果您添加多个数据透视字段(计算或其他),excel 会创建一个名为值的分组字段。 您可以将 PivotField("Values") 的 orientation 属性设置为 xlHidden,它会突出显示两个字段。 所以如果你想删除计算字段,只需添加一个非计算字段,将 PivotField("Values").orientation 设置为 xlHidden 即可。
没有人说它会很漂亮......
我想轻松删除数据字段(计算字段或不),就像手动完成一样。
我终于找到了这个解决方案(Excel 2010):
Set pt = ActiveSheet.PivotTables("mypivottable")
For Each pi In pt.DataPivotField.PivotItems
pi.Visible = False
Next
好吧,我会给你你需要的确认。 似乎在“计算字段”上使用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
[原始答案]
很可能您无法隐藏此项目,因为它是最后一个可见的项目。
相反,请尝试将其删除。
这是我今天发现的一个小解决方法,同样不是很优雅,但至少它不需要太多代码,它会隐藏所有字段,您需要在之后重新显示您想要的字段:
objTable.DataPivotField.Orientation = xlHidden
如果 excel 出于某种原因认为数据透视字段为空,您可能会遇到错误,但要解决此问题,只需在上述语句之前添加另一个字段作为数据字段即可。 还要确保它的字母 l 而不是 xlHidden vba 默认字体中的数字 1 让它们看起来非常相似。
快乐编码
似乎要隐藏计算字段,您需要先隐藏一个名为“值”的数据透视字段。
PivotTable(1).PivotFields("Values").Orientation = xlHidden
For Each PF In PT.DataFields
PF.Orientation = xlHidden
Next PF
我假设只有在 xlDataField 位置有两个或更多字段时,该字段才似乎存在。
感谢 Alinboss 为我指明了正确的方向。 我确定我之前尝试过您的方法但失败了 - 结果证明顺序很重要!
Ps 您的代码仍然不适用于仅一个计算数据字段
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
您是否更改了计算字段的名称? 它最初是“MyField 的总和”吗? 尝试查看 SourceName 属性,看看使用它是否不同。
您是否尝试过pt.CalculatedFields("MyField").Orientation = xlHidden
?
我不认为这是一个 excel 错误,我认为这是一个“功能”。 ;-)
回复:@AMissico,在 excel 中隐藏数据透视表中的所有字段没有问题,但他可能在谈论项目 - 你不能隐藏数据透视表中的最后一项。
这是我经常用来做你想做的事情的代码。 这些宏是在 Excel 2002 和 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
我和你有完全一样的问题。 看起来我将不得不删除计算字段并重新添加它而不是隐藏/显示它。
我第一次尝试隐藏计算字段时无意中发现了一个解决方法,所以我想在这里分享它:
您可以不修改方向属性,而是指示代码选择数据透视表中包含要隐藏的计算字段标题的单元格,然后删除选择。 只要您在表中已有另一个数据字段,这就有效。 下面的例子:
场景:数据透视表涵盖范围 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
不知道为什么会这样,但我很高兴我们至少可以使用它!
幸运的是,有一种非常简单的方法可以隐藏数据字段。 你们都错误地把数据透视表字段和数据字段混淆了。 我正在展示一段清空数据透视表的代码,无论数据透视表中最初有多少数据透视表字段/数据字段:
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
我知道有点晚了,但我发现这个问题还没有得到肯定的回答,我也遇到了同样的问题,很难找到有用的信息。 所以,我希望这篇文章可以帮助某人......
如果您将数据存储在数据模型中,那么请使用 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
感谢@user4709164 的回答,我得到了这段代码,它对我来说工作得很好:
我的数据透视表列都以 X 或 Y 结尾以指示轴,因此我使用最后一个字符作为字段标题。
Public Sub PivotFieldsChange()
Dim ValType As String, param As String
Dim pf As PivotField
Dim pt As PivotTable
Application.ScreenUpdating = False
Sheet = "mysheet"
'select between % calculated column or normal column
If Range("Z1").Value = 1 Then
ValType = "%"
Else: ValType = ""
End If
Application.EnableEvents = False
For Each pt In Sheets(Sheet).PivotTables
Select Case pt.Name
Case "case1": param = "param1"
Case "case2": param = "param2"
Case "case3": param = "param3"
Case Else: GoTo line1
End Select
pt.PivotFields("Values").PivotItems("X").Visible = False
pt.PivotFields("Values").PivotItems("Y").Visible = False
pt.PivotFields (param & ValType & "_X")
pt.PivotFields(param & ValType & "_X").Orientation = xlDataField
pt.PivotFields (param & ValType & "_Y")
pt.PivotFields(param & ValType & "_Y").Orientation = xlDataField
For Each pf In pt.DataFields
pf.Function = xlAverage
pf.Caption = Right(pf.Caption, 1)
Next
line1:
Next pt
Application.EnableEvents = True
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.