VBA, Application-defined or Object Error, changing Pivot Filter

天大地大妈咪最大 提交于 2021-02-08 06:39:43

问题


I am trying to change the pivot filter using vba based on a cell. I get error Application-defined or Object Error on my second line of code.

Sub RefreshPivots()

Sheets("Details").PivotTables("PivotTable1").PivotCache.Refresh
Sheets("Details").PivotTables("PivotTable2").PivotCache.Refresh


temp = Sheets("Input").Range("H2")
Sheets("Details").PivotTables("PivotTable1").PivotFields("Period").PivotFilters.Add Type:=xlCaptionEquals, Value1:=temp

  

End Sub

I am trying to switch to a date that I have in Sheets("Input").Range("H2") So if I have Sept 10/20 in this cell, I want the pivot to update to that.

Does anyone know what I am doing wrong?

Thanks.

Pivot Fields:

Pivot source data, maybe this format could be why?

filterDate value based on Christians Code:


回答1:


First of all I think the Period field must be under the Rows section of the PivotTable Fields pane (alone or among other fields - order doesn't matter):

Then you would need to replace this:

temp = Sheets("Input").Range("H2")
Sheets("Details").PivotTables("PivotTable1").PivotFields("Period").PivotFilters.Add Type:=xlCaptionEquals, Value1:=temp

with this:

With Sheets("Details").PivotTables("PivotTable1").PivotFields("Period")
    .ClearAllFilters
    .PivotFilters.Add Type:=xlSpecificDate, Value1:=Sheets("Input").Range("H2").Value2
End With

You might want to do some checks before running your code because sheet names can change as well as pivot table names and so on. Also instead of Sheets maybe use ThisWorkbook.Worksheets. This way you are not reffering to the ActiveWorkbook but to the Workbook where the code is running.

EDIT

Here's code that does some checks like mentioned above:

Option Explicit

Sub RefreshPivots()
    Dim pivTable1 As PivotTable
    Dim pivTable2 As PivotTable
    
    Set pivTable1 = GetPivotTable(ThisWorkbook, "Details", "PivotTable1")
    If pivTable1 Is Nothing Then
        'Do Something. Maybe Exit or display a MsgBox
    End If
    pivTable1.PivotCache.Refresh
    
    Set pivTable2 = GetPivotTable(ThisWorkbook, "Details", "PivotTable2")
    If pivTable2 Is Nothing Then
        'Do Something. Maybe Exit or display a MsgBox
    End If
    pivTable2.PivotCache.Refresh
    
    Dim periodField As PivotField
    
    On Error Resume Next
    Set periodField = pivTable1.PivotFields("Period")
    On Error GoTo 0
    If periodField Is Nothing Then
        'Do Something. Maybe Exit or display a MsgBox
    End If
    On Error GoTo 0
    
    Dim filterDate As Variant
    
    On Error Resume Next
    filterDate = ThisWorkbook.Worksheets("Inputs").Range("H2").Value2
    If Err.Number <> 0 Then
        'Do Something. Maybe Exit or display a MsgBox
    Else
        Select Case VarType(filterDate)
        Case vbDouble
            'Maybe check if serial number is valid
        Case vbString
            filterDate = CDbl(CDate(filterDate))
        Case Else
            'Maybe show a MsgBox
            Exit Sub
        End Select
    End If
    On Error GoTo 0
    
    With periodField
        .ClearAllFilters
        .PivotFilters.Add Type:=xlSpecificDate, Value1:=filterDate
    End With
End Sub

Private Function GetPivotTable(ByVal sourceBook As Workbook _
    , ByVal wSheetName As String _
    , ByVal pivotName As String _
) As PivotTable
    On Error Resume Next
    Set GetPivotTable = sourceBook.Worksheets(wSheetName).PivotTables(pivotName)
    On Error GoTo 0
End Function

EDIT 2

I've simplified the filter date check and added some code instead of the "Maybe" comments:

Sub RefreshPivots()
    Dim pivTable1 As PivotTable
    Dim pivTable2 As PivotTable
    
    Set pivTable1 = GetPivotTable(ThisWorkbook, "Details", "PivotTable1")
    If pivTable1 Is Nothing Then
        MsgBox "Missing Pivot Table", vbInformation, "Cancelled"
        Exit Sub
    End If
    pivTable1.PivotCache.Refresh
    
    Set pivTable2 = GetPivotTable(ThisWorkbook, "Details", "PivotTable2")
    If pivTable2 Is Nothing Then
        MsgBox "Missing Pivot Table", vbInformation, "Cancelled"
        Exit Sub
    End If
    pivTable2.PivotCache.Refresh
    
    Dim periodField As PivotField
    
    On Error Resume Next
    Set periodField = pivTable1.PivotFields("Period")
    On Error GoTo 0
    If periodField Is Nothing Then
        MsgBox "Missing Pivot Field", vbInformation, "Cancelled"
        Exit Sub
    End If
    On Error GoTo 0
    
    'Maybe check if date is within a certain range
'    If filterDate < minDate Or filterDate > maxDate Then
'        MsgBox "Invalid Date", vbInformation, "Cancelled"
'        Exit Sub
'    End If

    Dim filterDate As Variant
    
    On Error Resume Next
    filterDate = ThisWorkbook.Worksheets("Inputs").Range("H2").Value2
    If VarType(filterDate) = vbString Then filterDate = CDbl(CDate(filterDate))
    If Err.Number <> 0 Or VarType(filterDate) <> vbDouble Then
        MsgBox "Missing/Invalid Filter Date", vbInformation, "Cancelled"
        Err.Clear
        Exit Sub
    End If
    On Error GoTo 0
    
    With periodField
        .ClearAllFilters
        .PivotFilters.Add Type:=xlSpecificDate, Value1:=filterDate
    End With
End Sub

EDIT 3

Based on updated question:

Option Explicit

Sub RefreshPivots()
    Dim pivTable1 As PivotTable
    Dim pivTable2 As PivotTable
    
    Set pivTable1 = GetPivotTable(ThisWorkbook, "Details", "PivotTable1")
    If pivTable1 Is Nothing Then
        MsgBox "Missing Pivot Table", vbInformation, "Cancelled"
        Exit Sub
    End If
    pivTable1.PivotCache.Refresh
    
    Set pivTable2 = GetPivotTable(ThisWorkbook, "Details", "PivotTable2")
    If pivTable2 Is Nothing Then
        MsgBox "Missing Pivot Table", vbInformation, "Cancelled"
        Exit Sub
    End If
    pivTable2.PivotCache.Refresh
    
    Dim periodField As PivotField
    
    On Error Resume Next
    Set periodField = pivTable1.PivotFields("Period")
    On Error GoTo 0
    If periodField Is Nothing Then
        MsgBox "Missing Pivot Field", vbInformation, "Cancelled"
        Exit Sub
    End If
    periodField.ClearAllFilters
    
    'Maybe check if date is within a certain range
'    If filterDate < minDate Or filterDate > maxDate Then
'        MsgBox "Invalid Date", vbInformation, "Cancelled"
'        Exit Sub
'    End If

    Dim filterDate As Variant
    
    On Error Resume Next
    filterDate = ThisWorkbook.Worksheets("Inputs").Range("H2").Value2
    If Err.Number <> 0 Then
        Err.Clear
        MsgBox "Missing Filter Date", vbInformation, "Cancelled"
        Exit Sub
    End If
    
    'Try String first
    If VarType(filterDate) = vbString Then
        periodField.PivotFilters.Add Type:=xlCaptionEquals, Value1:=filterDate
        If Err.Number = 0 Then Exit Sub
        
        filterDate = CDbl(CDate(filterDate))
        Err.Clear
    End If
    
    If VarType(filterDate) <> vbDouble Then
        MsgBox "Invalid Filter Date", vbInformation, "Cancelled"
        Exit Sub
    End If
    
    'Try Date (as Double data type)
    periodField.PivotFilters.Add Type:=xlSpecificDate, Value1:=filterDate
    If Err.Number <> 0 Then
        Err.Clear
        MsgBox "Could not apply filter", vbInformation, "Cancelled"
        Exit Sub
    End If
End Sub

Private Function GetPivotTable(ByVal sourceBook As Workbook _
    , ByVal wSheetName As String _
    , ByVal pivotName As String _
) As PivotTable
    On Error Resume Next
    Set GetPivotTable = sourceBook.Worksheets(wSheetName).PivotTables(pivotName)
    On Error GoTo 0
End Function



回答2:


The filter items in the pivot table are characters, not values. Therefore, under the condition that the cell format type is the same as the field format type of the pivot table, you must obtain the character, not the cell value(range("h2").Text not range("h2").value).

Sub RefreshPivots()
    Dim Ws As Worksheet
    Dim PT As PivotTable
    Dim PF As PivotField
    Dim Temp As String
    
    Temp = Sheets("Input").Range("H2").Text  '<~~ it is string  not value
    
    Set Ws = Sheets("Details")
    Set PT = Ws.PivotTables("PivotTable1")
    Set PF = PT.PivotFields("Period")
    

    PT.PivotCache.Refresh
    PF.ClearAllFilters
    
    '*** if your source type is date
    'PF.PivotFilters.Add Type:=xlSpecificDate, Value1:=Temp
    'but your source data type is string
    PF.PivotFilters.Add Type:=xlCaptionEquals, Value1:=Temp
End Sub


来源:https://stackoverflow.com/questions/63890590/vba-application-defined-or-object-error-changing-pivot-filter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!