Usare le UserForm in sostituzione di MessageBox o di InputBox

A seguito di una domanda rivoltami, mi pare utile esaminare un utilizzo delle UserForm  al posto delle Finestre di Dialogo. Il motivo è semplice: le UserForm si possono personalizzare a piacere : nella dimensione della stessa, nella posizione in cui appaiono sullo schermo, nel tipo dimensione e colore dei caratteri, nel titolo; si possono inserire immagini come sfondo o come immagine incorniciata. Risultano decisamente più conformabili alle esigenze dell'utente. Per contro, necessitano di un maggior lavoro nella realizzazione del progetto, e diverse righe in più di codice da compilare.

Facciamo un primo esempio, sfruttando una UserForm al posto di una InputBox, usata come introduzione di una password. A volte si ha la necessità di non fare vedere i caratteri che si digitano come password, e con le InputBox non è possibile modificare i caratteri; inseriremo invece una TextBox in una UserForm opportunamente dimensionata, e sfrutteremo la proprietà PasswordChar della TextBox assegnandole il carattere che vorremo, in genere un'asterisco ( * ). L'impostazione di questa proprietà farà si che per ogni carattere digitato appaiano solo asterischi. Ovviamente affideremo i vari controlli ad un pulsante per il controllo della password. Sotto un immagine e relativo esempio di codice inserito nell'evento Click del commandbutton1 "Verifica":

Private Sub CommandButton1_Click()
Dim PASS As String
PASS = "pippo"
If TextBox1 = PASS Then
...istruzioni di cosa fare
Else
MsgBox "PASSWORD ERRATA - RIPROVA"
TextBox1 = ""
TextBox1.SetFocus
End If
End Sub

Vediamo un altro esempio: useremo due userform, una come Finestra di messaggio (msgbox), e l'altra come Finestra di introduzione dati (inputbox). Nell'esempio simuliamo di voler controllare l'inserimento di un determinato dato (la parola ALLOGGIO o la parola UFFICIO) in una cella (C3) e di voler essere avvisati se si inseriscono dati diversi. Una volta introdotto il dato giusto, facciamo apparire una finestra di inserimento dati (la inputbox), che ci chiederà di inserire i Mq del locale.

Una precisazione: per quanto riguarda il controllo inserimento delle parole, il vba è CaseSensitive, cioè è sensibile alle maiuscole o minuscole; dovremo decidere prima di compilare l'istruzione nel codice, se la parola sarà ALLOGGIO, oppure alloggio, o ancora Alloggio, perchè se nella cella preposta la scriveremo diversa da quanto contenuto nel codice, verrà segnalata come errore. Se invece vorremo non preoccuparci di come sarà scritta la parola (maiuscole/minuscole) possiamo inserire nella sezione "Generale - Dichiarazioni" della UserForm l'istruzione :
Option Compare Text. Questa dichiarazione sarà visibile (agirà) solo all'interno di istruzioni poste nel modulo della UserForm.

Vediamo come procedere: intanto dovremo sfruttare un "evento" che attivi il controllo, e useremo il SelectionChange del Foglio di lavoro, il WorkSheet. In questo modo faremo controllare se la cella C3 sarà vuota, o se invece conterrà una parola. Se inseriremo una parola uguale a quella prevista, allora si aprirà la finestra di immissione dati (inputbox), in caso contrario scatterà la finestra di messaggio che ci avviserà che il dato inserito è errato, cancellerà il contenuto della cella C3 e la selezionerà posizionandoci il focus se si premerà il pulsante Annulla, oppure scriverà la parola giusta se selezioneremo una delle due opzioni previste sulla form, e che altro non sono che due "Etichette" (Label) la cui proprietà "Caption" è stata impostata con il giusto termine. Per quanto riguarda invece l'evento che attiverà la comparsa della inputbox, ho usato il Worksheet_Change che controlla se la cella C3 subisce un cambiamento: se resterà vuota o se il dato immesso è diverso da quello previsto (alloggio o ufficio), non succede niente, se invece corrisponderà al termine previsto, si attiverà chiedendoci di immettere i Mq con la conferma sul pulsante OK. Vediamo il codice: questo attiva la comparsa della UserForm1, usata come MsgBox:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Range("C3") = "" Then Exit Sub
If Range("C3") = "ALLOGGIO" Or Range("C3") = "UFFICIO" Then
Exit Sub
Else
UserForm1.Show
End If

End Sub

e questa è l'immagine della nostra UserForm1

Nota: le due Label "ALLOGGIO" e "UFFICIO", si presentano rilevate, come un pulsante, perchè si è agito sulla proprietà "SpecialEffect" delle label impostandole a "fmSpecialEffectRaised". Sono possibili altri effetti.
Questo invece è il codice contenuto nella UserForm1: nell'evento "Activate" della userform inseriamo le istruzioni per il posizionamento della form sul foglio di lavoro: Top (dall'alto) e Left (da sinistra) con i valori espressi in punti. Poi sfruttiamo la proprietà Caption della Label1 dicendogli (via codice) il testo che apparirà nella label stessa. Le altre istruzioni sfruttano l'evento Click del commandbutton1 e delle Label per l'esecuzione delle stesse:

Private Sub UserForm_Activate()
Top = 120
Left = 165
Label1.Caption = "ATTENZIONE ! il dato immesso NON è valido. Inserire solo:"
End Sub

'sotto: Pulisce la cella C3, la seleziona, e chiude la form

Private Sub CommandButton1_Click()
Range("C3") = ""
Range("C3").Select
End
End Sub
'sotto: copia nella cella C3 la parola ALLOGGIO, poi chiude la form
Private Sub Label2_Click()
Range("C3") = "ALLOGGIO"
End
End Sub
'sotto: copia nella cella C3 la parola UFFICIO, poi chiude la form
Private Sub Label3_Click()
Range("C3") = "UFFICIO"
End
End Sub

Ora vediamo il codice per l'attivazione della UserForm2, usata come finestra di introduzione dati (inputbox).

Private Sub Worksheet_Change(ByVal Target As Range)
If Range("C3") = "" Then Exit Sub
If Range("C3") = "ALLOGGIO" Or Range("C3") = "UFFICIO" _
And Range("D3") = "" Then
UserForm2.Show
End If
End Sub

Da notare solo che nella seconda istruzione (If Range....) oltre all'operatore OR (oppure) viene usato anche l'operatore AND ( e ) per creare un'ulteriore condizione di controllo nel ciclo If....Then.....End If . Se la cella C3 è uguale ad ALLOGGIO oppure a UFFICIO, e la cella D3 è vuota, allora mi fai apparire la UserForm2, in caso contrario non si attiva. Un'altra nota da segnalare per i meno esperti è questa: quando una istruzione diventa lunga e si deve andare a capo, per far capire al codice che la nuova riga è la prosecuzione della precedente, si usa inserire dopo l'ultima lettera della riga stessa, uno spazio seguito dalla barretta grande _ come nell'esempio = "UFFICIO" _  E questa è l'immagine della UserForm2

Da segnalare che in questa userform il testo che vediamo nella Label1, anzichè "caricarlo" all'attivazione della form stessa, è stato inserito direttamente nella finestra delle proprietà della Lavbel1, come nella foto sotto

E questo è il codice contenuto nella UserForm2

'questa istruzione pone le coordinate per la posizione della form sul foglio

Private Sub UserForm_Activate()
Top = 120
Left = 165
End Sub

'questa istruzione copia il valore immesso nella TextBox1 dentro la cella D3

Private Sub CommandButton1_Click()
Range("D3").Value = TextBox1.Value
End
End Sub

'è possibile modificare l'istruzione sopra perchè esegua un controllo che la TextBox1 non 'sia vuota

Private Sub CommandButton1_Click()

If  TextBox1 = "" then Exit Sub 'se la textbox è vuota, esce dalla routine
Range("D3").Value = TextBox1.Value
End
End Sub

'oppure avvisare con un messaggio

Private Sub CommandButton1_Click()
If TextBox1 = "" Then
MsgBox "Inserire i Mq."
TextBox1.SetFocus
Exit Sub
End If
Range("D3").Value = TextBox1.Value
End
End Sub

 

File con l'esempio, scaricabile e consultabile:  Form-Box2000.zip   31 Kb