| Ein Array ( Liste, Vektor, Datenfeld, .. ) fasst mehrere Variable unter einem gemeinsamen Namen zusammen. |
Auf dieser Seite finden sie eine Zusammenstellung von Themen zur
Verwendung von Arrays in Javascript. Damit sollen bestehende Referenzen und Tutorials ergänzt werden. |
VBA
|
Visual Basic for Applications |
| Type | Typen von VBA-Arrays |
| Definition & Initialisierung | Erzeugung und Initialisierung, Geltungsbereich von Arrays |
| Eigenschaften | Type, Anzahl der Elemente eines Arrays |
| Lesen & Schreiben | Einfacher Zugriff auf Array-Elemente |
| Schleifen | Bearbeitung von Array-Elementen in Schleifen (loops) |
| Mehrdimensionale Arrays | Tabellen, Arrays in 2, 3 und mehr Dimensionen |
| Bereich | Daten-Austausch Kalkulations-Bereich ↔ VBA-Array |
| Array → Funktion | Arrays als Argumente an Unterprogramme übergeben |
| Funktion → Array | Arrays aus Funktionen zurückgeben |
| Verweise | Lookup mit Arrays |
| Push() & Pop() | Stack-Funktionen mit VBA-Arrays |
| Split() & Join() | Spalten und Zusammenfügen von 'strukturiertem Text' - Details |
| Verwandte Themen | Arrays in Javascript, Perl, PHP |
| Links |
|
Typen von VBA-Arrays |
|
|
VBA verwendet nur Arrays einheitlicher Typen, d.h. alle Elemente eines Arrays
haben den gleichen Daten-Typ. Für die Verwendung unterschiedlicher Datentypen müssen mehrere Arrays angelegt werden. |
Zur Kennzeichnung und Unterscheidung der einzelnen Elemente wird eine ganze Zahl>=0 verwendet, dafür sind die Begriffe Schlüssel und/oder Index üblich. |
Array-TypenVBA verwendet diese Standard-Typen für Variable:Boolean (True,False), Byte (1 Byte ganze Zahlen 0..255), Integer (2 Byte ganze Zahlen -32768..32767), Long (4 Byte ganze Zahlen -2147483648..2147483647), Single (4 Byte Gleitkomma-Zahlen -3.4E38..+3.4E38), Double (8 Byte Gleitkomma-Zahlen -1.8E308..+1.8E308), String (Text variabler Länge bis zu 2^31 = 2 Mia Zeichen) Arrays jeder Variablen-Type können verwendet werden, z.B. Dim i(10) As Integer
deklariert ein Array vom Type Integer, das 11 (!) einzelne Variable dieses Typs mit den
Namen i(0) bis i(10) enthält.Der Typ Date ist identisch mit Double, da VBA Datum und Zeit im Y1900-Format speichert. VBA kann auch Arrays vom Typ Date verwalten. |
Der Typ Variant kann für ganze Zahlen, Gleitkomma-Zahlen oder Texte variabler Länge verwendet werden. Der Zusammenhang entscheidet, wie eine Variant-Variable interpretiert wird, d.h. es wird nicht zwischen einem String "123" und einer ganzen Zahl 123 unterschieden. Das ist für unerfahrene EntwicklerInnen ein Vorteil. Im professionellen Bereich sollte man Variant vermeiden. Durch die unklare Interpretation werden schwer zu findende Programmier-Fehler begünstigt, außerdem benötigen Variant-Variable mehr Speicherplatz und mehr Zeit zur Verarbeitung. Alle Variable und Arrays, deren Type nicht ausdrücklich deklariert ist, werden VBA-intern als Variant geführt. Daher sind folgende Deklarationen äquivalent
Dim v(100) As Variant
Dim v(100) Auch andere spezielle Datentypen sind möglich, werden hier jedoch nicht vorgestellt. |
IndexOhne besondere Vereinbarung gilt:Das erste Array-Element trägt den Index (0), das zweite (1) usw. Der Index kann auch in anderen Zahlen-Bereichen angesiedelt werden: Dim a(100 To 200) As Integer
deklariert ein Array a mit
Index (100) bis (200)
|
Anweisung Option BaseMit der AnweisungOption Base 0
kann (am Modul-Anfang, vor dem Programmcode) vereinbart werden, dass der Index von
Arrays ohne besondere Vereinbarung bei (0) beginnt.Das ist Standard in allen gängigen Programmiersprachen. Man kann auch Option Base 1 vereinbaren, davon wird jedoch abgeraten, weil es der Praxis üblicher Programmierung widerspricht. |
Definition & Initialisierung von VBA-Arrays |
|
Option ExplicitEs wird unbedingt empfohlen, diese Vereinbarung an den Beginn jedes VBA-Programms zu stellen. Sie erzwingt die ausdrückliche Vereinbarung (Deklaration) aller Variablen und Arrays.Jeder Versuch, eine Variable oder ein Array ohne vorherige ausdrückliche Deklaration zu verwenden, wird verhindert, die entsprechende Programmzeile angezeigt. |
DeklarationDie Vereinbarung von Arrays erfolgt mit der Dim-Anweisung, gefolgt vom Array-Namen, der Dimension und der Type:Dim t(123) As String
vereinbart ein Array von Texten variabler Länge aus 124
Elementen t(0) bis t(123)Eine Vereinbarung kann auch mehrere Variable und Arrays des gleichen Typs enthalten: Dim x(100), y(100), z As Single
vereinbart die beiden Arrays x und y
sowie die (skalare) Variable z als Gleitkomma-Zahlen
geringer Genauigkeit.
|
GeltungsbereichJedes Array ist ebenso wie jede andere Variable nur innerhalb eines bestimmten Bereichs gültig.Lokale Arrays
Jedes Array, das innerhalb einer Function
oder eines Sub definiert wird, ist ausschließlich
innerhalb des betreffenden Unterprogramms gültig.
Bei Aufruf des Unterprogramms wird Speicherplatz für die darin definierten
Arrays bereitgestellt. Dabei werden die einzelnen Array-Elemente zwar automatisch
auf Anfangswerte gesetzt (z.B. Zahlen auf 0), darauf sollten sie sich jedoch nicht
verlassen. Betrachten sie die Daten als undefiniert und führen sie selbst
die Initialisierung (Festlegung der Anfangswerte) durch.Nach Verlassen des Unterprogramms wird dessen Speicherplatz freigegeben, die Daten lokaler Arrays sind daher wieder undefiniert, insbesondere bei erneutem Aufruf des gleichen Programms. Ein lokal definiertes Array kann nicht durch andere Unterprogramme verwendet werden, in anderen Unterprogrammen können Variable und Arrays mit den gleichen Namen verwendet werden. Im Beispiel rechts wird von jeder der beiden Funktionen ein Array mit dem gleichen (!) Namen definiert, trotzdem gibt es keine Kollision, da beide Arrays nur innerhalb ihrer Funktionen gültig sind. Function t_1 liefert bei jedem Aufruf das Ergebnis 33, Function t_2 immer das Ergebnis 66. Function t_3 löst einen Fehler aus, weil sie auf keines der beiden lokalen Arrays x zugreifen kann. |
Lokale VBA-Arrays
Function t_1
Dim x(10) As Integer
x(3) = 33
End Functiont_1 = x(3) Function t_2 Dim x(10) As Integer
x(3) = 66
End Functiont_2 = x(3) Fnction t_3 t_3 = x(3) ' Fehler !
End Function
|
|
Statische Arrays
sind ebenfalls nur innerhalb ihrer Function oder
ihres Sub gültig. Nach Verlassen der Unterprogramme
wird der Speicherplatz jedoch nicht freigegeben,
alle statischen Variablen und Arrays behalten daher ihre aktuellen Daten.Sie müssen daher durch geeignete Programmierung sicherstellen, dass statische Arrays bei Bedarf initialisiert werden, danach jedoch ohne Initialisierung weiter verwendet werden. Im Beispiel wird die Function t_4 als Zähler verwendet. Mit dem Wert WAHR (True) als Argument wird der Zähler initialisiert (auf die Zahl 0 gesetzt). Mit Argument FALSCH (False) wird der Wert von Array-Element (5) bei jedem Aufruf der Funktion um +1 erhöht und zurückgegeben. Jedes Element von Array x behält seinen Wert auch nach dem Ende von Funktion t_4. |
Ein statisches VBA-Array
Function t_4(init As Boolean) As Integer
Static x(10) As Integer
If init Then
End Function
x(5) = 0
Else
x(5) = x(5) + 1
End Ift_4 = x(5) |
|
Globale Arrays
werden am Modul-Anfang deklariert, d.h. vor und außerhalb
irgendeiner Function oder eines Sub.
Der Geltungsbereich umfasst das gesamte VBA-Modul, d.h. ein global definiertes Array
kann in jedem Programm, in jedem Sub und in jeder Function dieses Moduls verwendet
werden. Ein globales Array ist gleichzeitig Static, d.h. die
Array-Elemente behalten ihre Werte unabhängig von Unterprogramm-Aufrufen.Von anderen Modulen ist kein Zugriff möglich. Im Beispiel erfolgt die Initialisierung durch Aufruf der Function t_5, während Function t_6 als Zähler dient. Das globale Array y wird innerhalb der Funktionen nicht mehr definiert ! Function t_7 verwendet ein eigenes lokales Array mit dem gleichen Namen. Das ergibt keine Kollision, d.h. VBA verwendet das globale Array y für die beiden Functions t_5 und t_6, das lokale Array y für Function t_7 (die immer den Wert 777 zurückgibt). Das ist schlechter Programmier-Stil - man sollte unterschiedliche Namen verwenden, um Verwechslungen zu vermeiden - Das Beispiel dient lediglich zur Demonstration der Reichweite von Array-Deklarationen. |
Ein globales VBA-Array
Dim y(10) As Integer
Function t_5() As Integer
y(7) = 0
End Functiont_5 = y(7) Function t_6() As Integer
y(7) = y(7) + 1
End Functiont_6 = y(7) Function t_7() As Integer Dim y(10) As Integer
y(7) = 777
End Function
t_7 = y(7) |
| Vorteil einer globalen Deklaration ist die Verwendbarkeit in allen Programmteilen eines Moduls. Insbesondere braucht man solche Arrays weder an Unterprogramme übergeben noch von ihnen zurückgeben. Das ist sinnvoll, wenn die Elemente solcher Arrays von mehreren Programmteilen bearbeitet werden. | Nachteil der globalen Deklaration ist die geringere Übersicht sowie der größere Bedarf an Speicherplatz. Deklarieren sie so wenige Arrays wie möglich global, aber verwenden sie diese Möglichkeit gezielt für solche Daten, die tatsächlich die allgemeine Daten-Grundlage eines Moduls darstellen. |
Array-AnweisungMit der Array-Anweisung wird ein Array der Type Variant definiert und initialisiert, d.h. es werden Anfangswerte in alle Elemente eingetragen.Die Array-Anweisung kann sowohl für lokale als auch für globale Arrays verwendet werden, jedoch leider nicht für Arrays anderer Typen als Variant. |
a = Array(10,20,30)
wotag = Array("Mo", "Di", "Mi", "Do", "Fr", "Sa", "So") |
Dynamische Dimensionierung, LöschenMit der Redim-Anweisung ist es möglich, die Größe jedes Arrays nachträglich zu ändern. Im Beispiel wird das Array b zunächst ohne Elemente deklariert. Zu einem späteren Zeitpunkt wird die Redim-Anweisung ausgeführt, damit werden 100 Elemente b(0) bis b(100) reserviert.Achtung - Nach Redim sind die Werte aller Array-Elemente undefiniert, bzw. werden die vorhandenen Werte der Elemente durch Redim zerstört. Anweisung Erase löscht die Werte aller Elemente eines Arrays, gibt allerdings normalerweise keinen Speicher frei. Um den Speicher freizumachen (bei großen Arrays wichtig !) führt man Redim b (0) aus. |
Dim b() As Double
Redim b(100) Erase b Redim b(0) ♣ Tipp: Im Kapitel → Push() & Pop() auf dieser Seite wird gezeigt, wie man die Dimension eines Arrays ändert und dabei dessen Daten bewahrt. |
Schleifen & Arrays |
|
|
Eine Schleife (loop) ist die häufigste Methode zur Verarbeitung von Arrays. Das Beispiel zeigt eine typische Initialisierung, d.h. das Schreiben von Anfangswerten in jedes Array-Element. Beachten sie die Funktionen LBound und UBound (s.oben), mit denen man die Länge eines Arrays feststellen kann. Die For-Next-Schleife ist praktisch, da der Schleifen-Zähler (hier i ) gleichzeitig als Array-Index dienen kann. ♦ Details zur Programmierung von Schleifen in VBA |
Dim i As Integer
Dim z(1000) As Double For i = 0 To 1000 z(i) = i * i
Next i
|
|
Eine besondere Variante ist die For-Each-Next-Schleife:
Sie verwendet keinen (!) Index, sondern kopiert in jedem Durchgang ein Element
des Arrays (hier z ) an die Schleifen-Variable
(hier d ) vom gleichen Typ wie das Array. Vorsicht: Man kann die Schleifen-Variable zwar lesen und fehlerfrei verarbeiten, eine Änderung dieser Variablen wirkt sich jedoch nicht auf die Array-Elemente aus ! |
Dim d, z(10) As Double
For Each d In z
MsgBox "d=" & d
Next
d = d + 1 ' Readonly ! |
Datei I/O und ArraysNatürlich kann man Arrays so wie andere Variable beim Lesen und Schreiben von Dateien verwenden - in diesem Fall meist in Schleifen.● Wesentlich schneller ist es jedoch, die Funktionen Put und Get ohne Schleife zu verwenden, so wie im Beispiel gezeigt: Das Array a wird mit einer einzigen Get oder Put-Anweisung gelesen bzw. geschrieben. ♦ Details zum Lesen und Schreiben von Dateien mit VBA. |
Dim a(1000), fh As Integer
fh = FreeFile Open "C:\test.dat" For Binary As fh Put #fh, , a Close fh |
Stack-Funktionen: Push() und Pop() |
|
| VBA bietet keine Standard-Funktionen für die Verwendung von Arrays als Datenspeicher der Type Stack (Stapel) | Hier wird vorgestellt, wie man diese Funktionen ersetzen kann. |
|
Die hier gezeigten Beispiele verwenden Arrays der Type String
zur Simulation eines Stack-Speichers Das Muster rechts zeigt, wie man den Stack verwenden kann: • Mit array_string_pop() wird das letzte Element aus dem Array entnommen und als Ergebnis der Funktion zurückgegeben. • Mit array_string_push() wird ein neues Element an das Array angefügt. Die Funktion gibt die neue Obergrenze ( UBound ) als ganze Zahl zurück. Beide Funktionen entsprechen nicht ganz jenen der modernen Programmiersprachen: • Wenn das Array nur 1 Element hat, dann wird mit array_string_pop() lediglich dessen Inhalt gelöscht, nicht das Element selbst. Das Element bleibt als leerer String erhalten. • Umgekehrt wird mit array_string_push() der neu einzutragende String in das 1. Element eingetragen, wenn es nur dieses Element gibt und wenn es einen leeren String enthält. |
Visual Basic (VBA) Beispiel zur Anwendung der Stack-Funktionen:
Dim i As Integer
ergibt das Array sa mit den Elementen
Dim s, sa() As String ReDim sa(4) For i = 0 To 2 sa(i) = Chr(i + 65)
Next
"A","B","C"
Abtragen des Stacks mit
s = array_string_pop(sa)
ergibt das abgetragene Element s="A"
und das kürzere (!) Array
"A","B"
Aufschichten des Stacks mit
i=array_string_push(sa,"zzz")
ergibt die neue Obergrenze i=2 und das
längere (!) Array
"A","B","zzz"
|
|
Die Funktion erhält das Array a (genauer: einen
Pointer auf das Array) als Argument Die Verkürzung eines Arrays ist jedoch nicht trivial. Der maximale Index des Arrays wird mit Funktion UBound() ermittelt und in der Variablen iub gespeichert. Wenn das Array keine Elemente enthält, dann tritt dabei ein Fehler auf. Der Wert des letzten Elements a(iub) wird an die Variable a0 zugewiesen und mit dieser am Ende der Funktion zurückgegeben. Das Array b wird als Zwischenspeicher dimensioniert. Alle Daten mit Ausnahme des letzten Elements von a nach b kopiert. Das Original-Array a wird neu dimensioniert. Zuletzt werden die Daten aus dem Zwischenspeicher b in das (nun verkürzte) Array a kopiert. • Sonderfall: Wenn das letzte Element entnommen wurde, dann wird das Array a gelöscht. • Sonderfall: Wenn das Array keine Elemente (mehr) enthält, dann wird in dieser Version ein leerer String zurückgegeben. |
Diese Visual Basic (VBA) Funktion
schichtet das letzte Element eines Stack-Arrays ab:
Function array_string_pop(a) As String
Dim i, iub As Integer Dim a0, b() As String
On Error GoTo aspe
aspe:
iub = UBound(a) a0 = a(iub) If iub > 0 Then
ReDim b(iub - 1)
Else
For i = 0 To iub - 1 b(i) = a(i)
NextReDim a(iub - 1) For i = 0 To iub - 1 a(i) = b(i)
Next
Erase a
End Ifarray_string_pop = a0 Exit Function array_string_pop = ""
End Function
|
|
Die Funktion erhält als Argumente das Array a
(genauer: einen Pointer auf das Array) und das neu aufzuschichtende
Element anew Der maximale Index des Arrays wird mit Funktion UBound() ermittelt und in der Variablen iub gespeichert. Das Array b wird als Zwischenspeicher dimensioniert, und das neue Element mit dem Wert anew eingetragen. Danach werden alle Daten von a nach b kopiert, allerdings um eine Index-Position nach 'oben' versetzt. Das Original-Array a wird neu dimensioniert. Zuletzt werden die Daten aus dem Zwischenspeicher b in das (nun verlängerte) Array a kopiert. • Sonderfall: Wenn das erhaltene Array a nur 1 Element enthält, und wenn dieses einen leeren String enthält, dann wird kein neues Element erzeugt, sondern die Daten anew in das erste Element übertragen. Diese Programm-Teil ist nicht notwendig, sondern wurde eingeführt, um die Symmetrie zur ↑ Funktion array_string_pop() herzustellen. |
Diese Visual Basic (VBA) Funktion
schichtet ein neues Element auf ein Stack-Array:
Function array_string_push(a, anew As String) As Integer
Dim i, iub As Integer Dim b() As String
On Error GoTo aspe
aspe:
iub = UBound(a) ReDim b(iub + 1) For i = 0 To iub b(i) = a(i)
Nextb(iub + 1) = anew ReDim a(iub + 1) For i = 0 To iub + 1 a(i) = b(i)
Nextarray_string_push = iub + 1 Exit Function
ReDim a(0)
End Function
a(0) = anew array_string_push = 0 |
Strukturierte Texte und Arrays: Split() & Join() |
|
|
In der Informatik trifft man gelegentlich auf strukturierte Texte jener Art,
bei welcher einer unterschiedliche Anzahl von Einzelteilen durch spezielle
Trennzeichen getrennt bzw. verbunden ist. Typische Beispiele sind Web-Adressen, IP-Adressen, Datei-Pfade, ... |
Eine eigene Seite
stellt VBA-Funktionen zu diesem Thema vor, die sowohl mit Kalkulations-Programmen
(LibreOffice, OpenOffice, MS-Excel, ...) als auch mit VBA verwendbar sind.
Spezielle Beispiele: Spalten und Zusammenfügen von 'Sätzen' (aus Worten),
IP-Adressen, Datei-Pfaden, Internet-Adressen, Datum & Zeit, usw. ♦ Details zu Split() und Join() |
Funktion Join()verknüpft ein Array der Type String (im Beispiel sa) zu einem einzelnen String.Diese Funktion eignet sich zum Aufbau systematisch strukturierter Strings. Die Beispiel-Funktion kann man in jedem Kalkulations-Programm (LibreOffice, OpenOffice, MS-Excel, ...) verwenden. Der Inhalt der mit bereich angegebenen Zellen wird mit dem als join_char bezeichneten Zeichen zu einem Text verknüpft. Beispiel:
Die Zellen A1..C1 enthalten die
Texte a,b,cDie Formel =pst_join(A1:C1;"#") ergibt "a#b#c" |
Function pst_join( _
bereich As Range, _
Dim i, imax As IntegerOptional join_char As String = "") As String Dim sa() As String
imax = bereich.Count
End Function
ReDim sa(imax - 1) For i = 1 To imax sa(i - 1) = bereich(i).Value
Nextpst_join = Join(sa, join_char) |
Funktion Split()zerlegt einen systematisch strukturierten String in ein Array der Type StringEin String (hier s ) wird an allen Stellen zerlegt, die einen 'Delimiter'-String (Trennzeichen, z.B. das Zeichen "#") enthalten. Dabei werden alle Trennzeichen entfernt. Die Beispiel-Funktion kann man in jedem Kalkulations-Programm (OpenOffice Calc, MS-Excel, ...) verwenden, um ein einzelnes Element eines strukturierten Strings zu isolieren. Beispiel:
Zelle A2 enthält den
Text a#b#c Die Formel =pst_split(A2;"#";2) gibt das 2.Element "b" zurück. |
Function pst_split( _
text As String, _
Dim sa() As String
separator As String, _ index As Integer) As String
If index <= 0 Or index > 100 Then
End Function
pst_split = text
Else
sa = Split(text, separator)
End If
pst_split = sa(index - 1) |
|
|
| ● Visual Basic 2005 Handbuch (Andreas Kühnel / Galileo) - Grundlagen der Sprach-Syntax / Arrays, .NET-Arrays | |
|