Introduction to Användarformulär
Svep för att visa menyn
UserForms har begränsad eller saknad funktionalitet i Excel för Mac — VBA IDE på Mac saknar fullständigt stöd för UserForm-design i många versioner, vilket kan orsaka just denna typ av oförklarligt beteende.
MsgBox och InputBox täcker enkla ja/nej-frågor och enradiga svar, men när en kund verkligen behöver flera fält samtidigt — ett företagsnamn, en kontaktperson, en stad, en status. Det är vad en UserForm är till för: ett litet anpassat fönster med egna etiketter, textrutor, rullgardinsmenyer och knappar, byggt i VBE och helt styrt av din kod.
Skapa ett formulär
I VBE, högerklicka på ditt projekt i Project Explorer och välj Infoga → UserForm. En tom designyta visas, tillsammans med en flytande verktygslåda med kontroller som du kan dra in på ytan.
Etiketter, TextBoxar, ComboBoxar och Knappar
Varje kontroll du drar in på formuläret får ett standardnamn som TextBox1 eller CommandButton1 — funktionellt, men meningslöst när ett formulär har sex eller sju kontroller. Den viktigaste vanan i detta avsnitt syns i Egenskapsfönstret: byt namn på varje kontroll direkt efter att du lagt till den, med ett kort prefix som identifierar dess typ (txt för TextBox, cbo för ComboBox, cmd för CommandButton, opt för OptionButton, chk för CheckBox, lst för ListBox) följt av ett beskrivande namn. txtCompanyName är tydligt i koden även om tre veckor; TextBox1 är det inte.
Etiketter är vanliga, icke-interaktiva textfält ("Company Name:") — användaren kan se dem men aldrig skriva i eller klicka på dem. TextBoxar är där fri text skrivs in. ComboBoxar visar en rullgardinsmeny med val, vilket är precis vad cboCity och cboStatus används till — att begränsa City och Status till en känd lista istället för att låta användaren skriva fritt "chicago", "Chicago,IL" och "CHI" för samma sak i olika poster.
Skriva kod bakom formuläret
Dubbelklicka på valfri kontroll på designytan för att hoppa direkt till dess kod — VBA skapar automatiskt en händelseprocedur med namnet ControlName_EventName, och kod som skrivs där körs varje gång just den händelsen inträffar för just den kontrollen. En knapp har som standardhändelse 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 är en speciell händelseprocedur som körs automatiskt i samma ögonblick som formuläret laddas — innan användaren ser något — vilket gör det till rätt plats att fylla ComboBoxes med .AddItem istället för att skriva in alternativen manuellt i egenskapsfönstret, särskilt när alternativen kan ändras eller hämtas från ett kalkylblad. Unload Me i cmdCancel_Click stänger formuläret helt; Me syftar alltid på det formulär som koden körs i för tillfället, så denna rad fungerar oförändrat oavsett vad du senare döper om formuläret till.
Genomgångsexempel: Spara en ny kund
Detta är proceduren bakom Spara-knappen — den som faktiskt skriver en ny rad i 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
- Set
tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")når hela vägen från formuläret tillbaka till arbetsboken — ett UserForm är bara ytterligare en koddel, så allt som gäller för ListObjects gäller även här utan ändring; tbl.ListRows.Addlägger till en verkligt ny rad inom tabellens gränser istället för att skriva förbi sista använda cellen manuellt;txtCompanyName.Value,cboCity.Valueoch övriga läser av vad användaren just nu har skrivit eller valt i respektive kontroll —.Valueär gemensamt för nästan alla kontrolltyper, vilket gör att samma mönster fungerar för både TextBox och ComboBox;- Den genererade kund-ID-raden är en förenklad platshållare för denna övning — verklig ID-generering skulle behöva kontrollera luckor eller återanvända ID:n, vilket denna rad inte gör;
- Unload Me i slutet stänger formuläret först efter att raden har skrivits — att stänga tidigare skulle göra
txtCompanyName.Valueoch övriga kontrollvärden oläsbara, eftersom kontrollerna inte längre existerar när formuläret är stängt.
Formulärets "Företagsnamn"-etikett är endast en mer användarvänlig rubrik för tabellens Customer-kolumn — koden skriver txtCompanyName.Value till den kolumnen oavsett etikettens text, eftersom endast TextBoxens namn är relevant för VBA, inte dess visade rubrik.
Customer ID finns inte på formuläret eftersom det genereras automatiskt av koden ("C0" & (tbl.ListRows.Count + 100)) istället för att matas in av användaren — detta speglar hur verkliga system automatiskt numrerar nya poster istället för att förlita sig på att en person väljer ett unikt ID.
Uppgift
- Infoga ett nytt UserForm, namnge det
frmAddCustomer, och lägg till tre TextBoxes (txtCompanyName,txtContact,txtEmail) samt två ComboBoxes (cboCity, cboStatus), var och en med en motsvarande etikett. - Lägg till två CommandButtons,
cmdSaveochcmdCancel, och skriv procedurernaUserForm_InitializeochcmdCancel_Clickexakt som visas. - Skriv
cmdSave_Clickenligt exemplet, och lägg sedan till en tillfällig knapp någon annanstans i arbetsboken med kodenfrmAddCustomer.Showför att testa att öppna formuläret. - Fyll i formuläret för en fiktiv sjätte kund och klicka på Spara — bekräfta att en ny rad läggs till i tblCustomers med de värden du angav.
1. Skapa formuläret
- Infoga → UserForm i VBE, byt sedan namn på den via fönstret Egenskaper i fältet
(Name)tillfrmAddCustomer— inte fältet Caption, som bara ändrar texten i titelraden. - Dra ett par med en etikett (Label) + en textruta (TextBox) för varje av Företagsnamn, Kontaktperson och E-post; ett par med en etikett + en kombinationsruta (ComboBox) för Stad och Status.
- Byt namn på varje kontroll direkt efter att du lagt till den — detta är vanan som kapitlet betonade. Etiketter behöver inte kodvänliga namn eftersom du aldrig refererar till dem i koden, men varje TextBox/ComboBox/Knappar gör det.
2. UserForm_Initialize och cmdCancel_Click
- Dubbelklicka på formulärets tomma bakgrund (inte en kontroll) för att komma till
UserForm_Initialize— dubbelklickar du istället påcmdCancelhamnar du direkt icmdCancel_Click. - Båda procedurerna gavs exakt i kapitlet — skriv in dem oförändrade.
3. Testa med en tillfällig knapp
- Den här knappen behöver inte ligga på formuläret — placera den på valfritt kalkylblad via Utvecklare → Infoga → Knapp (Formulärkontroll), eller kör bara en enradig
Subfrån VBE istället för att lägga till en kalkylbladsknapp alls. frmAddCustomer.Showär hela koden som behövs för att visa formuläret.
4. Testa en fullständig sparning
- Fyll i alla fält och välj värden från båda rullgardinsmenyerna innan du klickar på Spara — ett tomt ComboBox-val skulle skriva en tom cell.
- Kontrollera sedan
tblCustomersför en ny rad med ett ID i stil medC00x.
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
För att testa det, kör detta från valfri vanlig modul (inte UserFormens egen kod):
Sub ShowAddCustomerForm()
frmAddCustomer.Show
End Sub
Tryck på F5 med markören i ShowAddCustomerForm — formuläret ska öppnas, och när du fyller i det och klickar på Spara ska en ny rad läggas till i tblCustomers.
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal