Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Introduction to Brugerformularer | Brugerinteraktion
Excel VBA til Forretningsautomatisering

Introduction to Brugerformularer

Stryg for at vise menuen

Note
Bemærk

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.

Figur 5.3

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.

Formularoprettelsesflow

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
Gennemgang linje for linje
expand arrow
  • 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.Add tilfø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.Value og de øvrige læser det, brugeren aktuelt har indtastet eller valgt i den specifikke kontrol — .Value er 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.Value og de andre kontrolværdier ulæselige, da kontrollerne ikke længere eksisterer, når formularen er lukket.
Note
Bemærk

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.

Note
Bemærk

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

  1. 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.
  2. Tilføj to CommandButtons, cmdSave og cmdCancel, og skriv procedurerne UserForm_Initialize og cmdCancel_Click nøjagtigt som vist.
  3. Skriv cmdSave_Click som vist, og tilføj derefter en midlertidig knap et andet sted i projektmappen med koden frmAddCustomer.Show for at teste åbningen af din formular.
  4. 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.
Tip
expand arrow

1. Oprettelse af formularen

  • Indsæt → UserForm i VBE, og omdøb den derefter via egenskabsvinduets (Name)-felt til frmAddCustomer — 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å cmdCancel i stedet springer direkte til cmdCancel_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 Sub fra VBE i stedet for at tilføje en regnearksknap.
  • frmAddCustomer.Show er 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 tblCustomers bagefter for en ny række med et C00x-stil ID.
Løsning
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

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.

Test af formularen
Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 5. Kapitel 2

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

Sektion 5. Kapitel 2
some-alt