Endlosformulare sind praktisch: Sie zeigen viele Datensätze untereinander in derselben Struktur. Doch sobald du versuchst, eine einzelne Zeile per VBA einzufärben — etwa einen überfälligen Auftrag rot —, stolperst du über eine Eigenheit, die viele Anfänger zur Verzweiflung bringt: Plötzlich sind alle Zeilen rot.
Diese Lektion erklärt, warum das so ist, und zeigt dir die richtige Lösung: die
bedingte Formatierung über das FormatConditions-Objekt.
Warum ein Steuerelement für alle Zeilen gilt
Ein Endlosformular sieht aus wie eine Tabelle mit vielen Zeilen — technisch ist es
aber nur ein Satz Steuerelemente im Detailbereich, der für jeden Datensatz neu
gezeichnet wird. Das Textfeld txtStatus existiert also nur einmal, nicht pro
Zeile.
Wenn du im Code schreibst:
Me.txtStatus.BackColor = vbRed
dann setzt du die Hintergrundfarbe dieses einen Steuerelements — und da es für
jede Zeile dasselbe ist, werden alle Zeilen rot. Das direkte Setzen von BackColor,
ForeColor oder FontBold funktioniert deshalb nur in Einzelformularen sinnvoll,
nicht in Endlosformularen.
Merke: In Endlosformularen ist jede optische Eigenschaft, die du per VBA direkt setzt, eine Eigenschaft für alle sichtbaren Zeilen zugleich. Für zeilenabhängige Farben brauchst du die bedingte Formatierung.
Die Lösung: FormatConditions
Access hat für genau diesen Fall die bedingte Formatierung eingebaut. Sie bewertet für jede Zeile einzeln einen Ausdruck und färbt nur die Zeilen, auf die er zutrifft. Genau das siehst du auch im Menüband unter Format → Bedingte Formatierung — und du kannst es komplett per VBA steuern.
Jedes Steuerelement hat eine Auflistung FormatConditions. Mit Add fügst du eine
Regel hinzu, mit Delete löschst du alle bestehenden.
Private Sub Form_Load()
Dim fc As FormatCondition
' Alte Regeln entfernen, sonst sammeln sie sich an
Me.txtStatus.FormatConditions.Delete
' Neue Regel: Wenn Feld "Status" = "offen", dann rot hinterlegen
Set fc = Me.txtStatus.FormatConditions.Add( _
acFieldValue, acEqual, "'offen'")
fc.BackColor = RGB(255, 199, 206) ' helles Rot
fc.ForeColor = RGB(156, 0, 6) ' dunkles Rot für Text
fc.FontBold = True
End Sub
Der wichtige Punkt: FormatConditions.Add wird einmalig beim Laden aufgerufen,
nicht pro Zeile. Access wendet die Regel danach automatisch auf jede Zeile
einzeln an.
Die Parameter von Add
FormatConditions.Add erwartet je nach Regeltyp unterschiedliche Argumente:
| Argument | Bedeutung | Beispielwerte |
|---|---|---|
Type | Was wird geprüft | acFieldValue, acExpression, acFieldHasFocus |
Operator | Vergleich | acEqual, acBetween, acGreaterThan, acLessThan |
Expression1 | Vergleichswert / Ausdruck | "100", "'offen'", "1000" |
Expression2 | zweiter Wert (nur bei acBetween) | "5000" |
Für Textvergleiche gehört der Wert in einfache Anführungszeichen innerhalb des
Strings: "'offen'". Bei Zahlen reicht "100".
Ampel-Status: Farbe abhängig vom Wert
Ein häufiger Wunsch ist eine „Ampel": Ein Feld Bestand soll rot werden, wenn er
kritisch niedrig ist, gelb bei Warnung und grün, wenn alles in Ordnung ist. Dafür
legst du mehrere Regeln übereinander. Access prüft sie in der Reihenfolge des
Hinzufügens und nimmt die erste zutreffende.
Private Sub Form_Load()
Dim fc As FormatCondition
Me.txtBestand.FormatConditions.Delete
' Rot: Bestand unter 10
Set fc = Me.txtBestand.FormatConditions.Add( _
acFieldValue, acLessThan, "10")
fc.BackColor = RGB(255, 92, 92)
fc.ForeColor = vbWhite
' Gelb: Bestand zwischen 10 und 50
Set fc = Me.txtBestand.FormatConditions.Add( _
acFieldValue, acBetween, "10", "50")
fc.BackColor = RGB(255, 214, 102)
' Grün: Bestand über 50
Set fc = Me.txtBestand.FormatConditions.Add( _
acFieldValue, acGreaterThan, "50")
fc.BackColor = RGB(146, 208, 80)
End Sub
Regel über einen Ausdruck (andere Spalte prüfen)
Manchmal soll die Farbe eines Feldes von einem anderen Feld abhängen — zum
Beispiel den Kundennamen rot einfärben, wenn das Lieferdatum überschritten ist.
Dafür nutzt du acExpression und schreibst einen Ausdruck, der die Feldnamen des
Formulars referenziert:
Private Sub Form_Load()
Dim fc As FormatCondition
Me.txtKunde.FormatConditions.Delete
' Ausdruck bewertet pro Zeile das Feld "Lieferdatum"
Set fc = Me.txtKunde.FormatConditions.Add( _
acExpression, , "[Lieferdatum] < Date() And [Erledigt] = False")
fc.BackColor = RGB(255, 199, 206)
fc.ForeColor = RGB(156, 0, 6)
fc.FontBold = True
End Sub
Beim Typ acExpression bleibt das Operator-Argument leer (das Komma bleibt
stehen), und der ganze Vergleich steht in Expression1. Die eckigen Klammern
verweisen auf die Felder der zugrunde liegenden Datenherkunft.
Achtung: Ein Steuerelement erlaubt maximal vier bedingte Formatierungsregeln plus das Standardformat. Brauchst du mehr Abstufungen, musst du auf einen Bericht oder eigene Logik im
Format-Ereignis ausweichen.
Bedingte Formatierung vs. Bericht
Beide Techniken färben zeilenabhängig — aber sie haben unterschiedliche Stärken:
| Endlosformular + FormatConditions | Bericht + Format-Ereignis | |
|---|---|---|
| Interaktiv (scrollen, bearbeiten) | ja | nein (nur Anzeige/Druck) |
| Anzahl Regeln | max. 4 pro Feld | unbegrenzt (per Code) |
Direktes BackColor je Zeile | nein | ja, im Detail_Format |
| Für den Druck gedacht | eher nicht | ja |
Im Bericht wird der Detailbereich für jede Zeile einzeln gerendert und das
Format-Ereignis pro Datensatz ausgelöst — dort funktioniert direktes BackColor
sehr wohl:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
If Me.Bestand < 10 Then
Me.txtBestand.BackColor = RGB(255, 92, 92)
Else
Me.txtBestand.BackColor = vbWhite
End If
End Sub
Der Else-Zweig ist wichtig: Da der Bereich wiederverwendet wird, musst du die
Farbe für nicht zutreffende Zeilen aktiv zurücksetzen — sonst „klebt" die Farbe der
vorherigen Zeile.
Zusammengefasst
- In Endlosformularen gibt es jedes Steuerelement nur einmal — direktes
BackColorfärbt darum immer alle Zeilen. - Für zeilenabhängige Farben nutzt du
FormatConditions.Add, das Access pro Datensatz einzeln auswertet. acFieldValueprüft den Feldwert,acExpressionerlaubt Regeln über andere Spalten; maximal vier Regeln pro Steuerelement.- Rufe die Regeln einmal in
Form_Loadauf und lösche vorher mitFormatConditions.Deletedie alten. - Für Druck oder mehr als vier Abstufungen nimm einen Bericht und färbe im
Detail_Format-Ereignis direkt — dort inklusiveElse-Zurücksetzen.