How to select one slicer = true and remaining = false in VBA - vba

Trying to narrow down this VBA script w/o having to list out . I'm a basic Macro user. How can I get one selected = True and the rest = False without having to list all 160?
With ActiveWorkbook.SlicerCaches("Slicer_Organization")
.SlicerItems("900110 - Danish Bemidji ").Selected = True
.SlicerItems("900101 - Arabic Bemidji").Selected = False
.SlicerItems("900105 - Chinese Callaway 1st Half").Selected = False
.SlicerItems("900106 - Chinese Callaway 2nd Half").Selected = False
.SlicerItems("900115 - Finnish Bemidji ").Selected = False
.SlicerItems("900120 - French Bemidji 1st Half ").Selected = False
.SlicerItems("900121 - French Bemidji 2nd Half ").Selected = False

Filtering SlicerItems can be tricky, because at least one item must remain visible at all times.
This code shows how to filter a Slicer on an array called vSelection. To amend to your needs, just change the vSelection = Array("B", "C", "E") line so that it contains the item(s) of interest.
Option Explicit
Sub FilterSlicer()
Dim slr As Slicer
Dim sc As SlicerCache
Dim si As SlicerItem
Dim i As Long
Dim vItem As Variant
Dim vSelection As Variant
Set sc = ActiveWorkbook.SlicerCaches("Slicer_ID")
vSelection = Array("B", "C", "E")
For Each pt In sc.PivotTables
pt.ManualUpdate = True 'Stops PivotTable from refreshing after each PivotItem is changed
Next pt
With sc
'At least one item must remain visible in the Slicer at all times, so make the first
'item visible, and at the end of the routine, check if it actually *should* be visible
.SlicerItems(1).Selected = True
'Hide any other items that aren't already hidden.
'Note that it is far quicker to check the status than to change it.
' So only hide each item if it isn't already hidden
For i = 2 To .SlicerItems.Count
If .SlicerItems(i).Selected Then .SlicerItems(i).Selected = False
Next i
'Make the PivotItems of interest visible
On Error Resume Next 'In case one of the items isn't found
For Each vItem In vSelection
.SlicerItems(vItem).Selected = True
Next vItem
On Error GoTo 0
'Hide the first PivotItem, unless it is one of the countries of interest
On Error Resume Next
If InStr(UCase(Join(vSelection, "|")), UCase(.SlicerItems(1).Name)) = 0 Then .SlicerItems(1).Selected = False
If Err.Number <> 0 Then
.ClearAllFilters
MsgBox Title:="No Items Found", Prompt:="None of the desired items was found in the Slicer, so I have cleared the filter"
End If
On Error GoTo 0
End With
For Each pt In sc.PivotTables
pt.ManualUpdate = False
Next pt
End Sub

You can loop through all SlicerItems in your SlicerCache using a For Each loop:
Dim si as SlicerItem
For Each si In ActiveWorkbook.SlicerCaches("Slicer_Organization").SlicerItems
si.Selected = (si.Name = "900110 - Danish Bemidji")
Next si
That (si.Name = "900110 - Danish Bemidji") will return a True or False and set the Selected property of the SlicerItem you are iterating appropriately.

Sub ExcelGuruVG()
Dim myval As String
myval = "VG"
Dim sli as SlicerItem
with Activeworkbook.slicercaches("Slicer_SLICERNAME")
for Each sli in SlicerItems
if sli.Name = myval then
sli.select = true
Else
sli.selected = False
End if
Next sli
End with
End Sub

I tried the code that was shared by Venugopal and combined it with JNevill's code, and it worked!
Thanks a bunch to both of you!
The adjustment I made is as below:
Sub ExcelGuruVG()
Dim myval As String
myval = ThisWorkbook.Worksheets("Sheet1").Range("A2").Value 'Taking the value from Sheet1 in Cell A2
Dim sli As SlicerItem
With ActiveWorkbook.SlicerCaches("Slicer_SlicerName1")
For Each sli In ActiveWorkbook.SlicerCaches("Slicer_SlicerName1").SlicerItems
If sli.Name = myval Then
sli.Selected = True
Else
sli.Selected = False
End If
Next sli
End With
End Sub

Related

Macro fires 50% of the time when changing slicer item

I have a particular problem and couldn't find any solution anywhere on the internet.
So I have a pivot table which is connected to 6 slicers and also a chart which data range is dependent on pivot table values.
I've made a macro which updates chart scales everytime a value in any of the worksheet cells is changed. Here is the macro:
Public Sub worksheet_Change(ByVal Target2 As Range)
If ActiveSheet.Name = "Dashboard" Then
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DataEntryMode = xlOff
'Chart_axis Macro
Sheets("Dashboard").ChartObjects("Chart 9").Activate
If ActiveSheet.Range("B19") = "excluding CE" Then
ActiveChart.Axes(xlValue).MinimumScale = Range("E3").Value
ActiveChart.Axes(xlValue).MaximumScale = Range("E4").Value
Else
ActiveChart.Axes(xlValue).MinimumScale = Range("A3").Value
ActiveChart.Axes(xlValue).MaximumScale = Range("A4").Value
End If
ActiveChart.Refresh
ActiveSheet.Range("B18").Select
Application.EnableEvents = True
Application.ScreenUpdating = True
End If
End Sub
In order to work as intended i also had to made a function which reads the active elements of a slicer:
Public Function GetSelectedSlicerItems(SlicerName As String) As String
Application.Volatile
Set coll = New Collection
Dim cache As Excel.SlicerCache
Dim i As Integer
Set cache = ActiveWorkbook.SlicerCaches(SlicerName)
Dim sItem As Excel.SlicerItem
Dim result As String
For Each sItem In cache.SlicerItems
If sItem.Selected And sItem.HasData Then
'Debug.Print sItem.Name
'Debug.Print sItem.HasData
'GetSelectedSlicerItems = (sItem.Name)
coll.Add sItem.Name
End If
Next sItem
For i = 1 To coll.Count
'Debug.Print coll(i)
result = result & coll(i) & ", "
Next i
result = Left(result, Len(result) - 2)
GetSelectedSlicerItems = result
End Function
My problem is that while the value of the function always updates when the slicer item is changed, the macro only does it randomly about 50% of the time.
Screenshot of my report:
The formulas containing the selected slicer items function are on the top right.
So do you have any idea how to make it work 100% of the time?
Thanks in advance,
Alan
Edit: i forgot to add that it's only the issue if only one slicer is highlited. When i select multiple slicers (with ctrl+click) it always works.

VBA filtering dates

This is my function, the code stops on the line "If pitem.visible=True" on the first iteration (line 17). While the code is running, I always have visible items int the field.
The code is not even setting any property to visible and it's working very well if I filter anything other than a date.
Function tableau()
Dim fld As PivotField
Dim pitem As PivotItem
Dim i As Long
Dim arr() As Variant
Dim a As String
Dim pvt As String
pvt = "PivotTable"
Sheets("Données").ListObjects("table1").AutoFilter.ShowAllData
Sheets("PivotTableSheet").Activate
Sheets("PivotTableSheet").PivotTables(pvt).ManualUpdate = True
Sheets("PivotTableSheet").PivotTables(pvt).PivotFields("Date").EnableMultiplePageItems = True
For Each fld In Sheets("PivotTableSheet").PivotTables(pvt).PivotFields
If fld.Orientation <> xlHidden And (fld.Orientation = xlPageField) Then 'loop through filtered pivot fields
i = 1
For Each pitem In fld.PivotItems 'loop through visible items in filtered pivot fields
If pitem.Visible = True Then
ReDim Preserve arr(1 To i) As Variant
arr(i) = pitem
i = i + 1
End If
Next pitem
Sheets("Données").ListObjects("table1").Range.AutoFilter Field:=TRVFILTRE(fld.Name), Criteria1:=arr, Operator:=xlFilterValues
End If
Next fld
Sheets("PivotTableSheet").PivotTables(pvt).ManualUpdate = False
End Function
When iterating over PivotItems, there's a couple of bottlenecks and gotchas that you want to avoid. See my post at http://dailydoseofexcel.com/archives/2013/11/14/filtering-pivots-based-on-external-ranges/ for more on this.
Among other things, you want to set the PivotTable's ManualUpdate property to TRUE while you do the iteration and then back to FALSE when you're done. Otherwise Excel will try to update the PivotTable each time you change the visibility of a PivotItem. And you also want to ensure that at least one item remains visible at all times. I use something like this:
Option Explicit
Sub FilterPivot()
Dim pt As PivotTable
Dim pf As PivotField
Dim pi As PivotItem
Dim i As Long
Dim vItem As Variant
Dim vItems As Variant
Set pt = ActiveSheet.PivotTables("PivotTable1") '<= Change to match your PivotTable
Set pf = pt.PivotFields("CountryName") '<= Change to match your PivotField
vItems = Array("FRANCE", "BELGIUM", "LUXEMBOURG") '<= Change to match the list of items you want to remain visible
pt.ManualUpdate = True 'Stops PivotTable from refreshing after each PivotItem is changed
With pf
'At least one item must remain visible in the PivotTable at all times, so make the first
'item visible, and at the end of the routine, check if it actually *should* be visible
.PivotItems(1).Visible = True
'Hide any other items that aren't already hidden.
'Note that it is far quicker to check the status than to change it.
' So only hide each item if it isn't already hidden
For i = 2 To .PivotItems.Count
If .PivotItems(i).Visible Then .PivotItems(i).Visible = False
Next i
'Make the PivotItems of interest visible
On Error Resume Next 'In case one of the items isn't found
For Each vItem In vItems
.PivotItems(vItem).Visible = True
Next vItem
On Error GoTo 0
'Hide the first PivotItem, unless it is one of the countries of interest
On Error Resume Next
If InStr(UCase(Join(vItems, "|")), UCase(.PivotItems(1))) = 0 Then .PivotItems(1).Visible = False
If Err.Number <> 0 Then
.ClearAllFilters
MsgBox Title:="No Items Found", Prompt:="None of the desired items was found in the Pivot, so I have cleared the filter"
End If
On Error GoTo 0
End With
pt.ManualUpdate = False
End Sub
You don't have to iterate through PivotItems if all you want to do is make each PivotItem visible. Instead, just use the .ClearAllFilters method.
Something like:
With Sheets("PivotTableSheet").PivotTable("PivotTable").PivotFields("Date")
.ClearAllFilters
.CurrentPage = "(All)"
End With

unable to update slicer value using VBA

The following is the code i am using to update the value of my slicer.
Sub country_select()
Application.ScreenUpdating = False
country_selected = ActiveSheet.Shapes(Application.Caller).Name
ActiveWorkbook.SlicerCaches("Slicer_Country").ClearManualFilter
For Count = 1 To 13 'countries
country = Sheet5.Range("E2").Offset(Count, 0).Value
If country = country_selected Then
ActiveWorkbook.SlicerCaches("Slicer_Country").SlicerItems(country).Selected = True
Else
ActiveWorkbook.SlicerCaches("Slicer_Country").SlicerItems(country).Selected =
False
End If
Next Count
Application.ScreenUpdating = True
End Sub
The country variable is not updating its value(only taking empty value).
I don't understand the reason for this.
I am trying to link a map to a macro hence the input.
I'm not sure why you need to interate through the range E3:E14. If all you want to do is to set the Slicer to show the item corresponding to the shape the user has selected, I would just use something like this:
Option Explicit
Sub country_select()
Dim si As SlicerItem
Dim Country As String
Dim sc As SlicerCache
Application.ScreenUpdating = False
Country = ActiveSheet.Shapes(Application.Caller).Name
Set sc = ActiveWorkbook.SlicerCaches("Slicer_Country")
With sc
.ClearAllFilters
For Each si In sc.SlicerItems
If si.Name <> Country Then si.Selected = False
Next si
End With
Application.ScreenUpdating = True
End Sub
Note that if the slicer was for a PivotTable (and not for a Table) I would set the .ManualUpdate propery of the PivotTable to TRUE before the loop, and to FALSE after, so that the PivotTable didn't try to update after each and every SlicerItem is selected.
And if this was for a PivotTable (and not for a Table) there is no need to iterate over a Slicer at all (which is inefficient/slow). Instead, just put the Country field in the Pivot as a PageField, and just set the .CurrentPage of the PageField directly, like so:
Sub FilterPivot()
Dim pf As PivotField
Set pf = ActiveSheet.PivotTables("PivotTable1").PivotFields("Country")
pf.CurrentPage = Application.Caller
End Sub

How to update slicer cache with VBA

I'm using Excel VBA to hide/show elements on slicer depending upon user selection.
I have the following code :
Private Sub removeFilterWithSlicer()
Dim slicerCache As slicerCache
Set slicerCache = ThisWorkbook.SlicerCaches("Slicer_Channel1")
slicerCache.SlicerItems("A").Selected = False
slicerCache.SlicerItems("B").Selected = False
slicerCache.SlicerItems("C").Selected = False
slicerCache.SlicerItems("D").Selected = False
slicerCache.SlicerItems("E").Selected = False
slicerCache.SlicerItems("F").Selected = False
End Sub
where A, B etc. are names of elements in slicer. I've cross checked the name of slicer cache ("Slicer_Channel1"). The issue is that the elements don't get deselected as they are supposed to. When I'm debugging the code, I found that each element gets deselected one by one but as soon as I reach the end of procedure i.e. End Sub, they all get back to being in selected state.
Any pointers ?
This code shows how to filter a Slicer on an array called vSelection.
Option Explicit
Sub FilterSlicer()
Dim slr As Slicer
Dim sc As SlicerCache
Dim si As SlicerItem
Dim i As Long
Dim vItem As Variant
Dim vSelection As Variant
Set sc = ActiveWorkbook.SlicerCaches("Slicer_ID")
'Set sc = slr.SlicerCache
vSelection = Array("B", "C", "E")
For Each pt In sc.PivotTables
pt.ManualUpdate = True 'Stops PivotTable from refreshing after each PivotItem is changed
Next pt
With sc
'At least one item must remain visible in the Slicer at all times, so make the first
'item visible, and at the end of the routine, check if it actually *should* be visible
.SlicerItems(1).Selected = True
'Hide any other items that aren't already hidden.
'Note that it is far quicker to check the status than to change it.
' So only hide each item if it isn't already hidden
For i = 2 To .SlicerItems.Count
If .SlicerItems(i).Selected Then .SlicerItems(i).Selected = False
Next i
'Make the PivotItems of interest visible
On Error Resume Next 'In case one of the items isn't found
For Each vItem In vSelection
.SlicerItems(vItem).Selected = True
Next vItem
On Error GoTo 0
'Hide the first PivotItem, unless it is one of the countries of interest
On Error Resume Next
If InStr(UCase(Join(vSelection, "|")), UCase(.SlicerItems(1).Name)) = 0 Then .SlicerItems(1).Selected = False
If Err.Number <> 0 Then
.ClearAllFilters
MsgBox Title:="No Items Found", Prompt:="None of the desired items was found in the Slicer, so I have cleared the filter"
End If
On Error GoTo 0
End With
For Each pt In sc.PivotTables
pt.ManualUpdate = False
Next pt
End Sub
at least one has to be selected. works the same way when selecting with a mouse. you cannot un-select all

Excel Command Button to Simultaneously Check and Uncheck certain Active-X checkboxes

I am trying to use an Active-X Command button in Excel to select certain checkboxes and deselect others simultaneously. As it stands right now, I wish to uncheck all boxes that start with or contain the name "Design" while checking all those that start with or contain the name "Checkbox".
The code below was working for the unchecking of boxes that have "Design" in their name, but ever since I have added the checking of boxes starting with "Checkbox", I receive an error (Method "Name" of object'_OLEOBJECT' Failed).
Private Sub CommandButton1_Click()
Dim o As Object
For Each o In ActiveSheet.OLEObjects
If InStr(1, o.Name, "Design") > 0 Then
o.Object.Value = False
ElseIf InStr(1, o.Name, "CheckBox") < 1 Then
o.Object.Value = True
End If
Next
End Sub
I have also tried this variation which still results in the same error as the above:
Private Sub CommandButton1_Click()
Dim o As Object
For Each o In ActiveSheet.OLEObjects
If InStr(1, o.Name, "Design") > 0 Then
o.Object.Value = False
End If
Next
Dim j As Object
For Each j In ActiveSheet.OLEObjects
If InStr(1, j.Name, "CheckBox") < 1 Then
j.Object.Value = True
End If
Next
End Sub
Try this, it unchecks all checkboxes. Just set it to true if you want to check all checkboxes.
Sub uncheck_all()
Dim sh As Shape
Application.ScreenUpdating = False
For Each sh In ActiveSheet.Shapes
If sh.Type = msoOLEControlObject Then
If TypeName(sh.OLEFormat.Object.Object) = "CheckBox" Then sh.OLEFormat.Object.Object = True 'set to true if you want to check all checkboxes
End If
If sh.Type = msoFormControl Then
If sh.FormControlType = xlCheckBox Then sh.OLEFormat.Object = True 'set to true if you want to check all checkboxes
End If
Next sh
Dim o As Object
For Each o In ActiveSheet.OLEObjects
If o.Name Like "Design*" Then 'use If o.Name Like "*Design*" Then if you want to be any name with "Design" in the name.
o.Object.Value = False
End If
Next o
Application.ScreenUpdating = True
End Sub