Live-Forum - Die aktuellen Beiträge
Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender

Forumthread: dynamisches Array und Dimensionen

dynamisches Array und Dimensionen
Werner
Hallo!
Angeblich kann bei einem dynamischen Array nicht das ganze Array dynamisch sein. Wenn ich z.B. ein
zweidimensionales Array habe und dies mit "Redim Preserve Ary(1 To 3, 1 To 4)" redimensioniere, kann ich dann mit "LBOUND" oder "UBOUND" nur die links in den runden Klammern stehende erste Dimension oder nur die rechts in den runden Klammern stehende zweite Dimension ermitteln?
Und wie? In obigem Beispiel z.B. mit "LBOUND(Ary, 1)" für die erste Dimension oder mit "LBOUND(Ary, 2)"
für die zweite Dimension? Für einen Hinweis wäre ich sehr dankbar, da bei einem meiner Makros (der
zum Hochladen zu kompliziert ist ) Excel bei "LBOUND" und "UBOUND" immer einen Überlauf meldet.
Werner R.

Anzeige

7
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Benutzer
Anzeige
AW: dynamisches Array und Dimensionen
01.06.2008 12:52:00
Tobias
Hallo Werner,
eigentlich hast Du schon alles richtig gesagt. Lbound(Ary,1) für die erste, Lbound(Ary,2) für die zweite Dimension.

Sub RedimArray()
Dim x() As Double
Dim i As Long, j As Long
ReDim x(2, 3)
For i = LBound(x, 1) To UBound(x, 1)
For j = LBound(x, 2) To UBound(x, 2)
x(i, j) = i * j
Next
Next
For i = LBound(x, 1) To UBound(x, 1)
For j = LBound(x, 2) To UBound(x, 2)
Debug.Print x(i, j)
Next
Next
End Sub


Und Redim geht nur für die zweite Dimension. ReDim Preserve x(3,4) verursacht in obigen Beispiel einen Fehler.
"Überlauf" deutet eigentlich darauf hin, dass ein Wert einer Variablen nicht zugewiesen werden kann. Überprüf doch mal die Werte und Datentypen in der entsprechenden Zeile. Vielleicht ist das Array ja größer als 32767 und Du weißt den Wert einer Integer-Variablen zu?
Falls Du übrigens UNBEDINGT AUCH DIE ERSTE DIMENSION ändern möchtest kannst Du ein Array mit Arrays verwenden. Ich habe das schon lange nicht mehr verwendet, aber es geht IN ETWA so. Kein Garantie für Vollständigkeit und Richtigkeit.


Sub ArrayArrays()
Dim i As Long, j As Long
Dim var1() As Variant
Dim var2() As Variant
Dim var3() As Variant
Dim var() As Variant
ReDim var1(2)
ReDim var2(3)
ReDim var(2)
var(1) = var1
var(2) = var2
For i = LBound(var) To UBound(var)
For j = LBound(var(i)) To UBound(var(i))
var(i)(j) = i * j
Next
Next
For i = LBound(var) To UBound(var)
For j = LBound(var(i)) To UBound(var(i))
Debug.Print var(i)(j)
Next
Next
ReDim Preserve var1(3)
var(1) = var1
var(1)(1) = 33
var(1)(2) = 22
var(1)(3) = 11
For i = LBound(var) To UBound(var)
For j = LBound(var(i)) To UBound(var(i))
Debug.Print var(i)(j)
Next
Next
End Sub


Anzeige
Dimensionierung noch etwas unklar
Werner
Hallo Tobias,
herzlichen Dank f. die aufschlussreichen Prozeduren, die ich sehr lehrreich finde! Unklar ist mir bloss
noch ein Detail bei der Redimensionierung:
In Deinem Beispielcode ist "x" zunächst als Arrayvariable mit leeren Klammern dimensioniert. Im Programm
folgt dann die Anweisung "Redim x(2,3)". Warum entsteht denn ein Fehler, wenn statt dieser Anweisung
"Redim Preserve (3, 4) steht?
Die Arrayvariable war vor der Anweisung "Redim x(2, 3) doch noch gar nicht
konkret dimensioniert (denn sie war ja nach "DIM" mit einem völlig leeren Klammerpaar
dimensioniert worden.
Werner R.

Anzeige
AW: Dimensionierung noch etwas unklar
01.06.2008 13:13:00
Tobias
Missverständnis. Deswegen: Das ReDim, das ich meinte, steht woanders.

Sub RedimArray()
Dim x() As Double
Dim i As Long, j As Long
ReDim x(2, 3)
For i = LBound(x, 1) To UBound(x, 1)
For j = LBound(x, 2) To UBound(x, 2)
x(i, j) = i * j
Next
Next
ReDim Preserve x(3, 4)
For i = LBound(x, 1) To UBound(x, 1)
For j = LBound(x, 2) To UBound(x, 2)
Debug.Print x(i, j)
Next
Next
End Sub


Anzeige
Redim Preserve(2, 4) also OK?
Werner
Hallo Tobias,
also würde an der Stelle, wo du jetzt "Redim Preserve(3,4)" eingefügt hast, "Redim Preserve(2, 4)"
akzeptabel sein? D.h. beim ersten "Redim" kann man die Werte offenbar innerhalb des erlaubten
Rahmens frei wählen!?
Ich glaube, so habe ich es richtig verstanden. Dank! R. Werner

Anzeige
AW: Redim Preserve(2, 4) also OK?
01.06.2008 13:26:30
Tobias
Exakt!
Gern geschehen!
Schönes Wochenende, Tobi
www.tobiasschmid.de

AW: dynamisches Array und Dimensionen
01.06.2008 13:04:00
Gerd
Hallo Werner,
aus einem 'alten' "Wort zum Sonntag" von Nepumuk.
Die letzte Dimension ist die, die ganz rechts steht.
Gruß Gerd
Um z.B. ein Array anzulegen, welches deine 16 Texte aufnehmen kann, deklarierst du erst das Feld für 16 Einträge
Dim strArray(15) As String
Die Zählung der Einträge beginnt normalerweise bei 0. Wenn du
Option Base 1
benutzt, dann bei 1. Du kannst aber die Untergrenze auch selbst angeben.
Dim strArray(5 To 20) As String
Das sind eindimensionale Arrays. Die kannst du so in einer Schleife ansprechen:

Public Sub test1()
Dim strArray(15) As String
Dim intIndex As Integer
For intIndex = 0 To 15
strArray(intIndex) = Chr$(intIndex + 65)
Next
End Sub


Eine andere Möglichkeit ein Array zu füllen wäre die Array - Funktion. Das funktioniert aber nur mit einer Variant - Variablen:


Public Sub test2()
Dim vntArray As Variant
Dim intIndex As Integer
vntArray = Array("A", "B", "C", "D", "F", "G")
For intIndex = 0 To 5
Debug.Print vntArray(intIndex)
Next
End Sub


Die bisher genannten Möglichkeiten haben aber den Nachteil, dass sie in ihrer Größe nicht änderbar sind. Das kannst du mit undimensionierten Arrays machen.


Public Sub test3()
Dim strArray() As String
Dim intIndex As Integer
ReDim strArray(3)
For intIndex = LBound(strArray) To UBound(strArray)
strArray(intIndex) = Chr$(intIndex + 65)
Next
ReDim strArray(5) 'alle Einträge gehen verloren
For intIndex = LBound(strArray) To UBound(strArray)
strArray(intIndex) = Chr$(intIndex + 65)
Next
ReDim Preserve strArray(8) 'die Einträge bleiben erhalten
For intIndex = LBound(strArray) To UBound(strArray)
strArray(intIndex) = Chr$(intIndex + 65)
Next
Erase strArray
End Sub


Hier haben wir mehrere Techniken angewendet.
1. Redim um ein Array in der Größe zu ändern, wobei alle Daten des Arrays verloren sind.
2. Redim Preserve zum umdimensionieren wobei die Daten erhalten bleiben. Das geht aber nur, wenn du die letzte Dimension eines Arrays änderst.
3. LBound um die Untergrenze und UBound um die Obergrenze der ersten Dimension zu erfahren.
4. Erase um die Eintrage eines Array zu löschen.
Das ist mal so ein grober Überblick zu eindimensionalen Arrays.....

Anzeige
Erase war mir neu!
Werner
Hallo Gerd,
Deine Erklärung war wirklich systematisch, fast lehrbuchgemäß. Herzlichen Dank!
Das meiste kannte ich zwar schon, doch dann kam der Hinweis auf "Erase". Dass das Löschen eines
Arrays so einfach geht, war mir nicht bekannt. Ich glaube, jetzt habe ich auch die Redimensionierung
zwei- und mehrdimensionaler Arrays einigermaßen begriffen.
R. Werner
Anzeige
;
Anzeige
Anzeige

Infobox / Tutorial

Dynamische Arrays in VBA effizient nutzen


Schritt-für-Schritt-Anleitung

Um ein dynamisches Array in Excel VBA zu verwenden, folge diesen Schritten:

  1. Variable deklarieren: Erstelle eine Array-Variable ohne Größe.

    Dim x() As Double
  2. Array dimensionieren: Verwende ReDim, um das Array zu dimensionieren.

    ReDim x(2, 3) ' Erstellen eines 2-dimensionalen Arrays
  3. Werte zuweisen: Fülle das Array mit Werten.

    For i = LBound(x, 1) To UBound(x, 1)
       For j = LBound(x, 2) To UBound(x, 2)
           x(i, j) = i * j
       Next j
    Next i
  4. Array wieder dimensionieren: Nutze ReDim Preserve, um das Array ohne Verlust der bestehenden Werte zu ändern, dabei darf jedoch nur die letzte Dimension geändert werden.

    ReDim Preserve x(3, 4) ' Ändert die Größe des Arrays
  5. Arraywerte ausgeben: Verwende Debug.Print, um die Werte zu überprüfen.

    For i = LBound(x, 1) To UBound(x, 1)
       For j = LBound(x, 2) To UBound(x, 2)
           Debug.Print x(i, j)
       Next j
    Next i

Häufige Fehler und Lösungen

  • Überlauf-Fehler: Dieser Fehler tritt häufig auf, wenn du versuchst, einen Wert zuzuweisen, der den Datentyp überschreitet. Überprüfe die Dimensionen und Typen deines Arrays.

  • Redim Preserve: Achte darauf, dass du nur die letzte Dimension eines Arrays mit ReDim Preserve ändern kannst. Ein Versuch, die erste Dimension zu ändern, führt zu einem Fehler.

  • LBound und UBound: Wenn du die Grenzen deines Arrays ermittelst, stelle sicher, dass das Array bereits dimensioniert ist. Ein nicht dimensioniertes Array führt zu einem Laufzeitfehler.


Alternative Methoden

Neben der Verwendung eines dynamischen Arrays gibt es auch andere Möglichkeiten:

  • Array-Funktion: Du kannst die Array-Funktion nutzen, um ein eindimensionales Array zu erstellen. Dies funktioniert allerdings nur mit einer Variant-Variablen.

    Dim vntArray As Variant
    vntArray = Array("A", "B", "C")
  • Array von Arrays: Um eine mehrdimensionale Struktur zu erstellen, kannst du ein Array von Arrays verwenden. Dies ermöglicht eine flexible Dimensionierung.

    Dim var() As Variant
    ReDim var(2)
    var(1) = Array(1, 2, 3)

Praktische Beispiele

Hier sind einige praktische Beispiele, um die Nutzung von Excel VBA dynamischen Arrays zu verdeutlichen:

  1. Einfache Berechnung mit einem 2D-Array:

    Sub SimpleArrayExample()
       Dim arr() As Double
       ReDim arr(1 To 5, 1 To 5)
       For i = 1 To 5
           For j = 1 To 5
               arr(i, j) = i + j
           Next j
       Next i
    End Sub
  2. Um eine Dimension anpassen:

    Sub AdjustArraySize()
       Dim arr() As Integer
       ReDim arr(1 To 5)
       ReDim Preserve arr(1 To 10) ' Größe ändern, Daten bleiben erhalten
    End Sub

Tipps für Profis

  • VBA LBound und UBound: Nutze LBound und UBound, um die Grenzen deines Arrays effizient zu ermitteln und Schleifen zu optimieren.

  • Verwendung von Erase: Mit Erase kannst du die Inhalte eines Arrays löschen und den Speicher freigeben.

    Erase arr
  • Dynamische Arrays und Performance: Bei der Arbeit mit sehr großen Datenmengen solltest du die Größe deines dynamischen Arrays sorgfältig planen, um die Leistung zu optimieren.


FAQ: Häufige Fragen

1. Kann ich die erste Dimension eines dynamischen Arrays mit ReDim Preserve ändern?
Nein, ReDim Preserve erlaubt nur Änderungen an der letzten Dimension eines Arrays.

2. Wie benutze ich LBound und UBound korrekt?
Du kannst LBound(Array, Dimension) und UBound(Array, Dimension) verwenden, um die Grenzen eines Arrays zu ermitteln, wobei Dimension 1 die erste und Dimension 2 die zweite Dimension bezeichnet.

3. Was passiert, wenn ich ein nicht dimensioniertes Array nutze?
Ein nicht dimensioniertes Array führt zu einem Laufzeitfehler, wenn du versuchst, LBound oder UBound darauf anzuwenden oder es mit Werten zu befüllen.

4. Wie lösche ich den Inhalt eines Arrays?
Verwende die Erase-Anweisung, um den Inhalt eines Arrays zu löschen und den Speicher freizugeben.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige