Discussione:
Come indicare a VBA il pulsante premuto?
(troppo vecchio per rispondere)
RE.MOTO
2020-11-20 08:28:06 UTC
Permalink
Buongiorno a tutti*

Esiste un modo per indicare a VBA il pulsante premuto? Mi spiego meglio. Se ho tre pulsanti P1, P2, P3 vorrei realizzare un Select Case dove devo poter specificare l'indicazione numero pulsante azionato.

Select Case Pulsante
Case = pulsante1
Visualizza Foglio1
Case =pulsante2
Visualizza Foglio 2
Case =pulsante 3
Visualizza Foglio3
End case

Ringrazio in anticipo per l'attenzione e per chi vorrà rispondere a questo ennesimo questo.

R.G.
casanmaner
2020-11-20 09:43:37 UTC
Permalink
Post by RE.MOTO
Buongiorno a tutti*
Esiste un modo per indicare a VBA il pulsante premuto? Mi spiego meglio. Se ho tre pulsanti P1, P2, P3 vorrei realizzare un Select Case dove devo poter specificare l'indicazione numero pulsante azionato.
Select Case Pulsante
Case = pulsante1
Visualizza Foglio1
Case =pulsante2
Visualizza Foglio 2
Case =pulsante 3
Visualizza Foglio3
End case
Ringrazio in anticipo per l'attenzione e per chi vorrà rispondere a questo ennesimo questo.
R.G.
Che tipo di pulsante è?
Un controllo "modulo" o "activex"?
ciao
RE.MOTO
2020-11-20 09:45:07 UTC
Permalink
ACTIVEX !
casanmaner
2020-11-20 10:22:27 UTC
Permalink
Post by RE.MOTO
ACTIVEX !
Prova a vedere questo file di esepio:
https://www.dropbox.com/s/x9rb0vk01syn2az/Test%20Controlli.xlsm?dl=0

Ho inserito un modulo di classe "Classe1" dove è presente questo codice:

Option Explicit

Public WithEvents CommandButton As CommandButton

Private Sub CommandButton_Click()
MsgBox CommandButton.Name
End Sub

Nel modulo standard Modulo1 ho invece inserito questo codice:
Option Explicit

Dim CommandButtons() As New Classe1

Sub ImpostaCommandButtons()
Dim ctrl As OLEObject
Dim cont As Long
For Each ctrl In ThisWorkbook.Worksheets("Foglio1").OLEObjects
If TypeName(ctrl.Object) = "CommandButton" Then
cont = cont + 1
ReDim Preserve CommandButtons(1 To cont)
Set CommandButtons(cont).CommandButton = ctrl.Object
End If
Next ctrl
End Sub

Infine nel modulo "Questa_cartella_di_lavoro" (chissà perché ad un certo punto l'hanno nominata in italiano :)) ho inserito l'evento activate della cartella di lavoro dove viene richiamata la routine ImpostaCommandBuggons:
Option Explicit

Private Sub Workbook_Activate()
Call ImpostaCommandButtons
End Sub

In questo modo quando viene cliccato su un pulsante viene lanciato un messaggio con il nome del pulsante azionato (tramite l'evento CommandButton_Click presente nel modulo di classe).

A questo punto puoi associare alla tua procedura un argomento tipo sNomePulsante as string e in base al nome eseguire il codice di interesse.

Nota che la routine ImpostaCommandButtons va eseguita quando si effettui qualche modifica al VBA che "svuota" dalla memoria i contenuti delle variabili (in questo caso CommandButtons() As New Classe1).

ciao
RE.MOTO
2020-11-21 07:23:07 UTC
Permalink
Buongiorno Casanmaner. Intanto grazie. A "pelle" capisco che la procedura è molto interessante e mi apre a nuove idee. Confesso però che non è per me di facile implementazione ed è pure la prima volta che mi trovo ad usare i moduli classe. Detto questo, vediamo se ho compreso bene cosa fare.
Ciò che desidero fare sarà consentito grazie alla interazione di tre elementi:
1) un semplice modulo dove scrive la parte operativa del codice che valuta quale tasto (numero di tasto è stato premuto e la relativa azione da compiere)
2) Questo Workbook
3) Modulo classe.
Il punto 3) crea e processa un messaggio che mette a disposizione per il Modulo Standard. Cosa mette a disposizione: il nome del pulsante azionato. E' cosi? Ho compreso bene?
Qui invece la routine dovrebbe fare in modo di capire quale pulsante è stato azionato e di conseguenza con il ciclo strutturato For Each consentire di visualizzare il foglio richiesto attraverso l'azione sul pulsante. Ho compreso bene?
:)) Io la soprannomino Questo Workbook, lo trovo più sbrigativo e di mediazione ... Purtroppo non ho compreso il ruolo di questa parte di codice. Quindi non è il modulo di classe1 che invia il messaggio ma Questo Workbook
Post by casanmaner
A questo punto puoi associare alla tua procedura un argomento tipo sNomePulsante as string e in base al nome eseguire il codice di interesse.
Ecco in questi punto non comprendo bene come agire e dove ma ci provo....
Post by casanmaner
Nota che la routine ImpostaCommandButtons va eseguita quando si effettui qualche modifica al VBA che "svuota" dalla memoria i contenuti delle variabili (in questo caso CommandButtons() As New Classe1).
Ecco in questo punto invece non comprendo bene ma credo di aver capito il senso. E cioè Classe1 porta memoria del nome del pulsante azionato che rende utile al Modulo Standard. Questo Workbook, grazie alla interazione tra questi due elementi, consente di poter agire sui vari pulsanti. Sarà così?

Ciao Casanmaner e grazie ancora, spero che tu mi possa rispondere.
Intanto ora provo a lavorarci su. Buona giornata

R.G.
casanmaner
2020-11-21 08:19:14 UTC
Permalink
Post by RE.MOTO
Buongiorno Casanmaner. Intanto grazie. A "pelle" capisco che la procedura è molto interessante e mi apre a nuove idee. Confesso però che non è per me di facile implementazione ed è pure la prima volta che mi trovo ad usare i moduli classe. Detto questo, vediamo se ho compreso bene cosa fare.
1) un semplice modulo dove scrive la parte operativa del codice che valuta quale tasto (numero di tasto è stato premuto e la relativa azione da compiere)
2) Questo Workbook
3) Modulo classe.
Il punto 3) crea e processa un messaggio che mette a disposizione per il Modulo Standard. Cosa mette a disposizione: il nome del pulsante azionato. E' cosi? Ho compreso bene?
Qui invece la routine dovrebbe fare in modo di capire quale pulsante è stato azionato e di conseguenza con il ciclo strutturato For Each consentire di visualizzare il foglio richiesto attraverso l'azione sul pulsante. Ho compreso bene?
:)) Io la soprannomino Questo Workbook, lo trovo più sbrigativo e di mediazione ... Purtroppo non ho compreso il ruolo di questa parte di codice. Quindi non è il modulo di classe1 che invia il messaggio ma Questo Workbook
Post by casanmaner
A questo punto puoi associare alla tua procedura un argomento tipo sNomePulsante as string e in base al nome eseguire il codice di interesse.
Ecco in questi punto non comprendo bene come agire e dove ma ci provo....
Post by casanmaner
Nota che la routine ImpostaCommandButtons va eseguita quando si effettui qualche modifica al VBA che "svuota" dalla memoria i contenuti delle variabili (in questo caso CommandButtons() As New Classe1).
Ecco in questo punto invece non comprendo bene ma credo di aver capito il senso. E cioè Classe1 porta memoria del nome del pulsante azionato che rende utile al Modulo Standard. Questo Workbook, grazie alla interazione tra questi due elementi, consente di poter agire sui vari pulsanti. Sarà così?
Ciao Casanmaner e grazie ancora, spero che tu mi possa rispondere.
Intanto ora provo a lavorarci su. Buona giornata
R.G.
Nel modulo di classe hai il corrispondente evento click (oltre ad altri eventi) tipico dei pulsanti (commandbutton).
Diversamente dovresti per ciascun pulsante creare tanti eventi click nel foglio dove sono presenti i pulsanti.
Lo scopo è di intercettare in un'unica procedura l'evento click e in tal modo avere un unico luogo dove intercettare quale è il pulsante su cui si è cliccato.
Diversamente nel modulo di classe del foglio (Foglio1 nell'esempio) avresti questo codice specifico per ciascun pulsante:

Private Sub CommandButton1_Click()
Call MiaRoutineBasataSulPulsante(Me.CommandButton1.Name, "Evento Click dal Modulo di classe specifico del foglio")
End Sub

Private Sub CommandButton2_Click()
Call MiaRoutineBasataSulPulsante(Me.CommandButton2.Name, "Evento Click dal Modulo di classe specifico del foglio")
End Sub

Private Sub CommandButton3_Click()
Call MiaRoutineBasataSulPulsante(Me.CommandButton3.Name, "Evento Click dal Modulo di classe specifico del foglio")
End Sub


Invece nel modulo di classe hai un'unica istruzione dell'evento Click comune a tutti i pulsanti di questo genere:

Private Sub CommandButton_Click()
Call MiaRoutineBasataSulPulsante(CommandButton.Name, "Evento Click del Modulo di Classe")
End Sub

Nel modulo1 sono presenti le istruzioni che memorizzano gli oggetti pulsante in una matrice che contiene i riferimenti agli oggetti commandbutton per fare in modo che il modulo di classe possa "intercettarne" l'azionamento.
Poiché questa matrice deve essere "riempita" con i riferimenti agli oggetti commandbutton occorre fare in modo che la routine ImpostaCommandButtons venga eseguita almeno una volta. Da qui l'utilizzo dell'evento Activate della cartella di lavoro (evento che viene eseguito anche quando si apre la cartella di lavoro e non solo quanto viene attivata passando da una diversa cartella di lavoro e questa).

Se però la cosa è troppo "complessa" puoi sempre utilizzare gli eventi click originari presenti nel modulo di classe del Foglio.

Vedi questo file dove ho inserito in modulo2 una routine che ha come argomento il nome del pulsante e viene azionata sia dagli eventi click nel foglio che quello presente nel modulo di classe.
L'ordine di esecuzione è prima gli eventi specifici dell'oggetto commandbutton del foglio e successivamente quello creato con il modulo di classe.

Otterrai due identici messaggi perché vengono azionati entrambi gli eventi click.

https://www.dropbox.com/s/h8mz10jh52vf4ut/Come%20indicare%20a%20VBA%20il%20pulsante%20premuto.xlsm?dl=0
RE.MOTO
2020-11-21 08:38:38 UTC
Permalink
Casanmaner,
mentre scrivevo un nuovo messaggio che troverai nella lista non mi ero accorto di questo messaggio che avevi composto. Ora cerco di studiarlo ...
Post by casanmaner
Post by RE.MOTO
Buongiorno Casanmaner. Intanto grazie. A "pelle" capisco che la procedura è molto interessante e mi apre a nuove idee. Confesso però che non è per me di facile implementazione ed è pure la prima volta che mi trovo ad usare i moduli classe. Detto questo, vediamo se ho compreso bene cosa fare.
1) un semplice modulo dove scrive la parte operativa del codice che valuta quale tasto (numero di tasto è stato premuto e la relativa azione da compiere)
2) Questo Workbook
3) Modulo classe.
Il punto 3) crea e processa un messaggio che mette a disposizione per il Modulo Standard. Cosa mette a disposizione: il nome del pulsante azionato. E' cosi? Ho compreso bene?
Qui invece la routine dovrebbe fare in modo di capire quale pulsante è stato azionato e di conseguenza con il ciclo strutturato For Each consentire di visualizzare il foglio richiesto attraverso l'azione sul pulsante. Ho compreso bene?
:)) Io la soprannomino Questo Workbook, lo trovo più sbrigativo e di mediazione ... Purtroppo non ho compreso il ruolo di questa parte di codice. Quindi non è il modulo di classe1 che invia il messaggio ma Questo Workbook
Post by casanmaner
A questo punto puoi associare alla tua procedura un argomento tipo sNomePulsante as string e in base al nome eseguire il codice di interesse.
Ecco in questi punto non comprendo bene come agire e dove ma ci provo....
Post by casanmaner
Nota che la routine ImpostaCommandButtons va eseguita quando si effettui qualche modifica al VBA che "svuota" dalla memoria i contenuti delle variabili (in questo caso CommandButtons() As New Classe1).
Ecco in questo punto invece non comprendo bene ma credo di aver capito il senso. E cioè Classe1 porta memoria del nome del pulsante azionato che rende utile al Modulo Standard. Questo Workbook, grazie alla interazione tra questi due elementi, consente di poter agire sui vari pulsanti. Sarà così?
Ciao Casanmaner e grazie ancora, spero che tu mi possa rispondere.
Intanto ora provo a lavorarci su. Buona giornata
R.G.
Nel modulo di classe hai il corrispondente evento click (oltre ad altri eventi) tipico dei pulsanti (commandbutton).
Diversamente dovresti per ciascun pulsante creare tanti eventi click nel foglio dove sono presenti i pulsanti.
Lo scopo è di intercettare in un'unica procedura l'evento click e in tal modo avere un unico luogo dove intercettare quale è il pulsante su cui si è cliccato.
Private Sub CommandButton1_Click()
Call MiaRoutineBasataSulPulsante(Me.CommandButton1.Name, "Evento Click dal Modulo di classe specifico del foglio")
End Sub
Private Sub CommandButton2_Click()
Call MiaRoutineBasataSulPulsante(Me.CommandButton2.Name, "Evento Click dal Modulo di classe specifico del foglio")
End Sub
Private Sub CommandButton3_Click()
Call MiaRoutineBasataSulPulsante(Me.CommandButton3.Name, "Evento Click dal Modulo di classe specifico del foglio")
End Sub
Private Sub CommandButton_Click()
Call MiaRoutineBasataSulPulsante(CommandButton.Name, "Evento Click del Modulo di Classe")
End Sub
Nel modulo1 sono presenti le istruzioni che memorizzano gli oggetti pulsante in una matrice che contiene i riferimenti agli oggetti commandbutton per fare in modo che il modulo di classe possa "intercettarne" l'azionamento.
Poiché questa matrice deve essere "riempita" con i riferimenti agli oggetti commandbutton occorre fare in modo che la routine ImpostaCommandButtons venga eseguita almeno una volta. Da qui l'utilizzo dell'evento Activate della cartella di lavoro (evento che viene eseguito anche quando si apre la cartella di lavoro e non solo quanto viene attivata passando da una diversa cartella di lavoro e questa).
Se però la cosa è troppo "complessa" puoi sempre utilizzare gli eventi click originari presenti nel modulo di classe del Foglio.
Vedi questo file dove ho inserito in modulo2 una routine che ha come argomento il nome del pulsante e viene azionata sia dagli eventi click nel foglio che quello presente nel modulo di classe.
L'ordine di esecuzione è prima gli eventi specifici dell'oggetto commandbutton del foglio e successivamente quello creato con il modulo di classe.
Otterrai due identici messaggi perché vengono azionati entrambi gli eventi click.
https://www.dropbox.com/s/h8mz10jh52vf4ut/Come%20indicare%20a%20VBA%20il%20pulsante%20premuto.xlsm?dl=0
RE.MOTO
2020-11-21 08:49:22 UTC
Permalink
Grazie ora vedo cosa riesco a combinare con le tue indicazioni e "prescrizioni" :)) grazie
RE.MOTO
2020-11-21 12:28:32 UTC
Permalink
Post by RE.MOTO
Grazie ora vedo cosa riesco a combinare con le tue indicazioni e "prescrizioni" :)) grazie
A seconda del pulsante dovrai associare il nome del foglio diverso.
Se con il pulsante 1 vuoi selezionare il "Foglio2" dovrai associare tale nome all'istruzione >Worksheets(NomeInBaseAlPulsanteCliccato).Select
Purtroppo non riesco a comprendere dove scrivere questa istruzione "Worksheets(NomeInBaseAlPulsanteCliccato).Select ", cioè se dovrò scriverla in Classe1 oppure in Questo Workbook oppure in Foglio1 dove ci sono i tre eventi CmmandButtonx_clicl()...

Sono in panne!
casanmaner
2020-11-21 15:04:54 UTC
Permalink
Post by RE.MOTO
Post by RE.MOTO
Grazie ora vedo cosa riesco a combinare con le tue indicazioni e "prescrizioni" :)) grazie
A seconda del pulsante dovrai associare il nome del foglio diverso.
Se con il pulsante 1 vuoi selezionare il "Foglio2" dovrai associare tale nome all'istruzione >Worksheets(NomeInBaseAlPulsanteCliccato).Select
Purtroppo non riesco a comprendere dove scrivere questa istruzione "Worksheets(NomeInBaseAlPulsanteCliccato).Select ", cioè se dovrò scriverla in Classe1 oppure in Questo Workbook oppure in Foglio1 dove ci sono i tre eventi CmmandButtonx_clicl()...
Sono in panne!
Vediamo se con un esempio più semplice riesci a capirti:

https://www.dropbox.com/s/hu3x6i9h9tpeob7/Come%20indicare%20a%20VBA%20il%20pulsante%20premuto%20%282%29.xlsm?dl=0

Nel VBA del Foglio1 ho inserito gli eventi click dei tre pulsanti

Option Explicit

Private Sub CommandButton1_Click()
Call MiaRoutineBasataSulPulsante("Foglio2")
End Sub

Private Sub CommandButton2_Click()
Call MiaRoutineBasataSulPulsante("Foglio3")
End Sub

Private Sub CommandButton3_Click()
Call MiaRoutineBasataSulPulsante("Foglio4")
End Sub

Nel Modulo1 la routine la quale ha come argomento il nome del foglio da selezionare e la cui unica istruzione, di selezione del foglio, fa riferimento all'argomento passato da ciascun pulsante:


Sub MiaRoutineBasataSulPulsante(sNomeFoglioDaSelezionare)
Worksheets(sNomeFoglioDaSelezionare).Select
End Sub
RE.MOTO
2020-11-23 06:59:33 UTC
Permalink
Grazie Casanmaner, non ho ancora proceduto all'applicazione dei tuoi suggerimenti. Spero di riuscirci oggi. Ho voluto dare precedenza alla soluzione di altro problema ma che interessa sempre il progetto del team di cui faccio parte.
RE.MOTO
2020-11-21 08:21:59 UTC
Permalink
Ciao Casanmaner,

nell'esempio che mi hai fornito, per mia incapacità, non riesco ad associare la visualizzazione dei fogli ai tre pulsanti inserendola nel codice. Mi spiego: nel tuo file di esempio, a Foglio1 ho aggiunto tre fogli per sperimentare appunto la visualizzazione dei tre fogli. Agendo nel codice che mi hai fornito alla pressione del 3 pulsanti non riesco a visualizzare o il Foglio2 o il Foglio3 o il Foglio4.
Post by casanmaner
A questo punto puoi associare alla tua procedura un argomento tipo sNomePulsante as string e in base al nome eseguire il codice di interesse.
non comprendo quali azioni determinare o meglio capisco che in una determinata parte del codice dovrò scrivere "Worksheets("Foglio2").Select", "Worksheets("Foglio2").Select", "Worksheets("Foglio2").Select" ovvero un elenco di fogli da visualizzare (sono 14 fogli)
casanmaner
2020-11-21 08:37:32 UTC
Permalink
Post by RE.MOTO
Ciao Casanmaner,
nell'esempio che mi hai fornito, per mia incapacità, non riesco ad associare la visualizzazione dei fogli ai tre pulsanti inserendola nel codice. Mi spiego: nel tuo file di esempio, a Foglio1 ho aggiunto tre fogli per sperimentare appunto la visualizzazione dei tre fogli. Agendo nel codice che mi hai fornito alla pressione del 3 pulsanti non riesco a visualizzare o il Foglio2 o il Foglio3 o il Foglio4.
Post by casanmaner
A questo punto puoi associare alla tua procedura un argomento tipo sNomePulsante as string e in base al nome eseguire il codice di interesse.
non comprendo quali azioni determinare o meglio capisco che in una determinata parte del codice dovrò scrivere "Worksheets("Foglio2").Select", "Worksheets("Foglio2").Select", "Worksheets("Foglio2").Select" ovvero un elenco di fogli da visualizzare (sono 14 fogli)
A seconda del pulsante dovrai associare il nome del foglio diverso.
Se con il pulsante 1 vuoi selezionare il "Foglio2" dovrai associare tale nome all'istruzione Worksheets(NomeInBaseAlPulsanteCliccato).Select
Loading...