簡體   English   中英

Excel vba:在數據透視表中隱藏計算字段時出錯

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM