Arbeiten mit Formularsteuerelementen
Swipe um das Menü anzuzeigen
TextBoxes und ComboBoxes decken den Großteil der Dateneingabe ab, aber einige andere Steuerelemente drücken bestimmte Auswahlmöglichkeiten auf natürlichere Weise aus – und das korrekte Auslesen ihrer Werte birgt einige echte Fallstricke, die man kennen sollte, bevor man sich darauf verlässt.
CheckBoxes
Die Value-Eigenschaft eines CheckBox ist ein einfacher Boolean – True, wenn aktiviert, False, wenn nicht:
If chkWelcomeEmail.Value = True Then
MsgBox "A welcome email would be sent here."
End If
Jede CheckBox auf einem Formular ist völlig unabhängig von allen anderen – das Aktivieren von chkWelcomeEmail hat keinen Einfluss auf chkNewsletter, was genau das gewünschte Verhalten ist, wenn die Auswahlmöglichkeiten nicht gegenseitig ausschließend sind.
OptionButtons
OptionButtons verhalten sich genau umgekehrt: Innerhalb derselben Gruppe hebt das Auswählen eines Buttons automatisch die Auswahl aller anderen auf – genau das, was die Status-Auswahl im Screenshot benötigt, da ein Kunde nicht gleichzeitig Aktiv und Inaktiv sein kann. Um auszulesen, welcher ausgewählt ist, prüft man den Wert jedes einzelnen Buttons:
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
Die gegenseitige Ausschließlichkeit ist automatisch und wird vollständig von VBA gehandhabt – es ist nie nötig, Code zu schreiben, der die anderen beiden Buttons deaktiviert, wenn einer ausgewählt wird. Die Gruppierung ist jedoch wichtig: OptionButtons schließen sich nur innerhalb desselben Containers (dem Formular selbst oder einem darauf platzierten Frame-Steuerelement) gegenseitig aus. Zwei separate Gruppen von OptionButtons auf demselben Formular – zum Beispiel Status und Priorität – müssen also in zwei verschiedenen Frames platziert werden, sonst behandelt VBA alle als eine einzige, gegenseitig ausschließende Gruppe.
ListBoxes
Eine ListBox zeigt mehrere Auswahlmöglichkeiten gleichzeitig an, ohne dass sie geöffnet werden muss, wie die Städte-Liste in Abbildung 5.5. Sie wird wie eine ComboBox mit .AddItem befüllt, und die Auswahl wird entweder über .Value oder .ListIndex ausgelesen:
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 ist die Position des ausgewählten Elements, beginnend bei 0 für das erste Element – und entscheidend ist, dass der Wert -1 ist, wenn noch nichts ausgewählt wurde. Das nutzt cmdAssign_Click, um abzufangen, wenn ein Benutzer auf den Button klickt, ohne vorher eine Stadt auszuwählen. .Value liefert direkt den ausgewählten Text, was in der Regel nützlicher ist als die numerische Position, die .ListIndex angibt.
Multi-Page Forms
Ein MultiPage-Steuerelement (die Details-/Präferenzen-Tabs oben in Abbildung 5.5) gruppiert verwandte Steuerelemente auf separaten Seiten desselben physischen Formulars – nützlich, wenn ein Formular zu viele Felder enthält, um bequem auf einen Bildschirm zu passen. Jede Seite wird über ihre Position angesprochen, und nur die Steuerelemente auf der aktuell sichtbaren Seite sind für den Benutzer relevant, obwohl alle weiterhin existieren und per Code ausgelesen werden können, unabhängig davon, welche Seite angezeigt wird:
Private Sub MultiPage1_Change()
If MultiPage1.Value = 1 Then
MsgBox "Now viewing Preferences"
End If
End Sub
MultiPage1.Value verwendet die gleiche 0-basierte Zählweise wie ListIndex – die erste Seite ist 0, die zweite (Präferenzen, in Abbildung 5.5) ist 1 – und das Change-Ereignis wird automatisch ausgelöst, wenn der Benutzer auf einen anderen Tab klickt.
Aufgabe
- Ersetzen Sie das frühere cboStatus-ComboBox durch einen Rahmen (Frame) mit drei Optionsfeldern (optActive, optInactive, optProspect) in frmAddCustomer und schreiben Sie den oben gezeigten If...ElseIf-Block, um die Auswahl auszulesen.
- Fügen Sie zwei unabhängige Kontrollkästchen (chkWelcomeEmail, chkNewsletter) hinzu und überprüfen Sie beim Testen, dass das Aktivieren des einen das andere nicht beeinflusst.
- Fügen Sie eine ListBox (lstCities) hinzu, die in UserForm_Initialize befüllt wird, und schreiben Sie eine Prüfung, die einen Fehler anzeigt, wenn der Benutzer versucht, ohne Auswahl fortzufahren (ListIndex = -1).
- Herausforderung: Platzieren Sie die Felder Firmenname, Kontakt und E-Mail auf einer MultiPage-Seite mit dem Namen "Details" und die Kontrollkästchen und Optionsfelder auf einer zweiten Seite mit dem Namen "Preferences".
1. Ersetzen von cboStatus durch einen Rahmen mit Optionsfeldern
- Löschen Sie zuerst
cboStatusund dessen Beschriftung aus dem Formular — Sie ersetzen es, nicht zusätzlich einfügen. - Ziehen Sie ein Frame-Steuerelement auf das Formular und platzieren Sie alle drei Optionsfelder innerhalb des Rahmens — diese Gruppierung sorgt dafür, dass sie sich gegenseitig ausschließen.
- Benennen Sie jedes Optionsfeld einzeln im Eigenschaftenfenster um; der Rahmen selbst kann eine einfache Beschriftung wie "Status" behalten und benötigt keinen codefreundlichen Namen, sofern Sie ihn nicht direkt referenzieren möchten.
- Um die Auswahl auszulesen, prüfen Sie den
.Valuejedes Optionsfeldes einzeln mitIf...ElseIf— es gibt keine Eigenschaft, die direkt angibt, "welches in der Gruppe ausgewählt ist". - Da
cboStatus.Valuenicht mehr existiert, benötigtcmdSave_Clickstattdessen einestatus-Variable, die aus den Optionsfeldern gebildet und anstelle dessen innewRowgeschrieben wird.
2. Hinzufügen von zwei unabhängigen Kontrollkästchen
- Diese befinden sich direkt auf dem Formular (nicht im Rahmen) — Kontrollkästchen außerhalb eines gemeinsamen Containers beeinflussen sich nie gegenseitig, unabhängig von der Gruppierung.
- Um "beim Testen zu bestätigen", aktivieren Sie einfach das eine, dann das andere, und beobachten Sie, dass keines das andere deaktiviert.
3. Hinzufügen und Validieren einer ListBox
- Befüllen Sie sie auf die gleiche Weise wie
cboCity— wiederholte.AddItem-Aufrufe inUserForm_Initialize. ListIndex = -1bedeutet es wurde noch nichts ausgewählt — genau dieser Zustand ist vor dem Speichern zu prüfen.- Diese Prüfung gehört in denselben Validierungsblock wie die anderen Pflichtfeldprüfungen und wird an denselben
errors-String angehängt.
4. MultiPage-Herausforderung
- Ziehen Sie ein MultiPage-Steuerelement auf das Formular — es enthält standardmäßig zwei Seiten, was genau benötigt wird.
- Benennen Sie jede Seite über Rechtsklick → Seitenreihenfolge oder durch Auswahl des Seiten-Tabs und Bearbeitung des Feldes "Caption" im Eigenschaftenfenster (Caption steuert den sichtbaren Tab-Text; es gibt auch ein separates (Name)-Feld, falls Sie eine Seite im Code referenzieren möchten).
- Um vorhandene Steuerelemente auf eine Seite zu verschieben, ziehen Sie sie im Entwurfsmodus physisch auf den sichtbaren Bereich der Seite — Code-Referenzen ändern sich nicht, da der Name des Steuerelements unabhängig von der Seite bleibt.
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
Testhinweise:
- Punkt 2 (Kontrollkästchen) hat keine eigene Validierung — klicken Sie einfach
chkWelcomeEmailundchkNewsletterunabhängig voneinander an und bestätigen Sie, dass jedes unabhängig umschaltet. - Punkt 4 (MultiPage) ist nur eine Layoutänderung — es sind keine Codeänderungen erforderlich, da jedes Steuerelement seinen Namen behält, unabhängig davon, auf welcher Seite es platziert ist.
- Beachten Sie, dass
cboCity.Valueweiterhin für das eigentliche Speichern verwendet wird (newRow.Range(1, 5)), währendlstCitiesausschließlich als separates, unabhängig validiertes Steuerelement gemäß der Aufgabe existiert — die beiden sind nicht miteinander verbunden, es sei denn, Sie erweitern dies selbst.
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen