Werken met Formulierbesturingselementen
Veeg om het menu te tonen
TextBoxes en ComboBoxes dekken het grootste deel van de gegevensinvoer, maar enkele andere besturingselementen geven bepaalde soorten keuzes op een natuurlijkere manier weer — en het correct uitlezen van hun waarden kent een paar valkuilen die je moet kennen voordat je erop vertrouwt.
CheckBoxes
De Value-eigenschap van een CheckBox is een eenvoudige Boolean — True wanneer aangevinkt, False wanneer niet:
If chkWelcomeEmail.Value = True Then
MsgBox "A welcome email would be sent here."
End If
Elke CheckBox op een formulier is volledig onafhankelijk van de andere — het aanvinken van chkWelcomeEmail heeft geen invloed op chkNewsletter, wat precies het gewenste gedrag is wanneer de keuzes niet wederzijds exclusief zijn.
OptionButtons
OptionButtons werken precies andersom: binnen dezelfde groep zorgt het selecteren van één ervoor dat alle andere automatisch worden gedeselecteerd — precies wat de Status-keuzes in de schermafbeelding nodig hebben, aangezien een klant niet tegelijkertijd Actief en Inactief kan zijn. Om te bepalen welke is geselecteerd, controleer je de Value van elk afzonderlijk:
Dim status As String
If optActive.Value = True Then
status = "Active"
ElseIf optInactive.Value = True Then
status = "Inactive"
ElseIf optProspect.Value = True Then
status = "Prospect"
End If
De wederzijdse exclusiviteit is automatisch en volledig door VBA geregeld — je hoeft nooit code te schrijven die de andere twee deselecteert wanneer er één wordt geselecteerd. Groepering is echter belangrijk: OptionButtons sluiten elkaar alleen uit binnen dezelfde container (het formulier zelf, of een Frame-besturingselement dat erop is geplaatst), dus twee aparte groepen OptionButtons op hetzelfde formulier — bijvoorbeeld Status en Prioriteit — moeten in twee verschillende Frames staan, anders behandelt VBA ze als één enkele wederzijds exclusieve groep.
ListBoxes
Een ListBox toont meerdere keuzes tegelijk zonder dat deze geopend hoeft te worden, zoals de lijst met steden in Figuur 5.5. Vul deze op dezelfde manier als een ComboBox, met .AddItem, en lees de selectie uit via .Value of .ListIndex:
Private Sub UserForm_Initialize()
lstCities.AddItem "Chicago"
lstCities.AddItem "Boston"
lstCities.AddItem "Austin"
End Sub
Private Sub cmdAssign_Click()
If lstCities.ListIndex = -1 Then
MsgBox "Please select a city first."
Exit Sub
End If
MsgBox "Assigning to: " & lstCities.Value
End Sub
ListIndex is de positie van het geselecteerde item, beginnend bij 0 voor het eerste item — en belangrijk: het is -1 wanneer er nog niets is geselecteerd, wat de controle is die cmdAssign_Click gebruikt om een gebruiker op te vangen die op de knop klikt zonder eerst een stad te kiezen. .Value geeft direct de geselecteerde tekst, wat meestal nuttiger is dan de numerieke positie die .ListIndex biedt.
Multi-Page Forms
Een MultiPage-besturingselement (de Details / Voorkeuren-tabbladen bovenaan in Figuur 5.5) groepeert gerelateerde besturingselementen op afzonderlijke pagina's van hetzelfde fysieke formulier — handig zodra een formulier te veel velden heeft om comfortabel op één scherm te passen. Elke pagina wordt aangeduid op basis van positie, en alleen de besturingselementen op de momenteel zichtbare pagina zijn relevant voor de gebruiker, hoewel ze allemaal nog steeds bestaan en vanuit code kunnen worden uitgelezen, ongeacht welke pagina zichtbaar is:
Private Sub MultiPage1_Change()
If MultiPage1.Value = 1 Then
MsgBox "Now viewing Preferences"
End If
End Sub
MultiPage1.Value volgt dezelfde 0-gebaseerde telling als ListIndex — de eerste pagina is 0, de tweede (Voorkeuren, in Figuur 5.5) is 1 — en het Change-event wordt automatisch geactiveerd wanneer de gebruiker op een ander tabblad klikt.
Taak
- Voeg een Frame toe met drie OptionButtons (optActive, optInactive, optProspect) aan frmAddCustomer, ter vervanging van de eerdere cboStatus ComboBox, en schrijf het hierboven getoonde If...ElseIf-blok om de selectie uit te lezen.
- Voeg twee onafhankelijke CheckBoxes toe (chkWelcomeEmail, chkNewsletter) en controleer tijdens het testen dat het aanvinken van de ene nooit invloed heeft op de andere.
- Voeg een ListBox toe (lstCities) die wordt gevuld in UserForm_Initialize, en schrijf een controle die een foutmelding geeft als de gebruiker probeert door te gaan zonder iets te selecteren (ListIndex = -1).
- Uitdaging: plaats de velden Bedrijfsnaam, Contactpersoon en E-mail op één MultiPage-pagina genaamd "Details", en de CheckBoxes en OptionButtons op een tweede pagina genaamd "Voorkeuren".
1. Vervangen van cboStatus door een Frame met OptionButtons
- Verwijder eerst
cboStatusen het bijbehorende Label van het formulier — je vervangt deze, niet toevoegen naast de nieuwe controls. - Sleep een Frame-control naar het formulier en sleep vervolgens alle drie de OptionButtons binnen de rand van het Frame — deze insluiting zorgt ervoor dat ze elkaar wederzijds uitsluiten als één groep.
- Hernoem elke OptionButton afzonderlijk in het Eigenschappenvenster; het Frame zelf kan een eenvoudige Caption zoals "Status" behouden, maar heeft geen codevriendelijke naam nodig tenzij je er direct naar wilt verwijzen.
- De selectie uitlezen betekent dat je de
.Valuevan elke OptionButton afzonderlijk controleert metIf...ElseIf— er is geen enkele eigenschap die aangeeft "welke in de groep is geselecteerd". - Omdat
cboStatus.Valueniet meer bestaat, heeftcmdSave_Clicknu eenstatus-variabele nodig die wordt opgebouwd uit de OptionButtons en in plaats daarvan innewRowwordt geschreven.
2. Toevoegen van twee onafhankelijke CheckBoxes
- Deze staan direct op het formulier (niet in het Frame) — CheckBoxes buiten een gedeelde container beïnvloeden elkaar nooit, ongeacht de groepering.
- Om "te bevestigen tijdens het testen", vink je gewoon de ene aan, dan de andere, en controleer je dat geen van beide de eerste uitschakelt.
3. Toevoegen en valideren van een ListBox
- Vul deze op dezelfde manier als
cboCitywerd gevuld — herhaalde.AddItem-aanroepen inUserForm_Initialize. ListIndex = -1betekent specifiek er is nog niets aangeklikt — dat is precies de voorwaarde die je moet controleren voordat je het opslaan toestaat.- Deze controle hoort in hetzelfde validatieblok als de andere verplichte velden, en wordt toegevoegd aan dezelfde
errors-string.
4. MultiPage-uitdaging
- Sleep een MultiPage-control naar het formulier — deze bevat standaard twee pagina's, precies het aantal dat je nodig hebt.
- Hernoem elke pagina via rechtsklik → Pagina Volgorde, of door het paginatabblad zelf te selecteren en het veld Caption in het Eigenschappenvenster te gebruiken (Caption bepaalt de zichtbare tekst op het tabblad; er is ook een apart (Name)-veld als je een pagina in de code wilt aanspreken).
- Bestaande controls naar een pagina verplaatsen betekent dat je ze fysiek naar het zichtbare gebied van die pagina sleept in de ontwerpweergave — codeverwijzingen naar deze controls veranderen niet, omdat de naam van een control niet afhankelijk is van de pagina waarop deze staat.
Private Sub UserForm_Initialize()
cboCity.AddItem "Chicago"
cboCity.AddItem "Boston"
cboCity.AddItem "Austin"
cboCity.AddItem "Seattle"
cboCity.AddItem "Denver"
lstCities.AddItem "Chicago"
lstCities.AddItem "Boston"
lstCities.AddItem "Austin"
lstCities.AddItem "Seattle"
lstCities.AddItem "Denver"
End Sub
Private Sub cmdCancel_Click()
Unload Me
End Sub
Private Sub cmdSave_Click()
Dim tbl As ListObject
Dim newRow As ListRow
Dim errors As String
Dim status As String
' --- Reset field colors ---
txtCompanyName.BackColor = vbWhite
txtContact.BackColor = vbWhite
txtEmail.BackColor = vbWhite
' --- Required field checks ---
If Trim(txtCompanyName.Value) = "" Then
errors = errors & "- Company Name is required" & vbNewLine
txtCompanyName.BackColor = RGB(255, 199, 206)
End If
If Trim(txtContact.Value) = "" Then
errors = errors & "- Contact is required" & vbNewLine
txtContact.BackColor = RGB(255, 199, 206)
End If
If Trim(txtEmail.Value) = "" Then
errors = errors & "- Email is required" & vbNewLine
txtEmail.BackColor = RGB(255, 199, 206)
End If
' --- Status via OptionButtons ---
If optActive.Value = True Then
status = "Active"
ElseIf optInactive.Value = True Then
status = "Inactive"
ElseIf optProspect.Value = True Then
status = "Prospect"
Else
errors = errors & "- Please select a Status" & vbNewLine
End If
' --- ListBox check ---
If lstCities.ListIndex = -1 Then
errors = errors & "- Please select a city from the list" & vbNewLine
End If
If errors <> "" Then
MsgBox "Please fix the following:" & vbNewLine & errors, vbExclamation
Exit Sub
End If
' --- All checks passed — safe to save now ---
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 = status
If chkWelcomeEmail.Value = True Then
MsgBox "A welcome email would be sent to " & txtEmail.Value & "."
End If
MsgBox txtCompanyName.Value & " was added successfully."
Unload Me
End Sub
Testnotities:
- Punt 2 (CheckBoxes) heeft geen aparte validatie — klik gewoon
chkWelcomeEmailenchkNewsletteronafhankelijk en bevestig dat elke schakelaar werkt zonder de ander te beïnvloeden. - Punt 4 (MultiPage) is alleen een lay-outwijziging — er zijn geen codewijzigingen nodig buiten wat hier al staat, omdat elke control zijn eigen naam behoudt, ongeacht op welke pagina deze staat.
- Merk op dat
cboCity.Valuenog steeds wordt gebruikt voor het daadwerkelijke opslaan (newRow.Range(1, 5)), terwijllstCitiespuur bestaat als een aparte, onafhankelijk gevalideerde control volgens de opdracht — de twee zijn niet aan elkaar gekoppeld, tenzij je ervoor kiest dit zelf uit te breiden.
Bedankt voor je feedback!
Vraag AI
Vraag AI
Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.
Werken met Formulierbesturingselementen
TextBoxes en ComboBoxes dekken het grootste deel van de gegevensinvoer, maar enkele andere besturingselementen geven bepaalde soorten keuzes op een natuurlijkere manier weer — en het correct uitlezen van hun waarden kent een paar valkuilen die je moet kennen voordat je erop vertrouwt.
CheckBoxes
De Value-eigenschap van een CheckBox is een eenvoudige Boolean — True wanneer aangevinkt, False wanneer niet:
If chkWelcomeEmail.Value = True Then
MsgBox "A welcome email would be sent here."
End If
Elke CheckBox op een formulier is volledig onafhankelijk van de andere — het aanvinken van chkWelcomeEmail heeft geen invloed op chkNewsletter, wat precies het gewenste gedrag is wanneer de keuzes niet wederzijds exclusief zijn.
OptionButtons
OptionButtons werken precies andersom: binnen dezelfde groep zorgt het selecteren van één ervoor dat alle andere automatisch worden gedeselecteerd — precies wat de Status-keuzes in de schermafbeelding nodig hebben, aangezien een klant niet tegelijkertijd Actief en Inactief kan zijn. Om te bepalen welke is geselecteerd, controleer je de Value van elk afzonderlijk:
Dim status As String
If optActive.Value = True Then
status = "Active"
ElseIf optInactive.Value = True Then
status = "Inactive"
ElseIf optProspect.Value = True Then
status = "Prospect"
End If
De wederzijdse exclusiviteit is automatisch en volledig door VBA geregeld — je hoeft nooit code te schrijven die de andere twee deselecteert wanneer er één wordt geselecteerd. Groepering is echter belangrijk: OptionButtons sluiten elkaar alleen uit binnen dezelfde container (het formulier zelf, of een Frame-besturingselement dat erop is geplaatst), dus twee aparte groepen OptionButtons op hetzelfde formulier — bijvoorbeeld Status en Prioriteit — moeten in twee verschillende Frames staan, anders behandelt VBA ze als één enkele wederzijds exclusieve groep.
ListBoxes
Een ListBox toont meerdere keuzes tegelijk zonder dat deze geopend hoeft te worden, zoals de lijst met steden in Figuur 5.5. Vul deze op dezelfde manier als een ComboBox, met .AddItem, en lees de selectie uit via .Value of .ListIndex:
Private Sub UserForm_Initialize()
lstCities.AddItem "Chicago"
lstCities.AddItem "Boston"
lstCities.AddItem "Austin"
End Sub
Private Sub cmdAssign_Click()
If lstCities.ListIndex = -1 Then
MsgBox "Please select a city first."
Exit Sub
End If
MsgBox "Assigning to: " & lstCities.Value
End Sub
ListIndex is de positie van het geselecteerde item, beginnend bij 0 voor het eerste item — en belangrijk: het is -1 wanneer er nog niets is geselecteerd, wat de controle is die cmdAssign_Click gebruikt om een gebruiker op te vangen die op de knop klikt zonder eerst een stad te kiezen. .Value geeft direct de geselecteerde tekst, wat meestal nuttiger is dan de numerieke positie die .ListIndex biedt.
Multi-Page Forms
Een MultiPage-besturingselement (de Details / Voorkeuren-tabbladen bovenaan in Figuur 5.5) groepeert gerelateerde besturingselementen op afzonderlijke pagina's van hetzelfde fysieke formulier — handig zodra een formulier te veel velden heeft om comfortabel op één scherm te passen. Elke pagina wordt aangeduid op basis van positie, en alleen de besturingselementen op de momenteel zichtbare pagina zijn relevant voor de gebruiker, hoewel ze allemaal nog steeds bestaan en vanuit code kunnen worden uitgelezen, ongeacht welke pagina zichtbaar is:
Private Sub MultiPage1_Change()
If MultiPage1.Value = 1 Then
MsgBox "Now viewing Preferences"
End If
End Sub
MultiPage1.Value volgt dezelfde 0-gebaseerde telling als ListIndex — de eerste pagina is 0, de tweede (Voorkeuren, in Figuur 5.5) is 1 — en het Change-event wordt automatisch geactiveerd wanneer de gebruiker op een ander tabblad klikt.
Taak
- Voeg een Frame toe met drie OptionButtons (optActive, optInactive, optProspect) aan frmAddCustomer, ter vervanging van de eerdere cboStatus ComboBox, en schrijf het hierboven getoonde If...ElseIf-blok om de selectie uit te lezen.
- Voeg twee onafhankelijke CheckBoxes toe (chkWelcomeEmail, chkNewsletter) en controleer tijdens het testen dat het aanvinken van de ene nooit invloed heeft op de andere.
- Voeg een ListBox toe (lstCities) die wordt gevuld in UserForm_Initialize, en schrijf een controle die een foutmelding geeft als de gebruiker probeert door te gaan zonder iets te selecteren (ListIndex = -1).
- Uitdaging: plaats de velden Bedrijfsnaam, Contactpersoon en E-mail op één MultiPage-pagina genaamd "Details", en de CheckBoxes en OptionButtons op een tweede pagina genaamd "Voorkeuren".
1. Vervangen van cboStatus door een Frame met OptionButtons
- Verwijder eerst
cboStatusen het bijbehorende Label van het formulier — je vervangt deze, niet toevoegen naast de nieuwe controls. - Sleep een Frame-control naar het formulier en sleep vervolgens alle drie de OptionButtons binnen de rand van het Frame — deze insluiting zorgt ervoor dat ze elkaar wederzijds uitsluiten als één groep.
- Hernoem elke OptionButton afzonderlijk in het Eigenschappenvenster; het Frame zelf kan een eenvoudige Caption zoals "Status" behouden, maar heeft geen codevriendelijke naam nodig tenzij je er direct naar wilt verwijzen.
- De selectie uitlezen betekent dat je de
.Valuevan elke OptionButton afzonderlijk controleert metIf...ElseIf— er is geen enkele eigenschap die aangeeft "welke in de groep is geselecteerd". - Omdat
cboStatus.Valueniet meer bestaat, heeftcmdSave_Clicknu eenstatus-variabele nodig die wordt opgebouwd uit de OptionButtons en in plaats daarvan innewRowwordt geschreven.
2. Toevoegen van twee onafhankelijke CheckBoxes
- Deze staan direct op het formulier (niet in het Frame) — CheckBoxes buiten een gedeelde container beïnvloeden elkaar nooit, ongeacht de groepering.
- Om "te bevestigen tijdens het testen", vink je gewoon de ene aan, dan de andere, en controleer je dat geen van beide de eerste uitschakelt.
3. Toevoegen en valideren van een ListBox
- Vul deze op dezelfde manier als
cboCitywerd gevuld — herhaalde.AddItem-aanroepen inUserForm_Initialize. ListIndex = -1betekent specifiek er is nog niets aangeklikt — dat is precies de voorwaarde die je moet controleren voordat je het opslaan toestaat.- Deze controle hoort in hetzelfde validatieblok als de andere verplichte velden, en wordt toegevoegd aan dezelfde
errors-string.
4. MultiPage-uitdaging
- Sleep een MultiPage-control naar het formulier — deze bevat standaard twee pagina's, precies het aantal dat je nodig hebt.
- Hernoem elke pagina via rechtsklik → Pagina Volgorde, of door het paginatabblad zelf te selecteren en het veld Caption in het Eigenschappenvenster te gebruiken (Caption bepaalt de zichtbare tekst op het tabblad; er is ook een apart (Name)-veld als je een pagina in de code wilt aanspreken).
- Bestaande controls naar een pagina verplaatsen betekent dat je ze fysiek naar het zichtbare gebied van die pagina sleept in de ontwerpweergave — codeverwijzingen naar deze controls veranderen niet, omdat de naam van een control niet afhankelijk is van de pagina waarop deze staat.
Private Sub UserForm_Initialize()
cboCity.AddItem "Chicago"
cboCity.AddItem "Boston"
cboCity.AddItem "Austin"
cboCity.AddItem "Seattle"
cboCity.AddItem "Denver"
lstCities.AddItem "Chicago"
lstCities.AddItem "Boston"
lstCities.AddItem "Austin"
lstCities.AddItem "Seattle"
lstCities.AddItem "Denver"
End Sub
Private Sub cmdCancel_Click()
Unload Me
End Sub
Private Sub cmdSave_Click()
Dim tbl As ListObject
Dim newRow As ListRow
Dim errors As String
Dim status As String
' --- Reset field colors ---
txtCompanyName.BackColor = vbWhite
txtContact.BackColor = vbWhite
txtEmail.BackColor = vbWhite
' --- Required field checks ---
If Trim(txtCompanyName.Value) = "" Then
errors = errors & "- Company Name is required" & vbNewLine
txtCompanyName.BackColor = RGB(255, 199, 206)
End If
If Trim(txtContact.Value) = "" Then
errors = errors & "- Contact is required" & vbNewLine
txtContact.BackColor = RGB(255, 199, 206)
End If
If Trim(txtEmail.Value) = "" Then
errors = errors & "- Email is required" & vbNewLine
txtEmail.BackColor = RGB(255, 199, 206)
End If
' --- Status via OptionButtons ---
If optActive.Value = True Then
status = "Active"
ElseIf optInactive.Value = True Then
status = "Inactive"
ElseIf optProspect.Value = True Then
status = "Prospect"
Else
errors = errors & "- Please select a Status" & vbNewLine
End If
' --- ListBox check ---
If lstCities.ListIndex = -1 Then
errors = errors & "- Please select a city from the list" & vbNewLine
End If
If errors <> "" Then
MsgBox "Please fix the following:" & vbNewLine & errors, vbExclamation
Exit Sub
End If
' --- All checks passed — safe to save now ---
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 = status
If chkWelcomeEmail.Value = True Then
MsgBox "A welcome email would be sent to " & txtEmail.Value & "."
End If
MsgBox txtCompanyName.Value & " was added successfully."
Unload Me
End Sub
Testnotities:
- Punt 2 (CheckBoxes) heeft geen aparte validatie — klik gewoon
chkWelcomeEmailenchkNewsletteronafhankelijk en bevestig dat elke schakelaar werkt zonder de ander te beïnvloeden. - Punt 4 (MultiPage) is alleen een lay-outwijziging — er zijn geen codewijzigingen nodig buiten wat hier al staat, omdat elke control zijn eigen naam behoudt, ongeacht op welke pagina deze staat.
- Merk op dat
cboCity.Valuenog steeds wordt gebruikt voor het daadwerkelijke opslaan (newRow.Range(1, 5)), terwijllstCitiespuur bestaat als een aparte, onafhankelijk gevalideerde control volgens de opdracht — de twee zijn niet aan elkaar gekoppeld, tenzij je ervoor kiest dit zelf uit te breiden.
Bedankt voor je feedback!