Introduzione ai UserForm
Scorri per mostrare il menu
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.
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.
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
- 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.Addaggiunge effettivamente una nuova riga all'interno dei confini della Tabella invece di scrivere manualmente oltre l'ultima cella utilizzata;txtCompanyName.Value,cboCity.Valuee 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.Valuee gli altri valori dei controlli illeggibili, poiché i controlli non esistono più una volta che il modulo è stato chiuso.
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.
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à
- Inserire un nuovo UserForm, nominarlo
frmAddCustomere aggiungere tre TextBox (txtCompanyName,txtContact,txtEmail) e due ComboBox (cboCity, cboStatus), ciascuno con una Label corrispondente. - Aggiungere due CommandButton,
cmdSaveecmdCancel, e scrivere le procedureUserForm_InitializeecmdCancel_Clickesattamente come mostrato. - Scrivere
cmdSave_Clickcome mostrato, quindi aggiungere un pulsante temporaneo altrove nella cartella di lavoro con il codicefrmAddCustomer.Showper testare l'apertura del modulo. - 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.
1. Creazione del modulo
- Inserisci → UserForm nell'editor VBE, quindi rinominalo tramite il campo
(Name)nella finestra Proprietà infrmAddCustomer— 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 sucmdCancelinvece si accede direttamente acmdCancel_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
Subdi 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
tblCustomerssuccessivamente per una nuova riga con un ID in stileC00x.
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.
Grazie per i tuoi commenti!
Chieda ad AI
Chieda ad AI
Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione