I have a weird error with excel vba. I am trying to set the visibility to false inside a pivot table for date values. My code works fine on a dummy table, but it return an error (1004) on my real table.
Sub MultiItemPivotFilter2()
Dim PI As PivotItem
Sheets("Pivot_stocks_1").PivotTables("Pivot_Stocks_1").RefreshTable
For Each PI In Sheets("Pivot_stocks_1").PivotTables("Pivot_Stocks_1").PivotFields("date2").PivotItems
If DateValue(PI.Name) < DateValue(Sheets("Pivot_stocks_1").Range("J13").Value) Then
PI.Visible = False
Else
PI.Visible = True
End If
Next PI
End Sub
The error occurs in line PI.Visible = False
(Unable to set Visible property of the PivotItem class)
Maybe this would help you:
unable to set the visible property of the pivotitem class
Excel sometimes does not remove old entries from pivotcache on which pivot table is based.In that some item may be there which is not in source data but excel keeps it in cache for optimizing.Refreshing cache does not solve issue.Only way is remove the cache and recreate it.
You should always do your select true loop and then do a select false loop. The reason being that Excel does them one at a time and will not allow you to have everything hidden in a pivot table, it will error out (or what have you) so:
Sub MultiItemPivotFilter2()
Dim PI As PivotItem
With Sheets("Pivot_stocks_1").PivotTables("Pivot_Stocks_1")
.RefreshTable
'Loop first setting all to "True"
For Each PI In .PivotFields("date2").PivotItems
PI.Visible = True
Next PI
'Loop then setting any "False"
For Each PI In .PivotFields("date2").PivotItems
If DateValue(PI.Name) < DateValue(Sheets("Pivot_stocks_1").Range("J13").Value) Then
PI.Visible = False
End If
Next PI
End With
End Sub
Hope that makes sense!
Edit
Even if it doesn't fix your problem you should always implement this logic when hiding pivotItems
Related
I need help with some rather easy macro, but I can't do that. So all I want is to switch between filters - I have two possibilities, by example two colours - black and white, and I only want to have one of them in the moment (I want to add button, so it will work as switch). Here is the situation
I've tried did it with conditional, of course it doesn't work, but hope it will helps you to understand my idea. If one filter is enable, the other one is disabled (so the objects connected with that obviously too).
Sub Makro5()
ActiveSheet.PivotTables("PivotTable3").PivotFields("colour"). _
CurrentPage = "(All)"
If ActiveSheet.PivotTables("PivotTable3").PivotFields("colour")
.PivotItems("black").Visible = False
.PivotItems("white").Visible = True
Then ActiveSheet.PivotTables("PivotTable3").PivotFields ("colour")
.PivotItems("black").Visible = True
.PivotItems("white").Visible = False
Else: ActiveSheet.PivotTables("PivotTable3").PivotFields ("colour")
.PivotItems("black").Visible = False
.PivotItems("white").Visible = True
End Sub
Something is wrong with If, because it's on red and I get "Complie error: Syntax error" info
This is what slicers are built for.
Put your cursor inside the the pivottable data area. Then goto insert > slicer > and choose colour. You will then have a slicer which will allow you to select either or. I don't know if you can disable multiselect in current excel version so user could press ctrl and select both. But this seems a simple way.
Or you could run code such as the following and then user just types in Black or White in to field and filter is applied:
Sub Test()
Dim wb As Workbook
Dim ws As Worksheet
Dim pvt As PivotTable
Set wb = ThisWorkbook
Set ws = wb.Worksheets("Sheet3")
Set pvt = ws.PivotTables("PivotTable3")
Dim pvtField As PivotField
Dim item As Long
Dim item2 As Long
Set pvtField = pvt.PivotFields("Colour")
pvtField.EnableItemSelection = False
End Sub
You need to have the Then on the same line as the If. (You can use _ to tell VBA that "code continues on next line")
You also don't have your And set up correctly, and you are making both "Black" and "White" visible before you check if they are visible?
Try this:
Sub ToggleColour()
With ActiveSheet.PivotTables("PivotTable3").PivotFields("colour")
If .PivotItems("white").Visible=True Then
.CurrentPage = "black"
Else
.CurrentPage = "white"
End If
End With
End Sub
I want to make PivotItem.Visible = False but I keep getting an error:
Unable to set the Visible property of the PivotItem class
I tried all the solutions I found in the internet but none seems to work
Sub FloorCompareSetter()
Dim pt As PivotTable
Dim pf As PivotField
Dim pi As PivotItem
Dim PivotSheet As Worksheet
Set PivotSheet = ThisWorkbook.Worksheets("PIVOT")
PivotSheet.PivotTables("PivotTable5").RefreshTable
Set pt = PivotSheet.PivotTables("PivotTable5")
pt.PivotCache.MissingItemsLimit = xlMissingItemsNone
Set pf = pt.PivotFields("Period")
For Each pi In _
pt.PivotFields("Period").PivotItems
Select Case pi.Name
Case Is = "1601A"
pi.Visible = True
Case Else
pi.Visible = False 'error
End Select
Next pi
End Sub
I tried refreshing the table and this line but still not working:
pt.PivotCache.MissingItemsLimit = xlMissingItemsNone
Here is a picture of my pivot table:
What am i doing wrong and how can I solve this problem ?
You will get this error if you attempt to hide all the items on any axis (rows, columns, filters). You can trap this error in your code by comparing the HiddenItems.Count property of your PivotField object to the PivotItems.Count property of the same object and make sure you are not trying to remove the last item of the collection from view:
So in your case statement, you can replace with update with something like:
Select Case pi.Name
Case Is = "1601A"
pi.Visible = True
Case Else
If pf.HiddenItems.Count < (pf.PivotItems.Count - 1) Then
pi.Visible = False
Else
MsgBox "Cannot hide all the items on this axis"
Exit For '<~~ break the loop to stop the MsgBox popping up
End If
End Select
Note that whilst manipulating the pivot table Excel won't allow you to remove the last item from an axis - the OK button will become disabled:
I added
On Error Resume Next
before
pi.Visible = False 'error
it works now !
The issue of the above solutions are: Before the loop reach the expected filter value, Robin's solution will stop (suppose the ideal value is the last item, but an unwanted value is the 1st one, and being the only one selected), while Sabir's solution (On Error Resume Next) can leave an unwanted value being selected.
How about before the loop starts, set the last item as visible? Like:
maxFilterIndex = objPivotField.PivotItems.Count
objPivotField.PivotItems(maxFilterIndex).Visible = True
Then at the end of the loop, if the expected value is not in the filter at all, we can leave the last one as visible, but pop a message box saying the value is not found.
With objPivotField
maxFilterIndex = objPivotField.PivotItems.Count
objPivotField.PivotItems(maxFilterIndex).Visible = True
For i = 1 To maxFilterIndex
If objPivotField.PivotItems(i).Name = filterValue Then
objPivotField.PivotItems(i).Visible = True
Else
'This is to skip the error. But the prob is it will leave the last quarter visible, if the last elelment not being ticked.
On Error Resume Next
objPivotField.PivotItems(i).Visible = False
If i = maxFilterIndex _
And objPivotField.HiddenItems.Count = (maxFilterIndex - 1) Then
MsgBox "The chosen filter values are not found, and EXCEL can't hide all the items on this Pivot filter"
End If
End If
Next i
End With
So I'm having some issues with my VBA and toggling a PivotTable filter. This is my code:
Sub Macro2()
Sheets("Report").Visible = True
Sheets("Report").PivotTables("PivotTable1").PivotCache.Refresh
Sheets("Report").PivotTables("PivotTable1").PivotFields("dwm").ClearAllFilters
Sheets("Report").PivotTables("PivotTable1").PivotFields("dwm").CurrentPage = "1"
Sheets("Report").Activate
End Sub
I've tried using "1", 1, 1.0 and haven't had any luck. The error I get is:
"Application-defined or object-defined error"
Any help is appreciated.
For some reason Excel 2013 might have been the issue here. I managed to find a workaround should anyone else run into this issue. I used a loop which would let me edit visibility of the fields. Here was the solution:
Sub CreateReport()
Sheets("Report").Visible = True
Sheets("Report").PivotTables("PivotTable1").PivotCache.Refresh
Sheets("Report").PivotTables("PivotTable1").PivotFields("dwm").ClearAllFilters
Dim pi As PivotItem
For Each pi In Sheets("Report").PivotTables("PivotTable1").PivotFields("dwm").PivotItems
If pi.Value = 0 Then
pi.Visible = False
End If
Next pi
Sheets("Report").Activate
End Sub
I'm trying to make a macro that changes the filters of several PivotTables (not all), but i'm getting an error on the PivotFields, here's a sample of my code:
Sheets("Sheet1").PivotTables("PivotTable" & pivot_counter).PivotFields( _
"[year].[year].[year]").VisibleItemList = Array("")
My questions are:
1- Why do we use PivotFields("[year].[year].[year]") when using VisibleItemList? Why do we have to repeat it and what's the meaning of it, couldn't anything about it anywhere.
2- What is supposedly wrong with this code? My pivot table has a field called "year" and the filter is set for a specific year (let's say 2013) and i wanted it change for all possible years.
Sub Tester()
ShowAll ActiveSheet.PivotTables("PivotTable1").PivotFields("Year")
End Sub
Sub ShowAll(pf As PivotField)
Dim pi As PivotItem
Application.ScreenUpdating = False
For Each pi In pf.PivotItems
pi.Visible = True
Next pi
Application.ScreenUpdating = True
End Sub
Can some quicly explain the way to deselect all items in a newly created pivot table so that I can go back and select only one or two items? I tried the following:
.PivotItems("(Select All)").Visible = False
Thanks.
This is probably the closest you can get to what you want:
Dim i As Long
.PivotItems(1).Visible = True
For i = 2 To .PivotItems.Count
.PivotItems(i).Visible = False
Next
This will make the very first option the only selected option (assuming this is within a with that points to the pivotfield). If you know what you want before hand... modify accordingly.
I've found that looping through each data item takes a lot of time, what you can do if you want to filter on a single item in a pivot without looping through all items is use the following code:
ActiveSheet.PivotTables("Your Pivot Name").PivotFields("Your Field Name").ClearAllFilters
ActiveSheet.PivotTables("Your Pivot Name").PivotFields("Your Field Name").PivotFilters.Add _
Type:=xlCaptionEquals, Value1:="Your string here"
this is basically a label filter but it worked for me.
Check the following out. Select data for specific field name. Please do note that you have to at least select one item by default. And also do not forget that if you want to hide items, Only contiguous items in a PivotTable Field can be hidden. Perhaps at page load, or worksheet open or any of your other sub trigger, you could select a particular items to be selected based on a specific field. Then allow your code to proceed with anything else.
Sub specificItemsField()
Dim pf As PivotField
Dim pi As PivotItem
Dim strPVField As String
strPVField = "Field Name"
Set pt = ActiveSheet.PivotTables(1)
Set pf = pt.PivotFields(strPVField)
Application.ScreenUpdating = False
Application.DisplayAlerts = False
On Error Resume Next
pf.AutoSort xlManual, pf.SourceName
For Each pi In pf.PivotItems
pi.Visible = True
Next pi
pf.AutoSort xlAscending, pf.SourceName
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
This is how I do for custom filter selection. May be slower due to double looping.
Dim toSelect(1 To 3) As String
toSelect(1) = "item1"
toSelect(2) = "item2"
toSelect(3) = "item3"
For Each pvItem In objField.PivotItems
For Each st In toSelect
If pvItem.Value = st Then
pvItem.Visible = True
Exit For
Else
pvItem.Visible = False
End If
Next
Next
Well.
Because you have not how to hide all, because, always you need to have 1 item visible
I do this:
I start hiding the first field, and before go to the next, i show all fields i need visible, then, i go to the secont item, and hide, and again show all items i want, and so on. Then, always will be visible any field, and wont have error.
After the loop, i again try to show all fields i want.
With ActiveSheet.PivotTables("TablaD2").PivotFields("Entity")
Dim i As Long
For i = 1 To .PivotItems.Count
.PivotItems(i).Visible = False
.PivotItems("ARG").Visible = True
.PivotItems("BRL").Visible = True
.PivotItems("GCB").Visible = True
.PivotItems("MEX").Visible = True
Next
.PivotItems("ARG").Visible = True
.PivotItems("BRL").Visible = True
.PivotItems("GCB").Visible = True
.PivotItems("MEX").Visible = True
End With