Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Introduction to Användarformulär | Användarinteraktion
Excel VBA för affärsautomatisering

Introduction to Användarformulär

Svep för att visa menyn

Note
Obs

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.

Figur 5.3

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.

Formulärskapandeflöde

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
Genomgång rad för rad
expand arrow
  • 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.Add lä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.Value och ö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.Value och övriga kontrollvärden oläsbara, eftersom kontrollerna inte längre existerar när formuläret är stängt.
Note
Notering

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.

Note
Notering

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

  1. 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.
  2. Lägg till två CommandButtons, cmdSave och cmdCancel, och skriv procedurerna UserForm_Initialize och cmdCancel_Click exakt som visas.
  3. Skriv cmdSave_Click enligt exemplet, och lägg sedan till en tillfällig knapp någon annanstans i arbetsboken med koden frmAddCustomer.Show för att testa att öppna formuläret.
  4. 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.
Tips
expand arrow

1. Skapa formuläret

  • Infoga → UserForm i VBE, byt sedan namn på den via fönstret Egenskaper i fältet (Name) till frmAddCustomer — 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å cmdCancel hamnar du direkt i cmdCancel_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 Sub frå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 tblCustomers för en ny rad med ett ID i stil med C00x.
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

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.

Testa formuläret
Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 5. Kapitel 2

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Avsnitt 5. Kapitel 2
some-alt