Erläuterung ByVal und Byref
Hallo Wilhelm,
anbei noch schnell eine Erklärung
ByRef-Parameter
Eine Parameter-Übergabe „By Reference“ bedeutet, dass die Adresse der übergebenen Variable an die Prozedur übergeben wird. Die Prozedur kann dadurch auf den Originalwert der Variable operieren, und daher auch den Inhalt ändern.
Gekennzeichnet wird ein solcher Parameter durch das Schlüsselwort ByRef. Bis einschließlich VB6 ist dies übrigens die Default-Methode der Parameter-Übergabe, daher kann die Deklaration aus obigem Beispiel auch so geschrieben werden:
Function Beispiel(ByRef n As Long) As Long
Ich empfehle dringend, dieses Schlüsselwort zu nutzen. Einerseits wird die Art der Parameter-Übergabe besser Dokumentiert, d.h. der Anwender der Prozedur ist „vorgewarnt“, dass sich eventuell die Inhalte seiner Parameter-Variablen ändern können. Andererseits wird ab VB7 (VB.NET) die Default-Methode „By Value“ sein!
Wichtiger Hinweis: Da bei Nutzung von „By Reference“ nur Adressen bewegt werden, müssen die Datentypen der Übergabe-Variablen und des Parameters exakt übereinstimmen. Dies wird von VB streng kontrolliert (Fehlermeldung 13, „Type mismatch“) und zwar vor dem Aufruf, da ansonsten „Allgemeine Schutzverletzungen“ die Folge wären (Weitere Gründe für Variablen-Deklarationen: „Pfui oder Hui? - Schöner programmieren!“).
ByVal-Parameter
Bei einer „By Value“ Parameter-Übergabe erzeugt VB erst eine komplette Kopie des Parameter-Werts. Die Prozedur operiert also immer auf eine Kopie des Parameters, der Originalwert der Variablen ist also sicher vor Veränderungen.
Gekennzeichnet wird ein solcher Parameter durch das Schlüsselwort ByVal. Ändern wir die obige Parameter-Deklaration auf „By Value“, also
Function Beispiel(ByVal n As Long) As Long
Wichtiger Hinweis: Objekt-Variablen enthalten intern sowieso nur einen Zeiger auf das Objekt. Daher ist es egal, welche Methode hier zur Parameter-Übergabe verwendet wird: Die Eigenschaften des Objekts sind in der Prozedur immer änderbar.
Tipps zur Verwendung
Da ByVal erst eine Kopie der Parameter macht, ist diese Methode sicher vor unerwünschten Nebenwirkungen. Allerdings kostet das Kopieren Zeit, insbesondere bei umfangreichen Parametern (z.B. langen Strings). Daher empfehle ich die Nutzung von ByRef aus folgenden Gründen:
Der Parameter muss verändert werden können, da er einen Rückgabewert liefern soll.
Es werden (lange) Strings übergeben. (Ausnahme: In der Prozedur wird sowieso eine Kopie des Strings benötigt, siehe Beispiel.)
Der Parameter ist eine Objekt-Instanz.
Die Nutzung von ByRef zur Beschleunigung der Parameter-Übergabe bei einfachen Datentypen wie z.B. Long ist sinnlos, da in diesen Fällen die Kopie (hier 4 Bytes) nicht größer ist, als die zu bewegende Adresse (immer 4 Bytes)! Dieses gilt im Wesentlichen auch für die anderen Datentypen (Integer, Single, …).
Hinweis: Sie können einen „By Reference“-Parameter beim Aufruf durch einfache Klammerung der zu übergebenen Variable in einen „By Value“-Parameter umwandeln. Im folgenden Beispiel ist x sicher vor jeder Veränderung, d.h. egal wie die Funktions-Parameter deklariert sind, der Aufruf verhält sich wie bei ByVal:
Function Beispiel((n)) As Long
VLG Alex