Introduction to Brugerformularer
Stryg for at vise menuen
UserForms har begrænset eller ingen funktionalitet i Excel til Mac — VBA IDE'en på Mac mangler fuld understøttelse af UserForm-design i mange versioner, hvilket kan forårsage netop denne slags uforklarlig adfærd.
MsgBox og InputBox dækker simple ja/nej-spørgsmål og énliniersvar, men når en kunde skal tilføjes, kræves der ofte flere felter på én gang — firmanavn, kontaktperson, by, status. Det er formålet med en UserForm: et lille brugerdefineret vindue med egne etiketter, tekstfelter, dropdowns og knapper, oprettet i VBE og fuldt styret af din kode.
Oprettelse af en formular
I VBE skal du højreklikke på dit projekt i Project Explorer og vælge Indsæt → UserForm. En tom designflade vises sammen med en flydende værktøjskasse med kontroller, du kan trække over på formularen.
Labels, TextBoxes, ComboBoxes og Knapper
Hver kontrol, du trækker ind på formularen, får et standardnavn som TextBox1 eller CommandButton1 — funktionelt, men meningsløst, når en formular har seks eller syv kontroller på sig. Den vigtigste vane i dette afsnit ses i Egenskabsvinduet: omdøb hver kontrol umiddelbart efter, du har tilføjet den, ved at bruge et kort præfiks, der identificerer typen (txt for TextBox, cbo for ComboBox, cmd for CommandButton, opt for OptionButton, chk for CheckBox, lst for ListBox) efterfulgt af et beskrivende navn. txtCompanyName er entydigt i koden om tre uger; TextBox1 er det ikke.
Labels er de enkle, ikke-interaktive tekstetiketter ("Company Name:") — brugeren kan se dem, men kan aldrig skrive i dem eller klikke på dem. TextBoxes er felter, hvor der kan indtastes fri tekst. ComboBoxes viser en dropdown med valgmuligheder, hvilket præcis er formålet med cboCity og cboStatus — at begrænse City og Status til en kendt liste i stedet for at lade brugeren frit indtaste "chicago", "Chicago,IL" og "CHI" for det samme på tværs af forskellige poster.
Kode bag formularen
Dobbeltklik på en hvilken som helst kontrol på designfladen for at gå direkte til dens kode — VBA opretter automatisk en hændelsesprocedure med navnet ControlName_EventName, og kode skrevet her vil blive kørt, hver gang den specifikke hændelse sker for den specifikke kontrol. En knaps standardhændelse er 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 er en særlig hændelsesprocedure, der automatisk aktiveres i det øjeblik, formularen indlæses — før brugeren ser noget — hvilket gør det til det rette sted at udfylde ComboBoxes med .AddItem i stedet for manuelt at indtaste valgmuligheder i egenskabsvinduet, især når valgmulighederne kan ændre sig eller komme fra et regneark. Unload Me i cmdCancel_Click lukker formularen helt; Me refererer altid til den formular, koden aktuelt kører i, så denne linje fungerer uændret, uanset hvad du senere omdøber formularen til.
Gennemarbejdet eksempel: Gem en ny kunde
Dette er proceduren bag Gem-knappen — den, der faktisk skriver en ny række ind 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
- Sætningen
tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")går hele vejen fra formularen tilbage til projektmappen — en UserForm er blot et andet stykke kode, så alt om ListObjects gælder uændret; tbl.ListRows.Addtilføjer en reel ny række inden for tabellens grænse i stedet for manuelt at skrive forbi den sidste brugte celle;txtCompanyName.Value,cboCity.Valueog de øvrige læser det, brugeren aktuelt har indtastet eller valgt i den specifikke kontrol —.Valueer fælles for næsten alle kontroltyper, hvilket gør, at samme mønster virker for både TextBoxes og ComboBoxes;- Den genererede Customer ID-linje er en forenklet pladsholder til denne øvelse — rigtig ID-generering ville skulle tjekke for huller eller genbrugte ID'er, hvilket denne linje ikke gør;
- Unload Me til sidst lukker formularen først efter, at rækken er skrevet — at lukke tidligere ville gøre
txtCompanyName.Valueog de andre kontrolværdier ulæselige, da kontrollerne ikke længere eksisterer, når formularen er lukket.
Formularens "Company Name"-etiket er blot en mere brugervenlig betegnelse for tabellens Customer-kolonne — koden skriver txtCompanyName.Value ind i denne kolonne uanset etikettens tekst, da det kun er TextBox-navnet, der betyder noget for VBA, ikke den viste tekst.
Customer ID er ikke på formularen, fordi det automatisk genereres af koden ("C0" & (tbl.ListRows.Count + 100)) i stedet for at blive indtastet af brugeren — dette afspejler, hvordan rigtige systemer automatisk nummererer nye poster i stedet for at lade en person vælge et unikt ID.
Opgave
- Indsæt en ny UserForm, navngiv den
frmAddCustomer, og tilføj tre TextBoxes (txtCompanyName,txtContact,txtEmail) og to ComboBoxes (cboCity, cboStatus), hver med en tilsvarende Label. - Tilføj to CommandButtons,
cmdSaveogcmdCancel, og skriv procedurerneUserForm_InitializeogcmdCancel_Clicknøjagtigt som vist. - Skriv
cmdSave_Clicksom vist, og tilføj derefter en midlertidig knap et andet sted i projektmappen med kodenfrmAddCustomer.Showfor at teste åbningen af din formular. - Udfyld formularen for en fiktiv sjette kunde og klik på Gem — bekræft, at en ny række vises i tblCustomers med de værdier, du har indtastet.
1. Oprettelse af formularen
- Indsæt → UserForm i VBE, og omdøb den derefter via egenskabsvinduets
(Name)-felt tilfrmAddCustomer— ikke Caption-feltet, som kun ændrer tekst i titellinjen. - Træk et Label + et TextBox-par for hver af Firmanavn, Kontaktperson og E-mail; et Label + et ComboBox-par for By og Status.
- Omdøb hver kontrol umiddelbart efter tilføjelse — dette er den vane, kapitlet understregede. Labels behøver ikke kodevenlige navne, da de aldrig refereres i kode, men alle TextBox/ComboBox/Button skal have det.
2. UserForm_Initialize og cmdCancel_Click
- Dobbeltklik på formularens tomme baggrund (ikke en kontrol) for at komme til
UserForm_Initialize— dobbeltklik påcmdCanceli stedet springer direkte tilcmdCancel_Click. - Begge procedurer blev givet præcist i kapitlet — indtast dem uændret.
3. Test med en midlertidig knap
- Denne knap behøver ikke være på formularen — placer den på et hvilket som helst regneark via Udvikler → Indsæt → Knap (Formularstyring), eller kør blot en enkelt linje
Subfra VBE i stedet for at tilføje en regnearksknap. frmAddCustomer.Shower hele koden, der kræves for at vise formularen.
4. Test af en fuld gemning
- Udfyld alle felter og vælg værdier fra begge dropdowns, før du klikker på Gem — et tomt ComboBox-valg vil skrive en tom celle.
- Kontroller
tblCustomersbagefter for en ny række med etC00x-stil ID.
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
For at teste det, kør dette fra et hvilket som helst almindeligt modul (ikke UserFormens egen kode):
Sub ShowAddCustomerForm()
frmAddCustomer.Show
End Sub
Tryk på F5 med markøren inde i ShowAddCustomerForm — formularen bør åbne, og når den udfyldes og der klikkes på Gem, bør en ny række blive tilføjet til tblCustomers.
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat