TOP

VBA-Lezione 12.2. Controlli (Controls)

I controlli (Controls) hanno tutti i tipi di proprietà e molti eventi ad essi associati, ma per ora ne vedremo solo alcuni utilizzati nella programmazione su VBA.


Iniziamo aggiungendo 3 controlli: Label, TextBox e CommandButton:

Modifica il nome e le proprietà di questo controllo (utilizzando la proprietà Caption che contiene il testo) per ottenere il seguente risultato:

Ora, quando inseriamo il numero e facciamo clic su OK, non succede nulla.

Per creare un'azione, aggiungeremo un evento che scriverà il valore inserito dalla casella di testo alla cella A1 e chiuderà il modulo.

È possibile accedere alle opzioni mostrate di seguito facendo doppio clic sul controllo:

Questo elenco a discesa contiene vari controlli e questo modulo.

Seleziona il pulsante (Button) e l'evento Click:

Private Sub CommandButton_validate_Click()

     Range("A1") = Textbox_number.Value
     'Textbox_number è il nome della casella di testo
     'Value è una proprietà contenente il valore della casella di testo
    
     Unload Me
     'Scarica chiude il modulo (UserForm)
     'Usiamo Me invece del nome del modulo (perché questo codice è nel mezzo di UserForm che vogliamo chiudere)
End Sub

Il valore inserito sarà ora già salvato nella cella A1 prima di chiudere questo modulo (UserForm).

Aggiungi una seconda didascalia (Label) e modifica le seguenti proprietà: Caption, Forecolor (colore: rosso) e Visible (False per nascondere il controllo predefinito):

Ora aggiungiamo un evento che verrà attivato quando il valore nel campo di testo viene modificato dall'utente. L'evento visualizzerà un messaggio di errore se il valore non è numerico.

Private Sub Textbox_number_Change()
     If IsNumeric(Textbox_number.Value) Then 'SE è un valore numerico...
         Label_error.Visible = False 'Il titolo (Label) è nascosto
     Else 'ALTRIMENTI...
         Label_error.Visible = True 'Viene visualizzato il nome
     End If
End Sub

Il valore inserito verrà testato ogni volta che viene inserito il carattere successivo.

Dobbiamo ancora aggiungere la verifica (convalida) dei valori inseriti nel modulo. Mostreremo un messaggio se il valore non è un numero:

Private Sub CommandButton_validate_Click()
     If IsNumeric(Textbox_number.Value) Then 'SE è un valore numerico...
         Range("A1") = Textbox_number.Value 'Copia in A1
         Unload Me 'Sto chiudendo
     Else 'ALTRIMENTI...
         MsgBox "Incorrect value" 'valore non valido
     End If
End Sub

Per non lasciare vuoto il lato destro del modulo quando non ci sono messaggi di errore, possiamo ridurne le dimensioni modificando la proprietà Width di questo modulo:

Private Sub Textbox_number_Change()
     If IsNumeric(Textbox_number.Value) Then 'SE è un valore numerico...
         Label_error.Visible = False 'Il titolo (Label) è nascosto
         Me.Width = 156 'Larghezza del modulo
     Else 'ALTRIMENTI...
         Label_error.Visible = True 'Viene visualizzato il nome
         Me.Width = 244 'Larghezza del modulo
     End If
End Sub

Puoi scaricare il file Excel con l'esempio: userform1.xls

Ecco il risultato:

Checkboxes

Ecco un esempio di come utilizzare CheckBox:

Quando la casella di controllo è selezionata/deselezionata, il valore della cella associata può essere modificato utilizzando l'evento Click:

Private Sub CheckBox1_Click() 'Numero 1
     If CheckBox1.Value = True Then 'SE selezionato...
        Range("A2") = "Checked"
     Else 'SE non selezionato...
        Range("A2") = "Unchecked"
     End If
End Sub

Private Sub CheckBox2_Click() 'Numero 2
     If CheckBox2.Value = True Then 'SE selezionato...
        Range("B2") = "Checked"
     Else 'SE non selezionato...
        Range("B2") = "Unchecked"
     End If
End Sub

Private Sub CheckBox3_Click() 'Numero 3
     If CheckBox3.Value = True Then 'SE selezionato...
        Range("C2") = "Checked"
     Else 'SE non selezionato...
        Range("C2") = "Unchecked"
     End If
End Sub

In questo esempio, le caselle di controllo sono inizialmente deselezionate quando il modulo viene aperto per la prima volta.

Per selezionare ciascuna casella di controllo quando il valore della cella corrispondente è "Checked" ("Checked"), eseguiremo il controllo sull'attivazione del modulo utilizzando UserForm_Initialize:

Private Sub UserForm_Initialize() 'Se selezionato
     If Range("A2") = "Checked" Then
         CheckBox1.Value = True
     End If
     
     If Range("B2") = "Checked" Then
         CheckBox2.Value = True
     End If
     
     If Range("C2") = "Checked" Then
         CheckBox3.Value = True
     End If
End Sub

Qui puoi vedere un esempio nel file Excel finito: userform2.xls

Pulsanti di opzione (Option Buttons)

Quando si utilizzano i pulsanti di opzione (Option Buttons o, a volte, chiamati anche Radio Buttons), l'utente può selezionare solo un'opzione per "gruppo", a differenza delle caselle di controllo, dove l'utente può selezionare più caselle contemporaneamente.

Per creare un "gruppo", inserire prima Frame e poi OptionButton:

Qui puoi vedere un esempio nel file Excel finito: userform3.xls

Quando si invia il modulo, i dati verranno inseriti nella cella associata al nome della colonna selezionata (column_value) e della riga (row_value).

Per sapere quali opzioni sono state selezionate, potremmo fare lo stesso dell'esempio precedente (con le caselle di controllo), ma utilizzeremo un ciclo per ridurre la dimensione del codice.

Utilizzeremo il ciclo For Each, che è un tipo di ciclo che non abbiamo mai trattato prima. Questo ciclo consente di eseguire istruzioni per ciascun oggetto in un "gruppo di oggetti":

Private Sub CommandButton1_Click()
     Dim column_value As String, row_value As String
     
     'Ciclo per ogni controllo Frame_column
     For Each column_button In Frame_column.Controls
         'Se valore di controllo = Vero (allora se selezionato)...
         If column_button.Value Then
            'La variabile "column_value" assume il valore del testo del pulsante
            column_value = column_button.Caption
         End If
     Next
     
     'Ciclo per un altro blocco
     For Each row_button In Frame_row.Controls
         If row_button.Value Then
             row_value = row_button.Caption
         End If
     Next

     Range(column_value & row_value) = "Cell chosen!"  '"Cella selezionata!"
     
     'Chiudi (Scarica) il modulo (Io)
     Unload Me
End Sub

Il nostro modulo ora inserisce il valore "Cella selezionata!" nella cella selezionata.

Per evitare un errore, dobbiamo verificare se l'utente ha scelto correttamente tra due serie di opzioni.

In questo esempio, quando il modulo non è ancora completo, il pulsante Conferma ("Confirm") sarà disattivato (disabilitato). Non è la soluzione più semplice, ma è un buon esempio del perché le funzioni/procedure sono utili nel mezzo di un modulo (UserForm).

Modifica il testo e la proprietà Enabled per disabilitare il pulsante.

Il risultato sarà il seguente:

Nel codice precedente, abbiamo utilizzato due cicli For Each per ottenere i valori dei pulsanti di opzione (Option Buttons). Ora dobbiamo utilizzare gli stessi valori per il pulsante Conferma ("Confirm") e l'evento Click per le dieci opzioni.

Per fare questo non avremo bisogno di copiare i loop per ogni evento, li chiameremo tramite una funzione.

Partendo dal codice precedente e modificandolo, otterremo questo risultato:

 Private Function column_value()
 'Funzione che restituisce un valore di testo per il pulsante selezionato (column_value)
     For Each column_button In Frame_column.Controls
         If column_button.Value Then
             column_value = column_button.Caption
         End If
     Next
 End Function

 Private Function row_value()
 'Una funzione che restituisce un valore di testo per il pulsante selezionato (row_value)
     For Each row_button In Frame_row.Controls
         If row_button.Value Then
             row_value = row_button.Caption
         End If
     Next
 End Function

 Private Sub CommandButton1_Click() 'Azione che si verifica quando si fa clic su ("Conferma la selezione")
     Range(column_value & row_value) = "Cell chosen!"  '"Cella selezionata!"
     'column_value e row_value sono i valori restituiti da queste funzioni
     Unload Me
 End Sub

Non ci resta che creare una procedura che controlli se i pulsanti di opzione sono stati selezionati correttamente (chiamando due funzioni) e che attivi quel pulsante quando necessario.

Anche in questo caso, la validazione avviene con una procedura separata per evitare di copiare il codice 10 volte per ogni evento di ciascun pulsante radio:

Private Sub activate_button()
 'Attivando il pulsante se la condizione è stata testata con successo
     If column_value <> "" And row_value <> "" Then
     'column_value e row_value sono i valori restituiti da queste funzioni
         CommandButton1.Enabled = True
         CommandButton1.Caption = "Confirm your selection"  '"Conferma la tua scelta"
     End If
End Sub

Private Sub OptionButton11_Click()
     activate_button 'Iniziamo la procedura "activate_button".
End Sub
Private Sub OptionButton12_Click()
     activate_button
End Sub
Private Sub OptionButton13_Click()
     activate_button
End Sub
Private Sub OptionButton14_Click()
     activate_button
End Sub
Private Sub OptionButton15_Click()
     activate_button
End Sub
Private Sub OptionButton16_Click()
     activate_button
End Sub
Private Sub OptionButton17_Click()
     activate_button
End Sub
Private Sub OptionButton18_Click()
     activate_button
End Sub
Private Sub OptionButton19_Click()
     activate_button
End Sub
Private Sub OptionButton20_Click()
     activate_button
End Sub

Qui puoi vedere un esempio nel file Excel finito: userform3b.xls