Office: Unterschied Public zu Parameter Übergabe ByRef / ByVal

Helfe beim Thema Unterschied Public zu Parameter Übergabe ByRef / ByVal in Microsoft Excel Hilfe um das Problem gemeinsam zu lösen; Hallo! Ich hätte einmal gern gewusst, was der genaue Unterschied bei einer Parameter Übergabe im Hintergrund ist. Ich kann eine Variable via Public... Dieses Thema im Forum "Microsoft Excel Hilfe" wurde erstellt von andysmith, 22. November 2011.

  1. andysmith Erfahrener User

    Unterschied Public zu Parameter Übergabe ByRef / ByVal


    Hallo!

    Ich hätte einmal gern gewusst, was der genaue Unterschied bei einer Parameter Übergabe im Hintergrund ist.
    Ich kann eine Variable via Public überall verfügbar machen, genauso wie diese Variable als Parameter an die Function bzw. Sub mit übergeben. Was wird wie verwendet und wie wird der Speicher damit "unnötig vollgepumpt".
    Über ByRef übergebe ich ja die Adresse der Variable wärend über ByVal der Wert übergeben wird. Beide Varianten benötigen aber zu diesem Zeitpunkt eigentlich den doppelten Speicherplatz im Arbeitsspeicher, das ich wiederum über die Public Definition umgehe.
    Mir geht es hier um die Definition der Strukturen und die Effektivität dessen.
    Eine Nebenfrage in der Sache, wird der Speicherbereich der Variablen in einer Funktion durch "End Function" prinzipiell gelöscht oder sollte man das auch hier immer tun (Bsp Range, Objekte etc.) Würde hier also eine Funktion mehrfach aufgerufen werden (Rekrusiv), dann wäre nach einer Weile mein Arbeitsspeicher eigentlich zig mal mit ein und der selben Variable besetzt.

    Vielen Dank für die Antworten
     
    andysmith, 22. November 2011
    #1
  2. miriki Erfahrener User
    Ganz pauschal: "public" Variablen sind böse. ;-)
    Genauso pauschal: "public" Variablen sind bequem.
    Und die Wahrheit liegt irgendwo dazwischen...

    Naja, relativ simpel: Je mehr "public" etwas ist, desto zumindest dauerhafter wird der Speicher davon belegt. Andererseits wird auch kein Verwaltungsaufwand weiter fällig, außer der ersten Initialisierung beim Öffnen der Mappe.

    Ähm, nein, zumindest wenn ich Dich richtig verstehe...

    Stell Dir ein Array(9,19) mit String(29) vor. Das ganze belegt im Speicher 10*20*30 Bytes (bei "option base 0" und wenn man an das Längenbyte in Strings denkt).

    Übergibst Du dieses Array "byval" an eine procedure/function, dann werden bei jedem Aufruf 6000 Bytes kopiert. Übergibst Du es "byref", wird nur ein Pointer von 4 Bytes generiert. Der Nebeneffekt ist, daß Änderungen sich aber direkt auf das Original durchschlagen, weil eben nicht mit einer (lokalen) Kopie gearbeitet wird.

    Benutzt Du das Array als "public" Variable, brauchst du ggf. nicht einmal den Pointer übergeben, wenn die Routine eh weiß, mit welcher Variablen sie arbeiten soll.

    Das ist eine Frage der Situation. Für Geschwindigkeit und Speicherverbrauch sind "byref" pauschal besser. Da eine "function" pauschal erstmal nur einen einzelnen Rückgabewert liefern kann (dabei laß ich mal benutzerdefinierte Typen außer Acht), ist "byref" auch eine gute Möglichkeit, mehrere Rückgabewert zu bekommen. Z.B. kann eine function den x und y Wert einer Funktion in den "byref" aktualisieren, während der Rückgabewert der function selbst ein Boolean sein könnte, der über Erfolg oder Mißerfolg der Berechnung berichtet.

    Hmmm... Tricky...

    Prinzipiell wird der Speicherbereich am Ende freigegeben, wenn es nicht vorher bereits manuell geschehen ist. Es gibt eine Anweisung, die das aber verhindern kann, womit Variablen beim nächsten Aufruf der Routine ihren vorherigen Wert behalten. Ich komm nur gerade nicht drauf, wie das Wort dafür heißt. Könnte irgendwas im Umfeld von "static" sein.

    Das ganze geht aber noch einen Schritt weiter... Der Aufruf einer Routine erzeugt einen kompletten Block im Speicher, der für eben die lokalen Variablen der Routine benutzt werden kann. Selbst, wenn Du die einzelnen Variablen wieder freigibst, so bleibt der Block als solches immer noch so lange reserviert, bis die Routine beendet wird. Das Freigeben der Variablen sorgt nur dafür, daß der Platz innerhalb des Blocks für andere Variablen frei wird. Ich weiß jetzt nicht, ob es da noch eine Beschränkung in VBA gibt und wie hoch die angesetzt ist. Aber mein altes Pascal-Gedenke erinnert mich immer wieder daran, daß für lokale Variablen (wie für globale übrigens auch) nur jeweils 64k Speicher pro procedure / function zur Verfügung standen.

    Bei Rekursionen (wenn Du die wirklich meintest, und nicht doch Iterationen...) wäre es aber ziemlich fatal, die Variablen zu löschen, nur weil ich eine Rekursionsebene tiefer gehe. Denn schließlich komme ich aus der tieferen Ebene ja auch wieder eine zurück hoch und will dann da weiter machen, wo ich quasi unterbrochen wurde. Und Rekursionen sind auch der zwingende Grund, nicht mit "public" Variablen zu arbeiten.

    Beispiel - Durchsuchen der Festplatten-Struktur: Variable "pfad" wird mit "C:\" initialisiert und die Routine aufgerufen. Die Routine listet alle im "pfad" vorhandenen Dateien auf und ruft sich selbst rekursiv auf, wenn der Eintrag keine Datei, sondern ein Unterverzeichnis ist. Dabei wird der ursprünglich übergebene Pfad um den gefunden Eintrag erweitert und damit z.B. "C:\Windows" übergeben.

    In der 2. Ebene der Rekursion wird jetzt also "C:\Windows" durchsucht, weil dies so in "pfad" steht. Die Ebene darüber hat aber immer noch "C:\" in "pfad" stehen. Sind alle Dateien in der 2. Ebene aufgelistet, wird die Routine ganz normal beendet und es geht wieder eine Ebene höher. Dort würde die Routine, als wäre nichts gewesen, genau dort weitermachen, wo sie unterbrochen wurde und alle Dateien bis zum Ende von "C:\" auflisten.

    Fazit: Globale Variablen haben ihren Sinn, aber sie soilten nur dort benutzt werden, wo es auch notwendig ist. Man kann natürlich auch alle im Code irgendwo vorkommenden Schleifen-Variablen public nutzen, um sich das DIM in den einzelnen Routinen zu sparen. Schön ist aber anders...

    "byref" Parameter sind schnell in der Übergabe und verbrauchen immer den geringsten Speicher, weil keine Kopie erstellt werden muß. Aber man muß eben schauen, ob die Routine die Werte ändern kann und darf. Bei notwendigen Änderungen in den Werten, die aber nicht auf das Original durchschlagen sollen, muß man dann eben doch "byval" benutzen.

    "Rekursion" und "public Variablen" sind zwei Begriffe, die in einem Satz über einen Algorithmus nicht gemeinsam auftreten dürften.

    "static" oder wie auch immer das hieß, ist eine Krücke, die dafür sorgt, daß der lokale Speicher der Routine nicht freigegeben wird, wenn die Routine beendet wird. Damit macht man die lokalen Variablen der Routine zu pseudo-public Variablen. "static" und "Nackenhaarsträuben" sind zwei Begriffe, die hier sehr wohl in einem Satz zusammen auftauchen sollten. Ist fast so übel wie "goto"...

    Gruß, Michael
     
  3. Thomas Ramel MVP für Microsoft Excel
    Grüezi Andy

    Noch eine Ergänzung zu Michaels ausgezeichneten Ausfürhungen:

    Wenn Du eine Function erstellst, die in Excel dann aus einer Zelle heraus aufgerufen und verarbeitet werden soll, darfst Du nicht mit globalen Variabeln arbeiten, sondern musst alle Bereiche und Werte sauber als Parameter übergeben.
    Ansonstenwird die Funktion nicht neu berechnet wenn sich der Inhalt der globalen Variablen ändert.
     
    Thomas Ramel, 23. November 2011
    #3
  4. andysmith Erfahrener User

    Unterschied Public zu Parameter Übergabe ByRef / ByVal

    @miriki
    Vielen Dank für diese perfekte ausführliche Erläuterung!! Damit kann ich viel anfangen und bin auch schon dabei, meine bisherigen Strukturen so zu überarbeiten.
    Wenn ich zu einer Sache noch wissen könnte, wie sich diese Speicherbelegung ergibt?? ==>
    @Thomas Ramel
    Danke auch für diesen sicherlich wesentlichen Unterschied, kommt aber in meinen Fällen nicht in Betracht
    ------------
    Eine erweiterte Frage zum Thema dennoch (einmal so schnell aus dem Kopf hier in die Zeilen getippelt ohne genau zu prüfen)
    Wesentliche Frage hierbei ist, ich verwende im Sub die gleiche Variable wie in der Function. Wenn ich mich recht erinnere dann wird jedesmal ein eigener Speicherbereich angelegt in dem sich diese Variablen Namen nicht überschneiden sollten???...
    ....oder könnte es hierbei doch unerwartete Überschneidungen geben??

     
    andysmith, 25. November 2011
    #4
  5. miriki Erfahrener User
    Naja, relativ simpel und auch noch einigermaßen überschaubar, wenn man bei 2 Dimensionen bleibt.

    Mit dem array(9,19) weist Du an, Speicherplatz für 10 Zeilen (0..9) mit jeweils 20 Spalten (0..19) zu reservieren. Mit der Typangabe string(29) wird in jeder Zelle dieser 10x20 Matrix Platz für einen String mit 29 Zeichen max. Länge reserviert. Da Strings aber entweder a) als "nulltes" Zeichen ein Byte haben, in dem die Länge des Strings steht (woraus sich die maximale Länge eines Strings von 255 Zeichen ergibt) oder b) der String durch ein chr$(0) abgeschlossen wird, muß dieses zusätzliche Zeichen ebenfalls mit reserviert werden, woraus sich 30 Bytes ergeben. (Dabei laß ich jetzt mal Strings, in denen Zeichen durch 2 Bytes codiert werden, außer Acht...)

    Also hast Du 10 [zeilen] mal 20 [spalten] mal 30 [bytes] = 6000 bytes

    Gruß, Michael
     
  6. miriki Erfahrener User
    Nope, keine Gefahr. Die Variablen sind so absolut lokal, daß die anderen Routinen nicht mal wissen, daß es sie gibt, geschweige denn, bei Namensgleichheit überschreiben.

    Sollte es passieren, daß es zu Überschneidungen kommen könnte, wird dir das übrigens vom Interpreter zur Laufzeit angemeckert. Stößt der zur Laufzeit auf 2 Variablen, die im gleichen Namensbereich den gleichen Namen erhalten sollen, dann gibt's 'ne Fehlermeldung.

    Sowas passiert gerne mal, wenn man eine globale Variable, vielleicht sogar in einem anderen Modul, hat und dann in einer procedure den gleichen Namen nochmal benutzen möchte. Während der Entwicklung merkt man das nicht unbedingt, aber zur Laufzeit gibt Handpatscher.

    Gruß, Michael
     
Thema:

Unterschied Public zu Parameter Übergabe ByRef / ByVal

Die Seite wird geladen...
  1. Unterschied Public zu Parameter Übergabe ByRef / ByVal - Similar Threads - Unterschied Public Parameter

  2. Unterschiedliche Steuersätze

    in Microsoft Excel Hilfe
    Unterschiedliche Steuersätze: Hallo Zusammen, ich benötige eure Unterstützung bei einem "Problem" mit zwei unterscheidlichen Steuersätzen. Ich habe ein kleines Unternehmen mit Steuersätzen von 7% und 19%. Ich habe sowohl...
  3. Zwei Dateien vergleichen - Zielinfo in unterschiedlichen Spalten

    in Microsoft Excel Hilfe
    Zwei Dateien vergleichen - Zielinfo in unterschiedlichen Spalten: Hallo, ich benötige eure Unterstützung. Ich habe zwei Dateien (Excel) dahingehend abgleichen ob in der einen Datei (Master) Zieldaten (Boxennummern - jede in einer Zeile) und deren Folgedaten...
  4. Prüfung unterschiedlicher Zellen auf Inhalt und Konsequenz

    in Microsoft Excel Hilfe
    Prüfung unterschiedlicher Zellen auf Inhalt und Konsequenz: Hallo zusammen, ich habe einen Code, bei dem ich mehrere voneinander getrennte Zellen auf Befüllung prüfe. Wenn ich mindestens eine nicht befülle, erscheint eine Fehlermeldung und das Script...
  5. Unterschiedliche Landes PLZ

    in Microsoft Excel Hilfe
    Unterschiedliche Landes PLZ: Schön guten Abend, In einer Datei sind PLZ`s aus Deutschland , Österreich und die Schweiz, Über die PLZ möchte ich mir den Ort usw. wieder geben lassen. Aber wie erfasst man dann die PLZ`s...
  6. in Aufzählung sind die Aufzählungszeichen unterschiedlich

    in Microsoft Word Hilfe
    in Aufzählung sind die Aufzählungszeichen unterschiedlich: In einer Aufzählung werden einzelne Aufzählungszeichen (Buchstaben) unterschiedlich dargestellt - siehe Anhang Wir können in der Formatvorlage keine Einstellung zu den einzelnen Buchstaben finden...
  7. Spalte unterschiedlich sortieren/ausblenden

    in Microsoft Excel Hilfe
    Spalte unterschiedlich sortieren/ausblenden: Hallo zusammen, ich würde gerne in einer sehr langen Liste - ähnlich der im Anhang - sowohl im Linken Bereich als auch im rechten Bereich -getrennt/unabhängig voneinander die Zeilen mit der...
  8. Verwendung der unterschiedlichen Typen von Formatvorlagen

    in Microsoft Word Hilfe
    Verwendung der unterschiedlichen Typen von Formatvorlagen: Hallo, ich verwende in meinen Dokumenten konsequent Absatz-Formatvorlagen. Neben den bekannten Vorteilen (einheitliche Formatierung etc.) geht es mir darum, die Dokumente "schlank und schnell" zu...
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Auf dieser Website werden Cookies für die Zugriffsanalyse und Anzeigenmessung verwendet.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden