Usare le UserForm.

Abbiamo già visto che Excel consente di inserire degli "Oggetti" nei nostri fogli di lavoro allo scopo di migliorare la gestione delle nostre applicazioni. Un "oggetto" che ci può aiutare parecchio è la USERFORM, cioè una finestra che si apre, su comando, e che ci consente di immettere nuovi dati, o di vedere, modificare dati già inseriti; oltre alla praticità di un simile accorgimento, daremo anche un aspetto un pò più "professionale" ai nostri lavori. Cominciamo quindi a vedere "come" inserire una "userform". Dovremo aprire l' "Editor di Visual basic", e dal menù "inserisci" selezionare "Userform", vedi immagine sotto

una volta confermato con un click, apparirà, nella finestrina "progetto", l'icona della cartella "Form", e nella zona "codice" sulla destra, la nostra userform1 con relativa "casella degli strumenti", cioè gli "oggetti" che a loro volta potranno essere inseriti nella form stessa, vedi immagine sotto

Ricordo, che ogni "oggetto" possiede delle "proprietà" , visibili nella finestra inferiore, posta a sinistra, sotto la finestra "progetto", e che sono modificabili nelle impostazioni: la proprietà "caption", che di default è impostata a "Userform1",  è la proprietà che consente di modificare il nome che vedremo nella barra del form, e che potremo modificare, per esempio in "Inserimento Dati", semplicemente sostituendo la nuova frase a "Userform1". Vedi immagini sotto

E questo sarà l'effetto della modifica fatta:

Rimando tutti i "pellegrini" come me, alla guida in linea, per scoprire il significato delle varie "proprietà" legate ad ogni oggetto. Ogni "oggetto" possiede le proprie "proprietà" e non necessariamente sono le stesse degli altri oggetti.

Proseguendo nelle spiegazioni, faremo un esempio: realizzeremo una "Maschera di introduzione dati", cioè inseriremo nella form gli strumenti necessari alla raccolta dei dati, e saranno le textbox, e i pulsanti necessari ad avviare le debite istruzioni, tipo un pulsante "Registra" ed un pulsante "Esci". Cominciamo ad inserire le Textbox : dalla "casella degli strumenti" inseribili nella form, selezioniamo l'icona della "Casella di Testo", in inglese "textbox", e spostandoci poi sulla form, clicchiamo su un punto e trasciniamo: appare un'area tratteggiata che corrisponde alla dimensione che assumerà la textbox stessa:

rilasciando il pulsante del mouse vedremo la textbox disegnarsi, ancora col bordo tratteggiato, in attesa di eventuali ridimensionamenti, da effettuarsi trascinando i quadratini che la circondano. Contemporaneamente, nella finestra delle proprietà appariranno le proprietà della textbox, compreso il nome, che sarà TextBox1. Ogni altra textbox che verrà inserita sarà nominata col numero in sequenza (textbox2, 3, ecc), questo per identificare in maniera univoca ogni oggetto inserito.

Nelle caselle di testo, con la form in funzione, dovremo inserire i nostri dati, come se fossero delle celle di un foglio di lavoro. Questi stessi dati saranno poi trasferiti in zone opportune del nostro foglio di lavoro, quando premeremo il pulsante "Registra". Per identificare che tipo di dati vogliamo inserire in una textbox, useremo una "Etichetta" (in inglese Label) che posizioneremo vicino alla textbox, e inseriremo nella proprietà "Caption" dell'etichetta, l'identificativo di ciò che dovrà essere inserito nella textbox. SE la textbox dovrà corrispondere ad un nome di un elenco, nella caption dell'etichetta scriveremo "Nominativo". Per inserire l'etichetta nella form, useremo lo stesso procedimento usato per la textbox (l'icona dell' etichetta è la prima a sinistra rispetto a quella textbox). Questo è l'effetto che otterremo:

Nell'esempio che stiamo preparando, utilizzeremo solo 5 campi, giusto per imparare a lavorare, quindi, oltre al nome, inseriremo un indirizzo , la città,  una data di nascita ed un campo "appunti". Quando avremo di inserire le 5 textbox che accoglieranno i dati, e le relative etichette per indicare i campi, avremo una form che si presenterà così:

Come vedete sono stati inseriti tutti i campi previsti, le relative etichette, e due pulsanti che serviranno per registrare i dati, oppure annullare ed uscire. Un unica cosa da segnalare: la textbox5, quella che ospiterà i dati relativi ad "Appunti", visto che potrà contenere anche informazioni contenenti molte parole, ha dovuto essere modificata in due "proprietà" che consentono di accettare testi lunghi : la proprietà "Multiline" è stata impostata a True, (di default è False) il che consentirà di poter disporre di più righe dove scrivere, e la proprietà "ScrollBars" (di default è None) è stata impostata su "fmScrollBarsVertical", che consente di far apparire una barra di scorrimento verticale se il testo inserito supera il numero di righe dato dall'attuale altezza della textbox5. A questo punto prendiamo in esame il codice necessario a far funzionare la nostra applicazione.

Avremo bisogno di un comando per far apparire la nostra userform, e per questo useremo un pulsante che metteremo sul foglio dove intendiamo far apparire la nostra "maschera di introduzione dati". Prenderemo un "CommandButton" dalla "Casella degli strumenti" del foglio di lavoro, e nell'evento Click del commandButton inseriremo la seguente istruzione:

Private Sub CommandButton1_Click()
UserForm1.Show
End Sub

Questa istruzione farà aprire la form sul nostro foglio di lavoro. Inseriremo i dati previsti e quindi premeremo il pulsante "Registra dati". Le istruzioni di ciò che vogliamo sia fatto andranno posizionate nell'evento Click di questo pulsante (anche questo, essendo il primo commandbutton inserito nella form, si chiamerà CommandButton1). In precedenza, avremmo dovuto decidere in quale foglio, e in quali celle, vorremo creare il nostro archivio. Supponiamo quindi di usare lo stesso foglio1, e di usare le celle che vanno da A3 a E3 (5 campi).Le istruzioni sarebbero queste:

Private Sub CommandButton1_Click()
Worksheets("Foglio1").Range("A3") = TextBox1.Text
Worksheets("Foglio1").Range("B3") = TextBox2.Text
Worksheets("Foglio1").Range("C3") = TextBox3.Text
Worksheets("Foglio1").Range("D3") = TextBox4.Text
Worksheets("Foglio1").Range("E3") = TextBox5.Text
End Sub

Poichè quando si fa eseguire un comando, è preferibile far eseguire dei controlli per verificare che uno o tutti i dati siano inseriti in maniera giusta, inseriremo una verifica sul campo "Nominativo": se ci scorderemo di inserire questo dato, l'esecuzione delle istruzioni verrà interrotta. In questo modo eviteremo di registrare dei dati "incompleti". Questa sarà la giusta impostazione delle istruzioni:

Private Sub CommandButton1_Click()

If  TextBox1 = "" Then  'controlla che il textbox1 non sia vuoto, se è vuoto allora
MsgBox "Bisogna inserire il Nominativo"  
'avvisa con un messaggio
TextBox1.SetFocus 
'posiziona il focus sul textbox1
Exit Sub   
'ed esce dalla routine senza completare il resto delle istruz.
End If
Worksheets("Foglio1").Range("A3") = TextBox1.Text
Worksheets("Foglio1").Range("B3") = TextBox2.Text
Worksheets("Foglio1").Range("C3") = TextBox3.Text
Worksheets("Foglio1").Range("D3") = TextBox4.Text
Worksheets("Foglio1").Range("E3") = TextBox5.Text
End Sub

Ma la nostra istruzione non è completa: compilata così funziona, ma ogni volta che registreremo nuovi dati, questi prenderanno il posto di quelli precedenti già inseriti, ed allora addio al nostro archivio: Sostituiremo dati esistenti con quelli nuovi, il che non va bene. Dobbiamo munire l'istruzione di un comando che cerchi, nella zona destinata all'archivio, una riga vuota, e lì, scarichi i nuovi dati. E' possibile seguire diverse procedure, noi ne sceglieremo una sola,  basata sulla proprietà End Select e sullo "Scarto" (Offset) (IMPORTANTE!!: per capire il funzionamento di End Select vi rimando in questa sezione, al paragrafo "Copia/Incolla 2") e le nostre istruzioni saranno:

Private Sub CommandButton1_Click()
If TextBox1 = "" Then
MsgBox "Bisogna inserire il Nominativo"
TextBox1.SetFocus
Exit Sub
End If
Sheets("Foglio1").Select
Range("A1").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
ActiveCell = TextBox1.Text
ActiveCell.Offset(0, 1) = TextBox2.Text
ActiveCell.Offset(0, 2) = TextBox3.Text
ActiveCell.Offset(0, 3) = TextBox4.Text
ActiveCell.Offset(0, 4) = TextBox5.Text

End Sub

Con la routine sopra  avremo i nostri dati inseriti sempre in nuove righe. Un altro sistema per reperire la prima cella vuota in un elenco, è quella di usare il ciclo While...Wend; al ciclo facciamo cercare, impostando una riga di inizio in una determinata colonna, una cella diversa da vuota, quindi occupata da dati; usiamo un incrementatore di numero riga in modo che fino a che si verifica la condizione posta, si proceda alla riga successiva; quando verrà trovata una cella vuota, il ciclo si esaurisce e quella sarà la prima riga vuota trovata in un elenco di dati.

Private Sub CommandButton1_Click()
If TextBox1 = "" Then
MsgBox "Bisogna inserire il Nominativo"
TextBox1.SetFocus
Exit Sub
End If
Sheets("Foglio1").Select
Riga = 3
'si imposta il numero di una riga iniziale
While Cells(Riga, 1) <> "" 
'fino a che la cella, numero Riga, colonna 1 (la A) è diversa da vuota, quindi occupata
Riga = Riga + 1  
' si incrementa di una unità il numero di Riga
Wend                
 'e si continua fino a che non si verifica una condizione diversa da vuota
Cells(Riga, 1) =  TextBox1.Text
 'trovata la cella libera, si rende la stessa uguale alla textbox1. e a seguire, si incrementa la colonna, stessa Riga, per ogni
'TextBox

Cells(Riga, 2) = TextBox2.Text
Cells(Riga, 3) = TextBox3.Text
Cells(Riga, 4) = TextBox4.Text
Cells(Riga, 5) = TextBox5.Text

End Sub

Teniamo ora presente che i dati che avremo inserito nelle TextBox della UserForm, vengono genericamente visti come testo, e per evitare che nel trasferimento dei dati alle celle del foglio, Excel non identifichi il "Formato" dei dati, inteso come "Tipo di dati" (cioè numero, data, ora, testo, ecc) è opportuno usare o il dimensionamento (Dim) dei dati raccolti o più velocemente usare la "Funzione di conversione del tipo di dati" che ha il preciso compito di definire di che tipo di dato si tratta. Leggere in questa sezione l'articolo "Conversione Tipi di Dati". Quindi l'istruzione che invierà la data al foglio, diventa ad esempio:
Cells(Riga, 4) = CDate(TextBox4)

Questa invece è l'istruzione che inseriremo nell'evento Click del secondo pulsante,  che ci consente di chiudere la form e scaricarla dalla memoria:

Private Sub CommandButton2_Click()
Unload Me
Set UserForm1 = Nothing
End Sub

Non è ancora finita: alla conversione del tipo di dati provvederemo con le funzioni appropriate, ma per quanto riguarda l'aspetto che i dati potranno avere nelle TextBox, potremo usare la funzione Format, che ha il compito di impostare il formato visivo con il quale ci apparirà il dato inserito. Questa istruzione la posizioneremo in un evento che sia antecedente all'esecuzione della registrazione: useremo quindi l'evento "AfterUpdate" della textbox4 (quella che porterà la data di nascita), e questa può essere l'istruzione, se vorremo "vedere" una data con i trattini come separatori :

Private Sub TextBox4_AfterUpdate()
TextBox4 = Format(TextBox4, "dd-mm-yy")
End Sub

Se vorremo che il formato visivo scelto venga trasferito al foglio così visualizzato, useremo nell'istruzione la proprietà NumberFormat dell'oggetto Range (da non confondere con la Funzione FormatNumber).
Cells(Riga, 4) = CDate(TextBox4)
Cells(Riga, 4).NumberFormat = "dd-mm-yy"

 

Ulteriori informazioni potrete leggerle nell'articolo "Variabili e Tipi di dati" presente sul nuovo sito, sezione "Articoli vba".