La sincronizzazione delle affettatrici può essere eseguita in modo generico.
Con "generico" intendo che non ci dovrebbero essere dipendenze sui nomi di cache slicer (letterali) e la sincronizzazione potrebbe iniziare da qualsiasi cache di slicer.
L'approccio per risolvere questo problema è salvare lo stato di tutti gli oggetti della cache slicer. Dopo una modifica in una tabella pivot (sottostante una o più cache di slicer) i nuovi stati possono essere confrontati con i vecchi stati e le cache aggiornate riconosciute. Da lì la sincronizzazione può essere compiuta.
La mia soluzione si compone di 4 fasi:
1) Creare clsWrapperCache
, una classe wrapper per Excel SlicerCache oggetto
2) creare clsWrapperCaches
, una classe collezione di clsWrapperCache oggetti
3) creare clsCacheManager
, una classe di manager per trattare con SlicerCache oggetto afferma
4) ThisWorkbook
, impostando le chiamate al gestore
1) clsWrapperCache, classe wrapper di oggetti di Excel SlicerCache
' wrapper class around Excel SlicerCache object
Option Explicit
Public Object As SlicerCache
Public OldState As String
Public Function CurrentState() As String
' state is set by:
' a) name of first visible slicer item
' b) number of visible slicer items
Dim s As String
If Object.VisibleSlicerItems.Count > 0 Then
s = Object.VisibleSlicerItems.Item(1).Name
Else
s = ""
End If
s = s & vbCrLf ' separator that cannot be found in a SlicerItem name
s = s & CStr(Object.VisibleSlicerItems.Count)
CurrentState = s
End Function
clsWrapperCache
contiene un oggetto SlicerCache di Excel.
Ancora più importante: può amministrare lo stato di un SlicerCache. Stato Ottenere può essere fatto molto velocemente, ossia concatenando:
- il nome del 1 ° VisibleSlicerItem e
- il numero di VisibleSlicerItems.
OldState
è inizialmente impostato nel Set_Caches
di routine (fase 3) e può essere ripristinato in de Synchronize_Caches
di routine (fase 3) se la cache affettatrice è stato coinvolto nel processo di sincronizzazione.
2) clsWrapperCaches, classe di raccolta di oggetti clsWrapperCache
' clsWrapperCaches, collection class of clsWrapperCache objects
Option Explicit
Private mcol As New Collection
Public Sub Add(oWC As clsWrapperCache)
mcol.Add oWC, oWC.Object.Name
End Sub
Public Property Get Item(vIndex As Variant) As clsWrapperCache
' vIndex may be of type integer or string
Set Item = mcol(vIndex)
End Property
Public Property Get Count() As Integer
Count = mcol.Count
End Property
Questa è una semplice classe di raccolta, semplicemente tiene clsWrapperCache
oggetti. Verrà utilizzato per contenere oggetti nella raccolta AllCaches
.
3) clsCacheManager, classe per trattare con oggetti stati SlicerCache
Option Explicit
Public AllCaches As New clsWrapperCaches
Public Sub Set_Caches()
Dim sc As SlicerCache
Dim oWC As clsWrapperCache
Dim i As Integer
If Me.AllCaches.Count <> ThisWorkbook.SlicerCaches.Count Then
' a) on Workbook_Open event
' b) maybe the user has added/deleted a Slice Cache shape by hand
Set AllCaches = New clsWrapperCaches
For Each sc In ThisWorkbook.SlicerCaches
'create a wrapper SlicerCache object
Set oWC = New clsWrapperCache
Set oWC.Object = sc
'save current state of SlicerCache into OldState
oWC.OldState = oWC.CurrentState
' add wrapper object to collection
AllCaches.Add oWC
Next
End If
End Sub
Sub Synchronize_Caches()
' copy current selections from slicer caches "FromCaches" into any other slicer cache with same SourceName
On Error GoTo ErrEx
Dim oWCfrom As clsWrapperCache
Dim oWCto As clsWrapperCache
Dim scFrom As SlicerCache
Dim scTo As SlicerCache
Dim si As SlicerItem
Dim i As Integer
Dim j As Integer
Application.EnableEvents = False ' prevent executing Workbook_SheetPivotTableUpdate event procedure
Application.ScreenUpdating = False
For i = 1 To Me.AllCaches.Count
Set oWCfrom = Me.AllCaches.Item(i)
If oWCfrom.CurrentState <> oWCfrom.OldState Then
Set scFrom = oWCfrom.Object
For j = 1 To Me.AllCaches.Count
Set oWCto = Me.AllCaches.Item(j)
Set scTo = oWCto.Object
' Debug.Print oWCto.Name
If scTo.Name <> scFrom.Name And scTo.SourceName = scFrom.SourceName Then
scTo.ClearAllFilters ' triggers a Workbook_SheetPivotTableUpdate event
On Error Resume Next
For Each si In scFrom.SlicerItems
scTo.SlicerItems(si.Name).Selected = si.Selected
Next
On Error GoTo 0
' update old state of wrapper object oWCto
oWCto.OldState = oWCto.CurrentState
End If
Next
' update old state of wrapper object oWCfrom
oWCfrom.OldState = oWCfrom.CurrentState
End If
Next
Ex:
Application.EnableEvents = True
Application.ScreenUpdating = True
Exit Sub
ErrEx:
MsgBox Err.Description
Resume Ex
End Sub
Classe clsCacheManager gestisce gli stati di cache con metodi Set_Caches
e Synchronize_Caches
.
Set_Caches
: se il numero di cache in ThisWorkbook è diverso da quello di AllCaches, la raccolta AllCaches viene (ri) creata. Con la presente il OldState
di ogni cache di slicer viene salvato.
Synchronize_Caches
: tutte le cache sono attraversate qui. Se una cache di slicer è stata aggiornata (oWCfrom.CurrentState <> oWCfrom.OldState
) rispetto a qualsiasi altra cache con lo stesso SourceName (ad esempio "anno") verrà aggiornata. L'aggiornamento è copiando tutte le selezioni di elementi slicer dalla cache di origine alla cache di destinazione. OldState
per tutte le cache interessate viene ripristinato allo stato corrente al termine del processo di sincronizzazione.
4) ThisWorkbook, impostando le chiamate al gestore della cache
Option Explicit
Private mCacheManager As New clsCacheManager
Private Sub Workbook_Open()
SetCacheManager
mCacheManager.Set_Caches
End Sub
Private Sub Workbook_SheetPivotTableUpdate(ByVal Sh As Object, ByVal Target As PivotTable)
SetCacheManager
mCacheManager.Set_Caches
mCacheManager.Synchronize_Caches
End Sub
Private Sub SetCacheManager()
If mCacheManager Is Nothing Then
Set mCacheManager = New clsCacheManager
End If
End Sub
benefici Alle dal punti da 1 a 3 possono essere sfruttati al punto 4: possiamo fare chiamate a CacheManager come SetCaches
o Synchronize_Caches
. Questo codice è facile da leggere.
I vantaggi di questa soluzione:
- funziona per tutte le cache affettatrice in una cartella di lavoro
- non dipende da nomi SlicerCache
- molto veloce, perché gli stati degli oggetti di cache affettatrice si ottengono molto veloce
- estendibile. La classe
clsCacheManager
potrebbe essere estesa per gestire le dipendenze tra le cache di slicer.
Hai visto [questo] (http://www.jkp-ads.com/articles/slicers04.asp) –
Anche se @SiddharthRout postato un link che forse risolve il problema, è possibile provare la sincronizzazione * Affettatrici * semplicemente sincronizzando una tabella * Pivot * collegata di ciascuna. Ho pubblicato un esempio che spero ti dia l'idea. – L42