Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Introduzione ai UserForm | Interazione con l'Utente
Excel VBA per l'Automazione Aziendale

Introduzione ai UserForm

Scorri per mostrare il menu

Note
Nota

Le UserForm hanno funzionalità limitate o assenti in Excel per Mac — l'IDE VBA su Mac non offre un supporto completo per la progettazione dei UserForm in molte versioni, il che può causare proprio questo tipo di comportamento inspiegabile.

MsgBox e InputBox coprono domande semplici sì/no e risposte su una sola riga, ma aggiungere un cliente richiede davvero diversi campi contemporaneamente — un nome azienda, un contatto, una città, uno stato. Questo è lo scopo di un UserForm: una piccola finestra personalizzata con proprie etichette, caselle di testo, menu a discesa e pulsanti, creata all'interno del VBE e controllata interamente dal tuo codice.

Creazione di un modulo

Nel VBE, fai clic con il tasto destro sul tuo progetto in Esplora progetti e scegli Inserisci → UserForm. Apparirà una superficie di progettazione vuota, insieme a una Toolbox mobile di controlli che puoi trascinare su di essa.

Figura 5.3

Etichette, Caselle di Testo, Caselle Combinata e Pulsanti

Ogni controllo che trascini sul form riceve un nome predefinito come TextBox1 o CommandButton1 — funzionale, ma privo di significato quando un form contiene sei o sette controlli. L'abitudine più importante in questa sezione è visibile nella finestra Proprietà: rinominare ogni controllo immediatamente dopo averlo aggiunto, utilizzando un prefisso breve che ne identifichi il tipo (txt per TextBox, cbo per ComboBox, cmd per CommandButton, opt per OptionButton, chk per CheckBox, lst per ListBox) seguito da un nome descrittivo. txtCompanyName è chiaro e inequivocabile nel codice anche dopo tre settimane; TextBox1 non lo è.

Le etichette sono semplici didascalie di testo non interattive ("Company Name:") — l'utente può vederle ma non può scriverci o cliccarle. Le caselle di testo sono dove viene digitato il testo libero. Le caselle combinata presentano un menu a discesa di scelte, che è esattamente ciò per cui vengono utilizzate cboCity e cboStatus — limitare City e Status a un elenco noto invece di permettere all'utente di scrivere liberamente "chicago", "Chicago,IL" e "CHI" per la stessa cosa in record diversi.

Flusso di creazione del modulo

Scrittura del codice dietro il modulo

Fare doppio clic su qualsiasi controllo nell'area di progettazione per accedere direttamente al suo codice — VBA crea automaticamente una procedura evento chiamata ControlName_EventName, e scrivere codice al suo interno significa che quel codice verrà eseguito ogni volta che si verifica quello specifico evento su quello specifico controllo. L'evento predefinito di un pulsante è Click:

Private Sub UserForm_Initialize()
    ' runs once, automatically, when the form is first shown
    cboCity.AddItem "Chicago"
    cboCity.AddItem "Boston"
    cboCity.AddItem "Austin"
    cboCity.AddItem "Seattle"
    cboCity.AddItem "Denver"
 
    cboStatus.AddItem "Active"
    cboStatus.AddItem "Inactive"
    cboStatus.AddItem "Prospect"
End Sub
 
Private Sub cmdCancel_Click()
    Unload Me
End Sub

UserForm_Initialize è una procedura evento speciale che viene eseguita automaticamente nel momento in cui il modulo viene caricato — prima che l'utente veda qualsiasi cosa — il che la rende il posto giusto per popolare le ComboBox con .AddItem invece di inserire manualmente le scelte nella finestra delle proprietà, soprattutto quando queste scelte potrebbero cambiare o provenire da un foglio di lavoro. Unload Me all'interno di cmdCancel_Click chiude completamente il modulo; Me si riferisce sempre al modulo in cui il codice è attualmente in esecuzione, quindi questa riga funziona senza modifiche indipendentemente dal nome che verrà assegnato successivamente al modulo stesso.

Esempio pratico: salvataggio di un nuovo cliente

Questa è la procedura dietro il pulsante Salva — quella che effettivamente scrive una nuova riga in tblCustomers:

Private Sub cmdSave_Click()
    Dim tbl As ListObject
    Dim newRow As ListRow
 
    Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
    Set newRow = tbl.ListRows.Add
 
    newRow.Range(1, 1).Value = "C" & Format(tbl.ListRows.Count + 1, "000")
    newRow.Range(1, 2).Value = txtCompanyName.Value
    newRow.Range(1, 3).Value = txtContact.Value
    newRow.Range(1, 4).Value = txtEmail.Value
    newRow.Range(1, 5).Value = cboCity.Value
    newRow.Range(1, 6).Value = cboStatus.Value
 
    MsgBox txtCompanyName.Value & " was added successfully."
    Unload Me
End Sub
Analisi riga per riga
expand arrow
  • L'istruzione tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers") collega il modulo direttamente alla cartella di lavoro — un UserForm è semplicemente un altro pezzo di codice, quindi tutto ciò che riguarda i ListObjects si applica senza modifiche;
  • tbl.ListRows.Add aggiunge effettivamente una nuova riga all'interno dei confini della Tabella invece di scrivere manualmente oltre l'ultima cella utilizzata;
  • txtCompanyName.Value, cboCity.Value e gli altri leggono ciò che l'utente ha attualmente digitato o selezionato in quel controllo specifico — .Value è comune a quasi tutti i tipi di controllo, motivo per cui lo stesso schema funziona sia per TextBox che per ComboBox;
  • La riga che genera il Customer ID è un semplice segnaposto per questo esercizio — una generazione reale degli ID dovrebbe controllare eventuali lacune o ID riutilizzati, cosa che questa riga non fa;
  • Unload Me alla fine chiude il modulo solo dopo che la riga è stata scritta — chiuderlo prima renderebbe txtCompanyName.Value e gli altri valori dei controlli illeggibili, poiché i controlli non esistono più una volta che il modulo è stato chiuso.
Note
Nota

L'etichetta "Company Name" del modulo è semplicemente una didascalia più amichevole per la colonna Customer della tabella — il codice scrive txtCompanyName.Value in quella colonna indipendentemente dal testo dell'etichetta, poiché solo il nome della TextBox è rilevante per VBA, non la didascalia visualizzata.

Note
Nota

Customer ID non è presente nel modulo perché viene generato automaticamente dal codice ("C0" & (tbl.ListRows.Count + 100)) invece di essere inserito dall'utente — questo rispecchia il modo in cui i sistemi reali numerano automaticamente i nuovi record invece di affidarsi a una persona per scegliere un ID univoco.

Attività

  1. Inserire un nuovo UserForm, nominarlo frmAddCustomer e aggiungere tre TextBox (txtCompanyName, txtContact, txtEmail) e due ComboBox (cboCity, cboStatus), ciascuno con una Label corrispondente.
  2. Aggiungere due CommandButton, cmdSave e cmdCancel, e scrivere le procedure UserForm_Initialize e cmdCancel_Click esattamente come mostrato.
  3. Scrivere cmdSave_Click come mostrato, quindi aggiungere un pulsante temporaneo altrove nella cartella di lavoro con il codice frmAddCustomer.Show per testare l'apertura del modulo.
  4. Compilare il modulo per un sesto cliente fittizio e fare clic su Salva — confermare che una nuova riga appare in tblCustomers con i valori inseriti.
Suggerimento
expand arrow

1. Creazione del modulo

  • Inserisci → UserForm nell'editor VBE, quindi rinominalo tramite il campo (Name) nella finestra Proprietà in frmAddCustomer — non il campo Caption, che cambia solo il testo della barra del titolo.
  • Trascina una coppia Etichetta + Casella di testo per ciascuno di Nome Azienda, Contatto ed Email; una coppia Etichetta + Casella combinata per Città e Stato.
  • Rinomina ogni controllo subito dopo averlo aggiunto — questa è l'abitudine sottolineata nel capitolo. Le etichette non necessitano di nomi adatti al codice poiché non vengono mai richiamate nel codice, ma ogni Casella di testo/Casella combinata/Pulsante sì.

2. UserForm_Initialize e cmdCancel_Click

  • Fai doppio clic sullo sfondo vuoto del modulo (non su un controllo) per accedere a UserForm_Initialize — facendo doppio clic su cmdCancel invece si accede direttamente a cmdCancel_Click.
  • Entrambe le procedure sono state fornite esattamente nel capitolo — trascrivile senza modifiche.

3. Test con un pulsante temporaneo

  • Questo pulsante non deve essere presente sul modulo — posizionalo su qualsiasi foglio tramite Sviluppatore → Inserisci → Pulsante (Controllo modulo), oppure esegui semplicemente una Sub di una riga dal VBE invece di aggiungere un pulsante al foglio.
  • frmAddCustomer.Show è l'unico codice necessario per visualizzare il modulo.

4. Test di un salvataggio completo

  • Compila tutti i campi e seleziona i valori da entrambi i menu a discesa prima di cliccare su Salva — una selezione vuota nella Casella combinata scriverebbe una cella vuota.
  • Controlla tblCustomers successivamente per una nuova riga con un ID in stile C00x.
Soluzione
expand arrow
Private Sub UserForm_Initialize()
    ' runs once, automatically, when the form is first shown
    cboCity.AddItem "Chicago"
    cboCity.AddItem "Boston"
    cboCity.AddItem "Austin"
    cboCity.AddItem "Seattle"
    cboCity.AddItem "Denver"

    cboStatus.AddItem "Active"
    cboStatus.AddItem "Inactive"
    cboStatus.AddItem "Prospect"
End Sub

Private Sub cmdCancel_Click()
    Unload Me
End Sub

Private Sub cmdSave_Click()
    Dim tbl As ListObject
    Dim newRow As ListRow

    Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
    Set newRow = tbl.ListRows.Add

    newRow.Range(1, 1).Value = "C0" & (tbl.ListRows.Count + 100)
    newRow.Range(1, 2).Value = txtCompanyName.Value
    newRow.Range(1, 3).Value = txtContact.Value
    newRow.Range(1, 4).Value = txtEmail.Value
    newRow.Range(1, 5).Value = cboCity.Value
    newRow.Range(1, 6).Value = cboStatus.Value

    MsgBox txtCompanyName.Value & " was added successfully."
    Unload Me
End Sub

Per testarlo, esegui questo da un modulo standard (non dal codice dello UserForm):

Sub ShowAddCustomerForm()
    frmAddCustomer.Show
End Sub

Premi F5 con il cursore all'interno di ShowAddCustomerForm — il modulo dovrebbe aprirsi, e compilando i campi e cliccando Salva dovrebbe aggiungere una nuova riga a tblCustomers.

Test del modulo
Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 5. Capitolo 2

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

Sezione 5. Capitolo 2
some-alt