Hallo Sven,
wenn du in der Argumentenliste einer Prozedur das Argument nicht ausdrücklich als Nichtrückgabewert (z.B. mit ByVal) deklarierst, ist er sowohl Eingabe- als Rückgabewert. Für die Bezeichnung ist nicht der Name der Variablen, sondern ihre Stellung in der Argumentenliste relevant. Beispiel:
Sub M1()
a = 5: b = 10
M2 a, b, c 'liefert 35 (5^2+10)
MsgBox c
'Beachte, dass hier a,b,c sowohl Ein- und Ausgabewert ist, a ist jetzt 25 (wegen d=d*d, d auf Position
'von a) , b 10!
M3 a, b, c 'liefert 25, also den Wert von a, weil d zwar im M3 andere Werte annehmen, aber als Rückgabewert nicht verändert werden kann
MsgBox a
End Sub
Sub M2(d, e, a) 'beachte: a hat eine andere Bedeutung als in M1
d = d * d
a = d + e
End Sub
Sub M3(ByVal d, e, c)
d = d * d
d = d + e
End Sub
Gruß
Holger
Sven schrieb am 24.03.2008 01:07:23:
Hallo Holger,
danke für die ausführliche Antwort.
Das mit der Übergabe ist ja dann so, wie in vielen anderen Programmiersprachen, oder zumindest so ähnlich.
Wenn ich jetzt aber im Hauptprogramm mehrere Durchläufe habe, von Prozedur 2 und 3. Prozedur 1 (erstellt Arry), Prozedur 2(verändert Arry) und Prozedur 3(verändert Arry) muss ich doch Arry global deklarieren, da ich Arry von Prozedur 2 nicht in Prozedur 3 bekomme oder? Das gleiche Problem tritt ja schon bei der Übergabe von 1 nach 2 auf. Ich könnte 2 in 1 aufrufen und 3 in 2, aber bei der Rückgabe von 3 nach 2 kann ich bei einer Funktion nur ein Wert zurückgeben und bei eienr Prozedur gar nichts.
Wüsstest du da eine Möglichkeit?
Grüße,
Sven
Holger schrieb am 23.03.2008 14:12:15:
Hallo Sven,
sei Arry(i,j) dein Array. Du kannst mit Dim Arry() das Array deklarieren. Mit ReDim Array(0,0) werden die Werte zurückgesetzt. Mit ReDim Preserve Array(a,b) wird das array ggf. erweitert, ohne dass die bisher gespeicherten Werte verloren gehen, wobei nur der letzte Index verändert werden kann. Sieh auch in die VBA-Hilfe.
Ich habe kein grundsätzliches Problem mit globalen Variablen. Aber überlege, ob nicht eine Private-Deklaration ausreicht. Du solltest keinen Allerweltsnamen verwenden, weil du sonst in Deklarationskonflikte bei anderen Makros kommen kannst. Ich setze große Arrays am Ende des Programms mit ReDim Arry(0,0) oder Erase Arry zurück.
Du kannst natürlich auch die Variablen an andere Prozeduren übergeben. Bei Arrays kannst du optional leere Klammern setzen oder einfach den Arraynamen verwenden. Bei Funktionen macht es Sinn, wenn aus den Array-Werten ein neuer Wert berechnet werden soll. Die Übergabe als Argument erfolg genauso.
sub Name (a()) oder sub Name (a)
...
end Sub
Aufruf der Prozedur in einer anderen mit
Name Arry() oder Name Arry
Ober- und untere Grenzen des übergebenen Array stellst du mit LBound und UBound fest.
Ich hoffe, dir geholfen zu haben
Holger
Sven schrieb am 22.03.2008 17:55:32:
Hallo Makro-Experten,
hätte da mal eine Frage.
Ich habe eine Schleife in der ein zweidimensionales Array beschrieben wird. Ich weiss vorher nicht wieviel Zeilen es hat aber wieviele Splaten. Und in jeden Schleifendurchlauf soll es geändert werden, also neue Inhalte eingefügt werden.
Da ist nun meine Frage wie ich dieses Array am besten deklariere und wieder am Schleifenanfang die Inhalte lösche?
Ich hatte hier zuerst über die Nutzung von Redim nachgedacht, aber in der Hilfe dann gelesen, dass redim nicht zum deklarieren beutzt werden soll. Ebenso muss man ja bei redim die Größe des Array angegeben. Wie kann ich wenn ich freie Arrayplätze habe effizient nur auf die belegten Felder zugreifen, nur mit einer Überprüfung emptycell oder so was?
Eine zweite Frage: Ich habe ein großes "Hauptarray" was verschiedene Prozeduren durchläuft. Man soll ja eigentlich kaum globale Variablen benutzen und immer im Prozeduraufruf Variablen übergeben. Macht dies wenn ich in jedem Unterprogramm dieses Hauptarray z.B.Array(100,10) ändere überhaupt Sinn und ist es überhaupt möglich, da Funktionen ja nur ein Wert zurückgeben?
Grüße, Sven |