Access: VBA-Funktionen für Kombinationsfeld (Combobox) und Listenfeld (Listbox)
Im folgenden geht es um Listboxen und Comboboxen auf Access-Formularen. Die Methoden funktionieren nicht auf Formularen der MSForms-Bibliothek, die man z.B. mit Excel erstellen kann.
Es gibt einige Funktionen, die nicht direkt in den Objektmethoden einer Listbox oder einer Combobox enthalten sind. Beispielsweise „Selektiere alle Einträge einer Listbox“ oder „Finde einen bestimmten Eintrag in einer Listbox“.
Problem bei Listboxen mit Spaltenüberschrift
Außerdem gibt es eine Merkwürdigkeit im Umgang mit den VBA-Listbox-Eigenschaften: Wenn die Listbox Überschriften enthält, dann liefern die Eigenschaften ListCount, ItemData, Column und Selected unerwartete Ergebnisse, weil die Überschriften als Zeile mit dem Index 0 gezählt wird, d.h. die erste Daten-Zeile hat den Index 1 !
Das führt z.B. dazu, dass der Versuch, via VBA die erste Zeile einer Listbox (ohne Mehrfachauswahl) zu selektieren:
ListBox = ListBox.ItemData(0)
nur klappt, wenn die Listbox keine Spaltenüberschriften hat!
Hier würde es also Sinn machen, eine Funktion dafür zu erstellen, die das erwartete Ergebnis liefert, unabhängig davon, ob die Liste Spaltenüberschriften hat oder nicht:
Public Sub LB_SelectIndex(lb_cb As Object, Index As Integer) ' Für Listbox und ComboBox ' selektiere zeile mit dem übergebenen Index ' Liefert mit und ohne Spaltenüberschriften das gleiche ergebnis lb_cb.Selected(Index - lb_cb.ColumnHeads) = True End Sub
Statt mit ItemData wird hier aber die Selected-Eigenschaft verwendet, bei der das gleiche Problem besteht:
lb.Selected(0)=True markiert die erste Zeile nur, wenn die Liste keine Überschriften enthält!
Funktionen um etwas aus einer Listbox oder einer Combobox zu lesen
Selektierten Wert der gebundenen Spalte ermitteln. Oder Wert einer bestimmten Zeile in der gebundenen Spalte ermitteln.
Public Function LB_Value(lb_cb As Object, Optional Index As Integer = -1) As Variant ' Für Listbox (ohne Mehrfachauswahl) und Combobox ' Selektierter Wert der gebundenen Spalte, wenn Index fehlt (Null, wenn kein Eintrag selektiert) ' Wert der gebundenen Spalte einer best. Zeile, wenn Index angegeben ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert If Index = -1 Then LB_Value = lb_cb.Value Else LB_Value = lb_cb.ItemData(Index - lb_cb.ColumnHeads) End If End Function
Selektierten Wert einer beliebigen Spalte ermitteln
Public Function LB_Column(lb_cb As Object, iCol As Integer, Optional Index As Integer = -1) As Variant ' Für Listbox (ohne Mehrfachauswahl) und Combobox ' Selektierter Wert der Spalte iCol, wenn Index fehlt (Null, wenn kein Eintrag selektiert) ' Wert der Spalte iCol einer best. Zeile, wenn Index angegeben (Index beginnt bei 0) ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert If Index = -1 Then LB_Column = lb_cb.Column(iCol, lb_cb.ListIndex) Else LB_Column = lb_cb.Column(iCol, Index - lb_cb.ColumnHeads) End If End Function
Summe der numerischen Werte einer bestimmten Spalte einer Listbox oder Combobox
Public Function LB_Sum(lb_cb As Object, Optional iCol As Integer = -1) As Double ' Für Listbox und Combobox ' Summe der numerischen Werte in Spalte iCol (oder gebundene Spalte, wenn iCol fehlt) ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert ' unabhängig von Selektion und Mehrfachauswahl Dim i As Integer If iCol = -1 Then iCol = lb_cb.BoundColumn - 1 For i = 0 To lb_cb.ListCount + lb_cb.ColumnHeads - 1 If IsNumeric(lb_cb.Column(iCol, i - lb_cb.ColumnHeads)) Then LB_Sum = LB_Sum + lb_cb.Column(iCol, i - lb_cb.ColumnHeads) End If Next End Function
Bestimmten Wert in bestimmter Spalte finden
Public Function LB_Find(lb_cb As Object, varFind As Variant, Optional iCol As Integer = -1) As Variant ' Für Listbox und Combobox ' Gibt zeilen-Index der zeile zurück, wenn bestimmter wert in Spalte iCol gefunden wird (bzw. in gebundener Spalte, wenn iCol fehlt) ' Gibt Null zurück, wenn Wert nicht gefunden wird ' varFind kann Wildcards * oder ? haben ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert ' unabhängig von Selektion und Mehrfachauswahl Dim i As Integer Dim strValue As String If iCol = -1 Then iCol = lb_cb.BoundColumn - 1 LB_Find = Null For i = 0 To lb_cb.ListCount + lb_cb.ColumnHeads - 1 strValue = lb_cb.Column(iCol, i - lb_cb.ColumnHeads) If strValue Like varFind Then LB_Find = i Exit Function End If Next End Function
Anzahl der Zeilen einer Listbox oder Combobox
Die Eigenschaft ListCount zählt tatsächlich 1 dazu, wenn die Liste Überschriften enthält!
-> Hier die Funktion, die mit und ohne Überschriften das richtige Ergebnis liefert.
Public Function LB_ListCount(lb_cb As Object) As Long ' Für Listbox und Combobox ' gibt Anzahl der Zeilen zurück ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert ' unabhängig von Selektion und Mehrfachauswahl ' bei tatsächlich 0 eintägen in der liste liefert .ListCount richtigerweise 0 bei mit und ohne Überschriften ' aber wenn Eintäge vorhanden sind, dann zählt .ListCount 1 dazu, wenn Überschriften=ja LB_ListCount = lb_cb.ListCount + lb_cb.ColumnHeads If LB_ListCount = -1 Then LB_ListCount = 0 End Function
Array mit Werten einer Spalte
Die folgende Funktion verwendet die Funktion ArrayAdd, die im Beitrag Nützliche Array-Funktionen aufgelistet ist.
Public Function LB_Array(lb_cb As Object, Optional iCol As Integer = -1) As Variant ' Für Listbox und Combobox ' Gibt Array mit Werten einer Spalte zurück (gebundene Spalte, wenn iCol fehlt) ' Gibt Empty zurück, wenn Liste leer ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert ' unabhängig von Selektion und Mehrfachauswahl Dim i As Integer Dim strValue As String If iCol = -1 Then iCol = lb_cb.BoundColumn - 1 For i = 0 To lb_cb.ListCount + lb_cb.ColumnHeads - 1 ArrayAdd LB_Array, lb_cb.Column(iCol, i - lb_cb.ColumnHeads) Next End Function
Auswahl-Aktionen mit Listboxen und Comboboxen
Selektiere eine bestimmte Zeile, d.h. Zeilenindex, einer Listbox oder Combobox
Public Sub LB_SelectIndex(lb_cb As Object, Index As Integer) ' Für Listbox und ComboBox ' selektiere zeile mit dem übergebenen Index (beginnend bei 0) ' Liefert mit und ohne Spaltenüberschriften das gleiche ergebnis lb_cb.Selected(Index - lb_cb.ColumnHeads) = True End Sub
Selektiere eine Zeile, bei der die gebundene Spalte oder eine bestimmte Spalte einen bestimmten Wert hat. Auch mit Wildcards.
Public Function LB_Select(lb As ListBox, varValue As Variant, Optional iCol As Integer = -1, Optional bAdditional As Boolean) As Boolean ' Für Listbox ' selektiere zeile (auch mehrere bei mehrfachauswahl), bei der Spalte iCol den Wert varValue hat (wenn iCol nicht angegeben ist, dann gebundene Spalte!) ' varValue kann Wildcards * und ? haben ' Liefert mit und ohne Spaltenüberschriften das gleiche ergebnis ' bAdditional: wenn false, dann wird initial die Listbox geleert ' wenn true, dann wird die bestehende selektion beibehalten ' Rückgabe: true, wenn zeile(n) markiert wurde(n) Dim i As Integer If iCol = -1 Then iCol = lb.BoundColumn - 1 For i = 0 To lb.ListCount - 1 If lb.Column(iCol, i) Like varValue Then lb.Selected(i) = True ElseIf Not bAdditional Then lb.Selected(i) = False End If Next End Function
Funktionen für Listboxen mit Mehrfachauswahl
Ist eine bestimmte Zeile selektiert?
Public Function LB_Selected(lb As ListBox, Index As Integer) As Boolean ' Für Listbox mit Mehrfachauswahl ' Liefert True, wenn Zeile Index selektiert ist ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert ' selected(0) ist bei MitÜberschriften immer 0, weil es die Überschriftenzeile ist LB_Selected = lb.Selected(Index - lb.ColumnHeads) End Function
Wieviele Zeilen sind selektiert?
Public Function LB_SelectCount(lb As ListBox) As Integer ' Für Listbox mit Mehrfachauswahl ' Liefert Anzahl der selektierten Einträge ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert LB_SelectCount = lb.ItemsSelected.Count End Function
Array mit den selektierten Werten (gebundene oder beliebige Spalte) einer Listbox mit Mehrfach-Auswahl
Public Function LB_ArrayOfSelected(lb As ListBox, Optional iCol As Integer = -1) As Variant ' Für Listbox mit Mehrfachauswahl ' Gibt Array zurück, mit den selektierten Values einer Listbox (Gebunden Spalte, wenn iCol nicht übergeben wird, sonst Spalte iCol) ' Empty, wen nichts selektiert ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert Dim varItem As Variant If iCol = -1 Then iCol = lb.BoundColumn - 1 For Each varItem In lb.ItemsSelected ArrayAdd LB_ArrayOfSelected, lb.Column(iCol, varItem) Next varItem End Function
Ist Zeile mit bestimmtem Wert (in gebundener oder beliebiger Spalte) selektiert in einer Listbox mit Mehrfach-Auswahl?
Public Function LB_ValueSelected(lb As ListBox, varValue As Variant, Optional iCol As Integer = -1) As Boolean ' Für Listbox mit Mehrfachauswahl ' Gibt True zurück, wenn varValue unter den selektierten Werten ist, wobei die Spalte iCol maßgeblich ist (wenn iCol fehlt, dann gebundene Spalte) ' varValue kann Wildcards * und ? haben ' Empty, wenn nichts selektiert ' Liefert mit und ohne Spaltenüberschriften den gleichen Wert Dim varItem As Variant If iCol = -1 Then iCol = lb.BoundColumn - 1 For Each varItem In lb.ItemsSelected If lb.Column(iCol, varItem) Like varValue Then LB_ValueSelected = True Exit Function End If Next varItem End Function
Selektiere oder deselektiere alle Zeilen in einer Listbox mit Mehrfachauswahl
Public Sub LB_SelectAllOrNone(lb As ListBox, bSelect As Boolean) ' Alle Zeilen einer Listbox selektieren oder deselektieren Dim i As Integer For i = 0 To lb.ListCount - 1 lb.Selected(i) = bSelect Next End Sub
If Index = -1 Then
LB_Value = lb_cb.Value
Else
LB_Value = lb_cb.ItemData(Index – lb_cb.ColumnHeads)
End If
End Function
Public Function LB_Column(lb_cb As Object, iCol As Integer, Optional Index As Integer = -1) As Variant
‚ Für Listbox (ohne Mehrfachauswahl) und Combobox
‚ Selektierter Wert der Spalte iCol, wenn Index fehlt (Null, wenn kein Eintrag selektiert)
‚ Wert der Spalte iCol einer best. Zeile, wenn Index angegeben (Index beginnt bei 0)
‚ Liefert mit und ohne Spaltenüberschriften den gleichen Wert
If Index = -1 Then
LB_Column = lb_cb.Column(iCol, lb_cb.ListIndex)
Else
LB_Column = lb_cb.Column(iCol, Index – lb_cb.ColumnHeads)
End If
End Function
Public Function LB_Sum(lb_cb As Object, Optional iCol As Integer = -1) As Double
‚ Für Listbox und Combobox
‚ Summe der numerischen Werte in Spalte iCol (oder gebundene Spalte, wenn iCol fehlt)
‚ Liefert mit und ohne Spaltenüberschriften den gleichen Wert
‚ unabhängig von Selektion und Mehrfachauswahl
Dim i As Integer
If iCol = -1 Then iCol = lb_cb.BoundColumn – 1
For i = 0 To lb_cb.ListCount + lb_cb.ColumnHeads – 1
If IsNumeric(lb_cb.Column(iCol, i – lb_cb.ColumnHeads)) Then
LB_Sum = LB_Sum + lb_cb.Column(iCol, i – lb_cb.ColumnHeads)
End If
Next
End Function
Public Function LB_Find(lb_cb As Object, varFind As Variant, Optional iCol As Integer = -1) As Variant
‚ Für Listbox und Combobox
‚ Gibt zeilen-Index der zeile zurück, wenn bestimmter wert in Spalte iCol gefunden wird (bzw. in gebundener Spalte, wenn iCol fehlt)
‚ Gibt Null zurück, wenn Wert nicht gefunden wird
‚ varFind kann Wildcards * oder ? haben
‚ Liefert mit und ohne Spaltenüberschriften den gleichen Wert
‚ unabhängig von Selektion und Mehrfachauswahl
Dim i As Integer
Dim strValue As String
If iCol = -1 Then iCol = lb_cb.BoundColumn – 1
LB_Find = Null
For i = 0 To lb_cb.ListCount + lb_cb.ColumnHeads – 1
strValue = lb_cb.Column(iCol, i – lb_cb.ColumnHeads)
If strValue Like varFind Then
LB_Find = i
Exit Function
End If
Next
End Function
Public Function LB_ListCount(lb_cb As Object) As Long
‚ Für Listbox und Combobox
‚ gibt Anzahl der Zeilen zurück
‚ Liefert mit und ohne Spaltenüberschriften den gleichen Wert
‚ unabhängig von Selektion und Mehrfachauswahl
‚ bei tatsächlich 0 eintägen in der liste liefert .ListCount richtigerweise 0 bei mit und ohne Überschriften
‚ aber wenn Eintäge vorhanden sind, dann zählt .ListCount 1 dazu, wenn Überschriften=ja
LB_ListCount = lb_cb.ListCount + lb_cb.ColumnHeads
If LB_ListCount = -1 Then LB_ListCount = 0
End Function
Public Function LB_Array(lb_cb As Object, Optional iCol As Integer = -1) As Variant
‚ Für Listbox und Combobox
‚ Gibt Array mit Werten einer Spalte zurück (gebundene Spalte, wenn iCol fehlt)
‚ Gibt Empty zurück, wenn Liste leer
‚ Liefert mit und ohne Spaltenüberschriften den gleichen Wert
‚ unabhängig von Selektion und Mehrfachauswahl
Dim i As Integer
Dim strValue As String
If iCol = -1 Then iCol = lb_cb.BoundColumn – 1
For i = 0 To lb_cb.ListCount + lb_cb.ColumnHeads – 1
ArrayAdd LB_Array, lb_cb.Column(iCol, i – lb_cb.ColumnHeads)
Next
End Function
Public Sub LB_SelectIndex(lb_cb As Object, Index As Integer)
‚ Für Listbox und ComboBox
‚ selektiere zeile mit dem übergebenen Index (beginnend bei 0)
‚ Liefert mit und ohne Spaltenüberschriften das gleiche ergebnis
lb_cb.Selected(Index – lb_cb.ColumnHeads) = True
End Sub
Public Function LB_Select(lb As ListBox, varValue As Variant, Optional iCol As Integer = -1, Optional bAdditional As Boolean) As Boolean
‚ Für Listbox
‚ selektiere zeile (auch mehrere bei mehrfachauswahl), bei der Spalte iCol den Wert varValue hat (wenn iCol nicht angegeben ist, dann gebundene Spalte!)
‚ varValue kann Wildcards * und ? haben
‚ Liefert mit und ohne Spaltenüberschriften das gleiche ergebnis
‚ bAdditional: wenn false, dann wird initial die Listbox geleert
‚ wenn true, dann wird die bestehende selektion beibehalten
‚ Rückgabe: true, wenn zeile(n) markiert wurde(n)
Dim i As Integer
If iCol = -1 Then iCol = lb.BoundColumn – 1
For i = 0 To lb.ListCount – 1
If lb.Column(iCol, i) Like varValue Then
lb.Selected(i) = True
ElseIf Not bAdditional Then
lb.Selected(i) = False
End If
Next
End Function
Public Function LB_Selected(lb As ListBox, Index As Integer) As Boolean
‚ Für Listbox mit Mehrfachauswahl
‚ Liefert True, wenn Zeile Index selektiert ist
‚ Liefert mit und ohne Spaltenüberschriften den gleichen Wert
‚ selected(0) ist bei MitÜberschriften immer 0, weil es die Überschriftenzeile ist
LB_Selected = lb.Selected(Index – lb.ColumnHeads)
End Function
Public Function LB_SelectCount(lb As ListBox) As Integer
‚ Für Listbox mit Mehrfachauswahl
‚ Liefert Anzahl der selektierten Einträge
‚ Liefert mit und ohne Spaltenüberschriften den gleichen Wert
LB_SelectCount = lb.ItemsSelected.Count
End Function
Public Function LB_ArrayOfSelected(lb As ListBox, Optional iCol As Integer = -1) As Variant
‚ Für Listbox mit Mehrfachauswahl
‚ Gibt Array zurück, mit den selektierten Values einer Listbox (Gebunden Spalte, wenn iCol nicht übergeben wird, sonst Spalte iCol)
‚ Empty, wen nichts selektiert
‚ Liefert mit und ohne Spaltenüberschriften den gleichen Wert
Dim varItem As Variant
If iCol = -1 Then iCol = lb.BoundColumn – 1
For Each varItem In lb.ItemsSelected
ArrayAdd LB_ArrayOfSelected, lb.Column(iCol, varItem)
Next varItem
End Function
Public Function LB_ValueSelected(lb As ListBox, varValue As Variant, Optional iCol As Integer = -1) As Boolean
‚ Für Listbox mit Mehrfachauswahl
‚ Gibt True zurück, wenn varValue unter den selektierten Werten ist, wobei die Spalte iCol maßgeblich ist (wenn iCol fehlt, dann gebundene Spalte)
‚ varValue kann Wildcards * und ? haben
‚ Empty, wenn nichts selektiert
‚ Liefert mit und ohne Spaltenüberschriften den gleichen Wert
Dim varItem As Variant
If iCol = -1 Then iCol = lb.BoundColumn – 1
For Each varItem In lb.ItemsSelected
If lb.Column(iCol, varItem) Like varValue Then
LB_ValueSelected = True
Exit Function
End If
Next varItem
End Function
Public Sub LB_SelectAllOrNone(lb As ListBox, bSelect As Boolean)
‚ Alle Zeilen einer Listbox selektieren oder deselektieren
Dim i As Integer
For i = 0 To lb.ListCount – 1
lb.Selected(i) = bSelect
Next
End Sub[/raw]