Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Barra strumenti personalizzata e individuazione comando su cui si è cliccato

70 views
Skip to first unread message

casanmaner

unread,
May 6, 2015, 6:07:02 AM5/6/15
to
In una barra dei menù personalizzata dove sono presenti dei comandi "msoControlButton" a cui, in fase di creazione della barra, sono stati assegnati dei Tag è possibile, a seguito della loro selezione con il mouse individuare il Tag del comando azionato?
Questa è la procedura (una parte) che crea una serie di comandi "bottone" della barra in base al numero di fogli presenti nella cartella (numero che potrebbe variare e non è un dato fisso).
=========================
Sub CreaBarra
Set Barra = Application.CommandBars.Add(MenuBar:=False, Name:=NomeBarra, Temporary:=True) 'crea la barra
With Barra
.Visible = True
.Position = msoBarTop


NumSchedeProc = Worksheets.Count - 2
If NumSchedeProc > 0 Then
For x = 1 To NumSchedeProc
Set MenuBut = .Controls.Add(Type:=msoControlButton)
With MenuBut
.Style = msoButtonIconAndCaption
.BeginGroup = True
.Caption = Worksheets(x).Name
.Tag = x
.OnAction="SelezionaSchedeProcedure"
End With
Next x
End If

End With
End sub
============================

Vorrei impostare il comando OnAction di questi bottoni in modo che selezionino, tramite una apposita procedura, il foglio in base al bottone su cui si è cliccato con il mouse (e avevo pensato assegnando un Tag numerico in modo da poi eseguire il comando worksheets("NumeroTagComandoSelezionato").activate

Vi risulta essere una cosa possibile?

Maurizio Borrelli

unread,
May 6, 2015, 1:41:19 PM5/6/15
to
Ciao casanmaner,
non lo so.

Prova se questo puo' esserti utile:

Public Sub SelezionaSchedeProcedure()
v = Application.Caller
For i = LBound(v) To UBound(v)
Debug.Print v(i)
Next
End Sub

(Ma tu non usi Option Explicit?)

--
Ciao! :)
Maurizio

casanmaner

unread,
May 6, 2015, 2:05:00 PM5/6/15
to
Ciao Maurizio, grazie proverò a vedere se può essere utile la tua procedura.
Per quanto riguarda l'uso di option explicit di solito sì e in questo file lo sto utilizzando.
Quello che ho postato è solo un estratto per far capire cosa stessi facendo.
Comunque al momento mi sono dirottato su di una userform con listbox dove inserire i nomi delle schede presenti.
Mi sembra alla fin fine la soluzione più semplice anche se mi piaceva l'idea della "barra mobile" :-)

casanmaner

unread,
May 7, 2015, 1:50:15 AM5/7/15
to
Il giorno mercoledì 6 maggio 2015 19:41:19 UTC+2, Maurizio Borrelli ha scritto:
Ciao Maurizio, mi dà errore 2023.
In verità non conosco la proprietà caller e dalle istruzioni non sono riuscito bene a comprenderne l'utilizzo :-)

Maurizio Borrelli

unread,
May 7, 2015, 9:52:49 AM5/7/15
to
> > non lo so.
> > Prova se questo puo' esserti utile:
> > Public Sub SelezionaSchedeProcedure()
> > v = Application.Caller
> > For i = LBound(v) To UBound(v)
> > Debug.Print v(i)
> > Next
> > End Sub
> mi dà errore 2023.
> In verità non conosco la proprietà caller e dalle istruzioni non sono riuscito bene a comprenderne l'utilizzo :-)

Ciao casanmaner,
se la routine "SelezionaSchedeProcedure" è la Macro associata ai ControlButtons creati con la routine "CreaBarra" che ci hai mostrato non dovresti ottenere quell'errore. Ho testato le due routine in una nuova Cartella di lavoro senza problemi. Tu come hai fatto?

--
Ciao! :)
Maurizio

Maurizio Borrelli

unread,
May 7, 2015, 9:54:17 AM5/7/15
to
Il giorno giovedì 7 maggio 2015 15:52:49 UTC+2, Maurizio Borrelli ha scritto:
> Il giorno giovedì 7 maggio 2015 07:50:15 UTC+2, casanmaner ha scritto:
> > Il giorno mercoledì 6 maggio 2015 19:41:19 UTC+2, Maurizio Borrelli ha scritto:
> > > Il giorno mercoledì 6 maggio 2015 12:07:02 UTC+2, casanmaner ha scritto:
[...]
> se la routine "SelezionaSchedeProcedure" è la Macro associata ai ControlButtons creati con la routine "CreaBarra" che ci hai mostrato non dovresti ottenere quell'errore. Ho testato le due routine in una nuova Cartella di lavoro senza problemi. Tu come hai fatto?

DIMENTICAVO! Versione di Excel? Io ho testato con Excel 2003.

--
Ciao! :)
Maurizio

casanmaner

unread,
May 7, 2015, 10:28:13 AM5/7/15
to
Ho capito il perché dell'errore allora :-)
Io l'ho lanciata "diretta". Invece è da lanciare dai bottoni della barra personalizzata dopo aver assegnato come OnAction il nome di quella routine.
In una cartella di lavoro con 3 fogli da selezionare, e quindi con 3 bottoni nella barra, la proprietà caller mi restituisce, per ogni bottone, 4 valori.
I° comando (relativo al Foglio1): 1, 1, 4105, 0
II° comando (relativo al Foglio2): 3, 3, 4105, 0
III° comando (relativo al Foglio3): 5, 5, 4105, 0
Se aggiugno altri foglio, e quindi altri controlli alla barra, ho notato che il primo valore della matrice aumenta di 2 in 2 per ogni comando aggiunto. Quindi 7, 9, 11, 13 ... e così via.

casanmaner

unread,
May 7, 2015, 10:34:22 AM5/7/15
to
Quindi, in teoria, sfruttando questa progressione potrei intercettare l'indice del foglio sommando al primo valore della proprietà caller + 1 e dividendo per 2.
Per il primo foglio: (1+1)/2=1
per il foglio2: (3+1)/2=2
per il foglio3: (5+1)/2=3
per il foglio4: (7+1)/2=4
ecc. ecc.

Mi piace :-)
Non ho ancora ben compreso la funzione di caller ma questa cosa è figa :D :D :D

Maurizio Borrelli

unread,
May 7, 2015, 12:02:42 PM5/7/15
to
Ciao casanmaner.

Come dice la guida:

"Restituisce le informazioni sul richiamo di Visual Basic"

che poi in soldoni quel "richiamo" è l'oggetto o l'accrocchio che ha scatenato l'evento. In contesti diversi da quella routine bisogna usarla con cautela, testando sempre chi o cosa e' il chiamante (caller, appunto). Con funzioni come TypeName ecc.

Con i tuoi pulsanti non so bene che significato dare ai valori che ritorna ne' se sono stabili in tutte le circostanze.

Prova e facci sapere. :-)

--
Ciao! :)
Maurizio

Maurizio Borrelli

unread,
May 7, 2015, 12:31:05 PM5/7/15
to
Il giorno giovedì 7 maggio 2015 16:34:22 UTC+2, casanmaner ha scritto:
> Quindi, in teoria, sfruttando questa progressione potrei intercettare l'indice del foglio sommando al primo valore della proprietà caller + 1 e dividendo per 2.
> Per il primo foglio: (1+1)/2=1
> per il foglio2: (3+1)/2=2
> per il foglio3: (5+1)/2=3
> per il foglio4: (7+1)/2=4
> ecc. ecc.
> Mi piace :-)

Ciao casanmaner.

Mi fa piacere che ti piaccia. Se funziona e' anche "economica". Perche' l'alternativa diciamo cosi' "regolare" sarebbe creare un modulo di classe e con variabili-oggetto dichiarate con WithEvents gestire gli eventi dei pulsanti. Un po' piu' dispendioso e delicato a livello di programmazione ma sicuramente efficace.

--
Ciao! :)
Maurizio

casanmaner

unread,
May 7, 2015, 12:33:45 PM5/7/15
to
Avevo provato a individuare il tipo di dato tramite TypeName è come risultato restituiva che si tratta di un dato Variant().
Ho provato a inserire molti fogli (una trentina) a cui ho assegnato anche nomi a caso e la corrispondenza alla selezione c'è sempre.
Ho provato anche a creare la barra con soli bottoni o con bottoni all'interno di un controllo popup e il "risultato" non cambia.
Quindi in questo caso sembra ci sia "corrispondenza" e "costanza" di comportamento.
Giusto per condividere incollo il codice completo per il test fatto:
'=====================================================
'CREAZIONE DI UNA BARRA CON TANTI CONTROLLI QUANTI SONO I FOGLI DI LAVORO E MACRO CHE CONSENTE DI
'SELEZIONARE I FOGLI IN BASE AL LORO INDICE UTILIZZANDO LA PROPRIETA' COLLER E DETERMINANDO L'INDICE
'TRAMITE LA FORMULA "(CALLER VALORE(1) + 1)/2"

Option Explicit
Option Private Module

Dim Barra As CommandBar
Dim MenuPop As CommandBarPopup
Dim MenuBut As CommandBarButton
Dim NumSchedeProc As Long
Dim x As Long
Public Const NomeBarra As String = "Barra Test"

Sub Crea_Barra()
On Error Resume Next
Application.CommandBars(NomeBarra).Delete
Set Barra = Application.CommandBars.Add(MenuBar:=False, Name:=NomeBarra, Temporary:=True) 'crea la barra
With Barra
.Visible = True
.Position = msoBarTop
Set MenuPop = .Controls.Add(Type:=msoControlPopup)
With MenuPop
.Caption = "GESTIONE SCHEDE"
NumSchedeProc = Worksheets.Count
If NumSchedeProc > 0 Then
For x = 1 To NumSchedeProc
Set MenuBut = .Controls.Add(Type:=msoControlButton)
With MenuBut
.Style = msoButtonCaption
.BeginGroup = True
.Caption = Worksheets(x).Name
.Tag = x
.OnAction = "Seleziona_Schede"
End With
Next x
End If
End With 'FINE MENUPOP SCHEDE PROCEDURE
End With 'FINE BARRA
End Sub

Sub Seleziona_Schede()
Dim v As Variant
v = Application.Caller
Worksheets((v(1) + 1) / 2).Activate
End Sub
'=====================================================

ciao e grazie ancora :-)


casanmaner

unread,
May 7, 2015, 12:45:57 PM5/7/15
to
Il giorno giovedì 7 maggio 2015 18:31:05 UTC+2, Maurizio Borrelli ha scritto:

>
> Mi fa piacere che ti piaccia. Se funziona e' anche "economica". Perche' l'alternativa diciamo cosi' "regolare" sarebbe creare un modulo di classe e con variabili-oggetto dichiarate con WithEvents gestire gli eventi dei pulsanti. Un po' piu' dispendioso e delicato a livello di programmazione ma sicuramente efficace.
>

Troppo complicato per me :-) ... io "sono" solo un semplice commercialista :-)

Maurizio Borrelli

unread,
May 7, 2015, 1:05:21 PM5/7/15
to
Il giorno giovedì 7 maggio 2015 18:33:45 UTC+2, casanmaner ha scritto:
> Il giorno giovedì 7 maggio 2015 18:02:42 UTC+2, Maurizio Borrelli ha scritto:
> > Il giorno giovedì 7 maggio 2015 16:34:22 UTC+2, casanmaner ha scritto:
> > > Quindi, in teoria, sfruttando questa progressione potrei intercettare l'indice del foglio sommando al primo valore della proprietà caller + 1 e dividendo per 2.
> > > Per il primo foglio: (1+1)/2=1
> > > per il foglio2: (3+1)/2=2
> > > per il foglio3: (5+1)/2=3
> > > per il foglio4: (7+1)/2=4
> > > ecc. ecc.
> > > Mi piace :-)
> > > Non ho ancora ben compreso la funzione di caller ma questa cosa è figa :D :D :D
> > Come dice la guida:
> > "Restituisce le informazioni sul richiamo di Visual Basic"
> > che poi in soldoni quel "richiamo" è l'oggetto o l'accrocchio che ha scatenato l'evento. In contesti diversi da quella routine bisogna usarla con cautela, testando sempre chi o cosa e' il chiamante (caller, appunto). Con funzioni come TypeName ecc.
> > Con i tuoi pulsanti non so bene che significato dare ai valori che ritorna ne' se sono stabili in tutte le circostanze.
> > Prova e facci sapere. :-)
Bello! :-)

Grazie per aver condiviso.

--
Ciao! :)
Maurizio

casanmaner

unread,
May 8, 2015, 3:40:57 AM5/8/15
to
Provato anche con Excel 2003 e 2013 (ieri avevo provato con 2007) e sembra mantenere il medesimo funzionamento "regolare" :-)

casanmaner

unread,
Dec 20, 2015, 8:11:09 PM12/20/15
to
Ritorno sull'argomento per dire che in alternativa a questa soluzione ho creato una barra dove ad un controllo bottone viene assegnato il comando proprio della barra "CommandBars("Workbook Tabs").Controls(1).ID"
Non è proprio "diretto" come avere tutto l'elenco in un menù (senza menù se i fogli sono tanti la barra diventa molto estesa in orizzontale) ma ha il pregio che se alcuni fogli vengono nascosti non si è costretti comunque a creare tanti controlli bottoni (da rendere inattivi visto che i fogli sono nascosti e quindi non attivabili).

Questo un esempio della barra con il bottone con l'elenco fogli:

'---
Dim Barra As CommandBar
Dim MenuBut As CommandBarButton

Sub Crea_Barra2()
On Error Resume Next
Application.CommandBars("BarraTest").Delete
Set Barra = Application.CommandBars.Add(MenuBar:=False, Name:="BarraTest", Temporary:=True) 'crea la barra
With Barra
.Visible = True
Set MenuBut = .Controls.Add(Type:=msoControlButton, ID:=CommandBars("Workbook Tabs").Controls(1).ID)
With MenuBut
.Style = msoButtonIconAndCaption
.Caption = "Elenco schede"
.FaceId = 53
End With
End With 'fine barra
End Sub
'---
0 new messages