PDA

Vollständige Version anzeigen : paramarray bzw. Übergabe eines array an Sub


Heiopei
18.02.2003, 14:51
Hallo liebe Leute,

da außer von Thomas (Lob!Lob!Lob!) ja nicht besonders viel Resonanz zu meiner kleinen Knobelaufgabe (http://www.ms-office-forum.net/forum/showthread.php?s=&threadid=86451) kam, muß ich die Drecksarbeit wieder mal allein machen. :bawling:


Wichtigstes Element einer Rekursion ist ja nun mal der rekursive Aufruf, und an dem scheitere ich bereits, denn ich schaff es nicht der nächsten Rekursionsgeneration einen array zu übergeben.
Im unten angeführten-code-Beispiel habe ich versucht per paramarray einen flexiblen array anzuhängen. Mir würde auch ein simpler eindimensionaler array völlig reichen. Aber ein array sollte es schon sein,
einzelne Parameter einzugeben wäre nicht so günstig, da das ganze ja ein bisserl dynamisch sein soll.

Hier das nicht funktionierende Code-Beispiel:

(Typen unverträglich)

<div><link href="http://www.ms-office-forum.net/forum/externals/codeconv.css" rel="stylesheet"><pre>
<span class="TOKEN">Public Sub</span> aufruf()
<span class="TOKEN">Dim</span> test <span class="TOKEN">As</span> Variant
&nbsp;
test = &quot;2,5,2,3,6&quot;
<span class="TOKEN">Call</span> subRekursionssuche2(test)
&nbsp;
<span class="TOKEN">End</span> <span class="TOKEN">Sub</span>
<span class="TOKEN">Public Sub</span> subRekursionssuche2(<span class="TOKEN">ByVal</span> lngGeneration <span class="TOKEN">As</span> Long, <span class="TOKEN">ParamArray</span> arrayKontrolle() <span class="TOKEN">As</span> Variant)
&nbsp;
arraygroesse = <span class="TOKEN">UBound</span>(arrayKontrolle) - <span class="TOKEN">LBound</span>(arrayKontrolle) <span class="REM">'array beginnt bei 0</span>
&nbsp;
<span class="TOKEN">Debug.Print</span> arraygroesse
<span class="TOKEN">Debug.Print</span> <span class="TOKEN">UBound</span>(arrayKontrolle)
<span class="TOKEN">Debug.Print</span> <span class="TOKEN">LBound</span>(arrayKontrolle)
&nbsp;
<span class="TOKEN">End</span> <span class="TOKEN">Sub</span></pre></div>

Kann mir da jemand helfen ??

Liebe Grüße
Heie

hm001
18.02.2003, 15:04
Hallo,

der Fehler 'Typen unverträglich' erscheint, weil Du ein Array übergibst, aber ein Long-Wert (lngGeneration) erwartet wird.

Versuch mal folgendes, sollte so eigentlich funktionieren.

Public Sub aufruf()
Dim test As Variant

test = Array(2, 5, 2, 3, 6)
Call subRekursionssuche2(1, test)

End Sub

Public Sub subRekursionssuche2(ByVal lngGeneration As Long, arrayKontrolle As Variant)
Dim arraygroesse
arraygroesse = UBound(arrayKontrolle) - LBound(arrayKontrolle) 'array beginnt bei 0

Debug.Print arraygroesse
Debug.Print UBound(arrayKontrolle)
Debug.Print LBound(arrayKontrolle)

End Sub

Gruß
Holger

Heiopei
18.02.2003, 15:19
Stimmt!
Danke für die schnelle Hilfe, Holger.

Der erste Wert der variable test, sollte ja die Integervariable bedienen und der Rest den array auffüllen.

Kann das irgendwie gehen?


Liebe Grüße
Heie

erwin
18.02.2003, 15:28
hier mal eine sinnlose Rekursion mit Übergabe eines Arrays als Beispiel:

Public Sub rekurs(pArr() As Long)
pArr(1) = pArr(1) - 1
pArr(2) = pArr(2) - 1
Debug.Print pArr(1)
If pArr(1) > 0 Then Call rekurs(pArr())
End Sub
'
Public Function testr()
Dim hArr(20) As Long
hArr(1) = 20
hArr(2) = 50
Call rekurs(hArr())
End Function


so long Erwin...

Heiopei
18.02.2003, 16:41
Hallo erwin,

das mit dem paramarray war ja auch nur der tatsache geschuldet, daß ich den array innerhalb der sub-deklaration nicht dimensioniert bekam.
Aber siehe da!
Das ist gar nicht nötig.

Danke Erwin,
damit müßte ich eigentlich weiter kommen...:):)


Liebe Grüße
Heie

Sascha Trowitzsch
18.02.2003, 16:48
Naja, man könnte es auch undimensioniert (dyamisch) Public bzw. Private im Modul deklarieren (statt 20) und mit Redim Preserve jeweils nachdimensionieren. Falls nötig.

Heiopei
18.02.2003, 20:52
@sascha:
Und wie geht das genau?


Bei mir kommt eine Fehlermeldung: Unveränderlich oder gerade gesperrt,
ich nehme an, meine erstdeklaration hat Mängel

ReDim Preserve arraykontrolle(arraygroesse + 1)

Liebe Grüße

Heie

Aquarii
18.02.2003, 21:59
Hallo Heie,

ein dynamisches Array wird mit folgender Syntax z. B. als String

Dim strFeld () as String

deklariert. Damit wird vorgegeben, daß ein Datenfeld strFeld existiert, aber es wurde noch kein Speicherplatz reserviert.

Mithilfe von "ReDim" wird der Speicherplatz dann belegt:

Dim intAnzahl as integer
intAnzahl = InputBox ("Anzahl eingeben:")
ReDim strFeld (intAnzahl)

Bei einer späteren Erweiterung des Datenfeldes kann erneut ReDim verwendet werden. Aber Achtung, bei Nichtverwendung von Preserve gehen alle bisherigen Inhalte verloren.

Syntax: ReDim Preserve strFeld (100)
erhält die Inhalte des dynamischen Arrays.

Heiopei
18.02.2003, 22:36
Hallo Heiko,
danke für Deine Erläuterungen.

Bei mir fällt die eigentliche Dim-Zeile weg, weil ich das array by val aus dem Prozeduraufruf übernehme:
Public Sub subRekursionssuche(ByVal lngGeneration As Long, arraykontrolle() As Long)

Wenn das der Grund ist, daß es nicht geht, dann geht´s halt nicht und ich muß mit statischen arrays arbeiten, was auch nicht so schlimm ist und wahrscheinlich auf lange Sicht sogar etwas schneller, weil die Zeit für redim wegfällt.

Ich würd nur gern wissen, ob´s daran liegt?


Liebe Grüße
Heie

Aquarii
18.02.2003, 22:54
Hallo Heie,

versuche mal die Definition des dynamischen Arrays im Modulkopf und mache es so im gesamten Modul verfügbar. Vielleicht funktioniert es dann mit ReDim. :rolleyes:

Heiopei
18.02.2003, 23:06
Fieserweise arbeite ich mit rekursion und da habe ich dann etwa 8-15 Instanzen der Prozedur gleichzeitig am Wickel. Deshalb kann ich die nicht im Modulkopf dimensionieren.

Ich bin mittlerweile sowieso schon bei den dynamischen arrays angelangt. Dabei fiel mir aber auf, daß die sich nicht mit einer variable dimensionieren lassen
e = AnzahlLose + 1
Dim arraykontrolle(0 To e) As Long ging zum Beispiel nicht.

Erst mit

Dim arraykontrolle(0 To 10) As Long

lief der Laden.

Oder muß die Variable von einem bestimmten Typ sein, der nicht integer heißt?

Liebe Grüße

Heie

Aquarii
18.02.2003, 23:22
Hallo Heie,

Dim arraykontrolle(0 To 10) As Long

Du definierst IMHO da kein dynamisches Array. (siehe oben meinen Beitrag)

Und was bedeutet das "To" in Deinem Ausdruck? Das ist mir bisher noch nicht untergekommen.

Nouba
18.02.2003, 23:54
Hallo Heie

versuche es mal mit

e = AnzahlLose + 1
'
Dim arraykontrolle() As Long
Redim arraykontrolle(e)

die Arraygröße beträgt bei bei voreingestelltem Option Base 0 e + 1 Elemente, bei Option Base 1 ist sie um eins kleiner.