Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Arbeiten mit Formularsteuerelementen | Benutzerinteraktion
Excel VBA für Geschäftsautomatisierung

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.

Abbildung 5.5

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

  1. 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.
  2. 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.
  3. 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).
  4. 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".
Hinweis
expand arrow

1. Ersetzen von cboStatus durch einen Rahmen mit Optionsfeldern

  • Löschen Sie zuerst cboStatus und 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 .Value jedes Optionsfeldes einzeln mit If...ElseIf — es gibt keine Eigenschaft, die direkt angibt, "welches in der Gruppe ausgewählt ist".
  • Da cboStatus.Value nicht mehr existiert, benötigt cmdSave_Click stattdessen eine status-Variable, die aus den Optionsfeldern gebildet und anstelle dessen in newRow geschrieben 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 in UserForm_Initialize.
  • ListIndex = -1 bedeutet 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.
Lösung
expand arrow
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 chkWelcomeEmail und chkNewsletter unabhä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.Value weiterhin für das eigentliche Speichern verwendet wird (newRow.Range(1, 5)), während lstCities ausschließlich als separates, unabhängig validiertes Steuerelement gemäß der Aufgabe existiert — die beiden sind nicht miteinander verbunden, es sei denn, Sie erweitern dies selbst.
War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 5. Kapitel 4

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

Abschnitt 5. Kapitel 4
some-alt