Erstes Feld eines Arrays mittels ubound füllen

Hallo Wissende,

bei /t/excel-vba-array-verwuerfeln-und-aufteilen/5585026/2

Ich definiere/deklariere ein Array mit
Dim MeinArray()

Jetzt möchte ich in einer Schleife dieses Array befüllen.
Das versuche ich mit
ReDim Preserve MeinArray(UBound(MeinArray) + 1)
MeinArray(UBound(MeinArray)) = Chr(N)
Leider geht das schief da durch UBound(MeinArray) ein Fehler kommt,
(Index außerhalb des gültigen Bereiches)

Mit Einführung der Hilfsvariablen „Anz“ klappt es dann, siehe Code von Klappt und Klappt nicht.

Gibt es eine Variante dies auch ohne Hilfsvariable zu erreichen?

Dim MeinArray()
ReDim Preserve MeinArray(UBound(MeinArray) + 1)

klappt auch nicht, obwohl ich dann sowieso ein leeres MeinArray(0) hätte :smile:

Danke ^ Gruß
Reinhard

Sub KlapptNicht()
Dim MeinArray() As String, N As Byte
For N = 65 To 67
 ReDim Preserve MeinArray(UBound(MeinArray) + 1)
 MeinArray(UBound(MeinArray)) = Chr(N)
 MsgBox MeinArray(UBound(MeinArray))
Next N
End Sub
'
Sub Klappt()
Dim MeinArray() As String, N As Byte, Anz As Byte
For N = 65 To 67
 ReDim Preserve MeinArray(Anz)
 MeinArray(UBound(MeinArray)) = Chr(N)
 MsgBox MeinArray(UBound(MeinArray))
 Anz = Anz + 1
Next N
End Sub

Korrektur
Hallo,

ich meinte mit dem was auch nicht klappt:

Dim MeinArray( 0 )
ReDim Preserve MeinArray(UBound(MeinArray) + 1)

Gruß
Reinhard

Grüezi Reinhard

ich meinte mit dem was auch nicht klappt:

Dim MeinArray( 0 )
ReDim Preserve MeinArray(UBound(MeinArray) + 1)

Vermutlich beisst sich die Redim Preserve-Anweisung daran, dass innerhalb derselben auf das zu veränderne Array zugegriffen werden soll.

Eine andere Idee wäre es, das Array zum vornherein grösser zu erstellen, das Ganze mit einer Schleife zu bfüllen und dann am Ende auf die effektive Grösse anhand des Schleifen-Zählers zu redimeinsionieren.
Mir scheint dies performanter zu sein, als bei jedem Zugriff das Array zu erweitern.


Mit freundlichen Grüssen

Thomas Ramel

  • MVP für MS-Excel -

Moin, Reinhard,

mir scheint, Du hast ein Gemüt wie ein Schlachterhund. Wenn die Maschine dermaßen nach einer Dimension bettelt, dann gib ihr halt eine:

 Dim MeinArray()
 ReDim MeinArray(0)
 ...
 ReDim Preserve MeinArray(UBound(MeinArray) + 1)
 ... 

Dim MeinArray()
ReDim Preserve MeinArray(UBound(MeinArray) + 1)

klappt auch nicht, obwohl ich dann sowieso ein leeres
MeinArray(0) hätte :smile:

Von wegen - Du siehst hier den Unterschied zwischen Null und Nichts :smile:))

Um Ubound einzusetzen, muss das Array eine Dimension haben, und sei es die Dimension Null. Und die unterscheidet sich ganz erhebich von Nichts wie in Array().

Gruß Ralf

Hallo Ralf,

mir scheint, Du hast ein Gemüt wie ein Schlachterhund.

*aargs*, das kostet mich wieder 6 Doppelstunden bei meinem Therapeuten :smile:

Wenn die Maschine dermaßen nach einer Dimension bettelt, dann gib
ihr halt eine:

Da wird nicht nach einer Dimension gebettelt, sondern Ubound() braucht einen ersten Eintrag = Index 0 in der Arrayvariablen.

Dim MeinArray()
ReDim MeinArray(0)

ReDim Preserve MeinArray(UBound(MeinArray) + 1)

Dim MeinArray()
ReDim Preserve MeinArray(UBound(MeinArray) + 1)

klappt auch nicht, obwohl ich dann sowieso ein leeres
MeinArray(0) hätte :smile:

Von wegen - Du siehst hier den Unterschied zwischen Null und
Nichts :smile:))

Leider nein.
siehe:

Sub tt()
Dim MeinArray()
ReDim MeinArray(0)
ReDim Preserve MeinArray(UBound(MeinArray) + 1)
MeinArray(UBound(MeinArray)) = „Huhu“
MsgBox MeinArray(0)
MsgBox MeinArray(1)
End Sub

Danach hat das Array zwei Einträge, der erste ist wie gesagt leer.

Wonach mich bei meiner Anfrage gelüstetet war quasi sowas:

Dim MeinArray()
Wenn MeinArray() noch unbelegt dann Redim Meinarray(0), ansonsten Redim preserve meinArray(Ubound(meinArray) + 1)

Um Ubound einzusetzen, muss das Array eine Dimension haben,
und sei es die Dimension Null. Und die unterscheidet sich ganz
erhebich von Nichts wie in Array().

Ja.
ich denke, glaube, die Programmierer von Ubound hätten das anders machen können.
Daß die Anwendung von Ubound() auf eine zwar deklarierte aber noch nicht befüllte Arrayvariable „Minus Eins“ ergibt und keine Fehlermeldung.
Dann würde mein Ausgangscode funktionieren.

Gruß
Reinhard

Grüezi Thomas,

ReDim Preserve MeinArray(UBound(MeinArray) + 1)

Vermutlich beisst sich die Redim Preserve-Anweisung daran,
dass innerhalb derselben auf das zu veränderne Array
zugegriffen werden soll.

nein, siehe bitte:

Dim MeinArray()
MsgBox UBound(MeinArray)

Eine andere Idee wäre es, das Array zum vornherein grösser zu
erstellen, das Ganze mit einer Schleife zu bfüllen und dann am
Ende auf die effektive Grösse anhand des Schleifen-Zählers zu
redimeinsionieren.
Mir scheint dies performanter zu sein, als bei jedem Zugriff
das Array zu erweitern.

Das ist korrekt.

Gruß
Reinhard

Hallo Reinhard,

funktioniert das …

http://www.activevb.de/tipps/vb6tipps/tipp0571.html

… bei Dir?
Ich fürchte das ist VB6.

Gruß Rainer

hallo Rainer,

funktioniert das …
http://www.activevb.de/tipps/vb6tipps/tipp0571.html
… bei Dir?

ja, funktioniert:

Option Explicit
'
Private Declare Sub GetSafeArrayPointer Lib "msvbvm60.dll" Alias "GetMem4" \_
 (pArray() As Any, sfaPtr As Long)
'
Sub Command1\_Click()
Dim sfaPtr As Long, arr() As Long
GetSafeArrayPointer arr(), sfaPtr
If sfaPtr \> 0 Then
 MsgBox "dimensioniert"
Else
 MsgBox "undimensioniert"
End If
End Sub
'
Sub Command2\_Click()
Dim sfaPtr As Long, arr() As Long
ReDim arr(0)
GetSafeArrayPointer arr(), sfaPtr
If sfaPtr \> 0 Then
 MsgBox "dimensioniert"
Else
 MsgBox "undimensioniert"
End If
End Sub

Gruß
Reinhard

Grüezi Reinhard

ReDim Preserve MeinArray(UBound(MeinArray) + 1)

Vermutlich beisst sich die Redim Preserve-Anweisung daran,
dass innerhalb derselben auf das zu veränderne Array
zugegriffen werden soll.

nein, siehe bitte:

Dim MeinArray()
MsgBox UBound(MeinArray)

Ja, das klappt schon - ich meinte, dass Du in der Anweisung zur Erweiterung des Arrays auf selbiges direkt zugreifst.

Aber dieser Punkt ist ja inzwischen geklärt worden.

Eine andere Idee wäre es, das Array zum vornherein grösser zu
erstellen, das Ganze mit einer Schleife zu bfüllen und dann am
Ende auf die effektive Grösse anhand des Schleifen-Zählers zu
redimeinsionieren.
Mir scheint dies performanter zu sein, als bei jedem Zugriff
das Array zu erweitern.

Das ist korrekt.

…wenigstens das… :wink:

Mit freundlichen Grüssen

Thomas Ramel

  • MVP für MS-Excel -

Hi Reinhard,

Wonach mich bei meiner Anfrage gelüstetet war quasi sowas:

Dim MeinArray()
Wenn MeinArray() noch unbelegt dann Redim Meinarray(0),
ansonsten Redim preserve meinArray(Ubound(meinArray) + 1)

genau das habe ich doch vorgeschlagen. Zunächst mal ist das Array unbelegt, damit kannst Du eh nichts anfangen als es eben zu dimensionieren.Mit (0) hat Du doch einen definierten Zustand.

ich denke, glaube, die Programmierer von Ubound hätten das
anders machen können.

Mag sein, ist aber nicht so. Es dürfte aber auf endlos viele Konstrukte zutreffen, dass sie nicht den Erwartungen entsprechen.

Gruß Ralf

Moin Ralph,

hilf mir mal auf die Sprünge: Wie komme ich in die
Verlegenheit nachfragen zu müssen, ob ein Array dimensioniert
ist?

wenn ich wissen möchte, ob ein Array bereits Daten enthält.

Vorstellbar wäre, daß der Inhalt eines Bytearray angezeigt oder verarbeitet werden soll, in das irgendwann per Mausklick mit ‚GetBitmapBits‘ Bilddaten eingelesen werden.

Wird dann versucht Daten aus dem Array anzuzeigen liefert VB einen Fehler. Dann kann es sinnvoll sein, erst mal nachzusehen, ob da Daten sind.

Ich weiß, das Beispiel ist etwas an den Haaren herbeigezogen, aber etwas besseres ist mir gerade nicht eingefallen. :smile:

Gruß Rainer

Kumpels unter sich
Hi Rainer,

Ich weiß, das Beispiel ist etwas an den Haaren herbeigezogen,
aber etwas besseres ist mir gerade nicht eingefallen. :smile:

das wundert micht nicht. APIs zu missbrauchen, um einen Entwurfs-/Spezifikations-/Schnittstellenfehler zu verbergen ist kein Kunstfehler, sondern Sabotage.

Ein QS-Manger bei einem großen PKW-Hersteller hat mir mal erzählt, was sein größtes Problem war: Die Einstellung „Da hat mein Kumpel Schrott angeliefert, aber das kriege ich schon hin.“

Gruß Ralf