Flexiblere Listen

Callback-Funktion schreiben

Jetzt fehlt nur noch das Gegenstück, nämlich die Funktion selber. Ihr Name ist beliebig, aber die Parameter sind in Reihenfolge und Typ festgelegt, wie in Listing 4 zu sehen ist. Die Namen der Parameter finden sich in Beispielen häufig auch in englischer Sprache, können aber auch frei gewählt werden.

Function Demo(Feld As Control, ID As Variant, _
Zeile As Variant, Spalte As Variant, Code As Variant) As Variant
Select Case Code
Case acLBInitialize
Demo = {True|False}
Case acLBOpen
Demo = eindeutigeID
Case acLBGetRowCount
Demo = {AnzahlZeilen|-1}
Case acLBGetColumnCount
Demo = AnzahlSpalten
Case acLBGetColumnWidth
Demo = SpaltenBreiten
Case acLBGetValue
Demo = Wert
Case acLBEnd
aufräumen, wenn nötig
End Select
End Function

Die Funktion selber wird bei der Aktualisierung einer Liste von dieser mit verschiedenen Code-Konstanten aufgerufen. Dadurch „weiß“ die Funktion, welche Ergebnisse gerade gebraucht werden. Beim ersten Aufruf mit acLBInitialize ist es sinnvoll, alle Daten zu ermitteln und in einem Array bereitzuhalten. Achtung: Variablen wie ein solches Array müssen als Static deklariert werden, damit sie beim nächsten Aufruf nicht leer sind!

Listing 5 zeigt den konkreten Code für die Anzeige aller Dateien eines Verzeichnisses. Die Funktion befindet sich wie alle anderen Prozeduren im Formularmodul und kann deswegen auch direkt auf die Inhalte anderer Controls wie cmbPfad zugreifen.

Function HoleDateien(Feld As Control, ID As Variant, _
Zeile As Variant, Spalte As Variant, Code As Variant) As Variant
Static Dateien() As String
Dim aktDatei As String
Static L As Long
HoleDateien = Null
Select Case Code
Case acLBInitialize
L = 0
ReDim Dateien(2, 0)
aktDatei = Dir(cmbPfad.Value & "*.*")
Do While aktDatei <> ""
Dateien(0, L) = aktDatei
Dateien(1, L) = FileDateTime(cmbPfad.Value & aktDatei)
Dateien(2, L) = FileLen(cmbPfad.Value & aktDatei)
ReDim Preserve Dateien(2, UBound(Dateien, 2) + 1)
L = L + 1
aktDatei = Dir()
Loop
ReDim Preserve Dateien(2, UBound(Dateien, 2) - 1)
HoleDateien = L
Case acLBOpen
HoleDateien = Timer
Case acLBGetRowCount
HoleDateien = L - 1
Case acLBGetColumnCount
HoleDateien = 3
Case acLBGetColumnWidth
HoleDateien = -1
Case acLBGetValue
HoleDateien = Dateien(Spalte, Zeile)
Case acLBEnd
Erase Dateien
End Select
End Function

Nach dem Loop über alle Dateien muss das Array Dateien noch in der zweiten Dimension um einen Eintrag gekürzt werden, damit keine Leerzeile übrig bleibt.

Mit Redim Preserve können Arrays vergrößert und verkleinert werden, ohne dass ihr Inhalt verloren geht. Allerdings ist das nur für die letzte Dimension zulässig.