Eine Sub-Prozedur führt unter VBA eine Aktion durch, eine Funktion möglicherweise auch, doch wichtiger ist in der Regel das berechnete Ergebnis, welches sie dem Aufruf zurückgibt. Fast immer handelt es sich dabei um einen bestimmten gesuchten Wert. Gelegentlich erwartet die aufrufende Prozedur aber auch eine Menge von Rückgabedaten. Hier kommen Arrays ins Spiel.
Beispieldatenbank
Die Beispiele dieses Artikels finden Sie in der Datenbank 1508_Array.accdb.
Multiple Ergebnisse
Gerade in der Datenbankprogrammierung ist die Rückgabe von Ergebnissen, die mehr, als einen Wert enthalten, trivial. Nur kommen hier zur Auswertung gewöhnlich Datenbankobjekte zum Einsatz, deren Hauptprotagonist das Recordset ist.
So gibt die Methode OpenRecordset von DAO nicht nur eine Serie von Daten zurück, sondern sogar eine zweidimensionale: in der einen Dimension die Spalten, also Felder, eines Datensatzes, in der anderen die Datensätze selbst.
An die Zellen dieser zweidimensionalen Wertemenge gelangt man dann über spezielle Methoden des Objekts, statt über Indizes, wie das bei Arrays der Fall ist. Auf der einen Seite ist dies praktisch, auf der anderen Seite verlangt es mehr Programmierung.
Hierzu ein Beispiel. Sie möchten den Wert der Zelle einer Adressentabelle ermitteln, sei es etwa die dritte Spalte des vierzehnten Datensatzes. Unter Excel könnte das Arbeitsblatt nun tatsächlich über Koordinaten abgefragt werden:
Debug.Print WorkSheet.Cells(13,2)
Bei einem Recordset ist das nicht direkt möglich. Hier sähe die Routine so aus:
Set rs = CurrentDb. _ OpenRecordset("tblAdressen") rs.Move 13 Debug.Print rs(2).Value
Hier haben wir eine Zeile mehr Code und die übersicht ist geringer, weil die Koordinaten auf unterschiedliche Zeilen aufgeteilt sind.
Befänden sich alle Adressdaten in einem Array, so könnte über zwei Indizes auf die Zelle zugegriffen werden. Immerhin hält DAO dafür eine eigene Methode bereit:
Set rs = CurrentDb. _ OpenRecordset("tblAdressen") V = rs.GetRows Debug.Print V(2,13)
GetRows verwandelt nämlich die Datensätze eines Recordsets in ein zweidimensionales Array, wobei dieses als Variant deklariert sein muss und die einzelnen Elemente darin ebenfalls diesen Datentyp aufweisen.
Wollten Sie dieses Array als Ergebnis einer Funktion zurückgeben, dann käme diese Routine infrage:
Function TabellenArray() As Variant Dim rs As DAO.Recordset Set rs = CurrentDb. _ OpenRecordset("tblAdressen") TabellenArray = rs.GetRows End Function
Aber schauen wir uns den Umgang mit Arrays in Funktionen einmal etwas genereller an.
Array mit Elementen füllen
Es muss nicht eine Funktion sein, wenn ein Array in einer Sub-Prozedur mit Werten gefüllt werden soll. Sie können ein Array der Prozedur auch als Argument übergeben. Die folgende Routine vollzieht das:
Sub FillArray(cnt As Long, _ arr As Variant) Dim i As Long ReDim arr(cnt) For i = 0 To cnt arr(i) = "Element " & i Next i End Sub
Für den Aufruf der Prozedur könnte man dies schreiben:
Dim arr As Variant FillArray 4, arr
Die Prozedur nimmt als Parameter die Zahl an Elementen in der Variablen cnt entgegen und dimensioniert das Array arr dann entsprechend, um es schließlich in einer Schleife mit Werten zu besetzen. Die Auswertung des so erhaltenen Arrays erfolgte ebenfalls in einer Schleife:
For i = 0 To UBound(arr) Debug.Print arr(i) Next i
Das erstaunliche an der Sache ist, dass in der aufrufenden Prozedur das Array gar nicht als solches deklariert wurde, sondern als Variant. Der Datentyp der Variablen arr steht zu diesem Zeitpunkt also noch gar nicht fest.
Dennoch lässt sich die Redim-Anweisung auf den Variant anwenden, wodurch VBA ihn automatisch zu einem Array macht, dessen Elemente ebenfalls vom Typ Variant sind. Deshalb kann in der Folge die Funktion UBound zum Ermitteln der Grenzen des Arrays angewandt werden.
In dieser Version ist die vorherige Deklaration einer Variablen, die der Prozedur übergeben wird, zwingend. Anders sieht der Fall aus, wenn, wie in Listing 1, eine Funktion fuArray zum Einsatz kommt, die als Rückgabe direkt ein Array herausrückt.
Sub Test() Dim arr As Variant arr = fuArray(4) For i = 0 To UBound(arr) Debug.Print arr(i) Next i End Sub Function fuArray(cnt As Long) As String() Dim i As Long Dim arr() As String ReDim arr(cnt) For i = 0 To cnt arr(i) = "Element " & i Next i fuArray = arr End Function
Listing 1: String-Array als Ergebnis einer Funktion fuArray
Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein: