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. Formel auf andere Zellen unterschiedlicher Größe anwenden

    in Microsoft Excel Hilfe
    Formel auf andere Zellen unterschiedlicher Größe anwenden: Hallo zusammen, ich habe eine Formel gebastelt, die wie angehängt in der Beispiel-Excel zu sehen ist, funktioniert. Kann ich die Formel so vereinfachen, dass ich nicht 3x die angepasste Formel...
  3. Outlook IMAP Struktur im selben Postfach auf Clients unterschiedlich

    in Microsoft Outlook Hilfe
    Outlook IMAP Struktur im selben Postfach auf Clients unterschiedlich: Ich habe ein IMAP Postfach, auf das ich 1) von meinem Arbeitsplatzrechner im Büro, 2) meinem Arbeitsplatzlaptop und 3) meinem Privatrechner gleichzeitig über Outlook zugreife. Auf allen drei...
  4. Zwei gleiche Dateien unterschiedlich groß?

    in Microsoft Excel Hilfe
    Zwei gleiche Dateien unterschiedlich groß?: Hallo, erst einmal einen schönen guten morgen. Ich bin neu hier und hoffe evtl. Hilfe bei meinem Problem zu erhalten :-) Folgendes Problem. Ich erstelle jeden Monat eine PPT (Ja ich weiß es...
  5. Absatz erzeugt unterschiedliche Höhen in Tabellen (-zeile)

    in Microsoft Word Hilfe
    Absatz erzeugt unterschiedliche Höhen in Tabellen (-zeile): Hallo! Kurzfassung: Ich möchte einfach nur eine Tabelle erstellen, in der Abstände von 6 Pt. vor und nach jeder Tabellenzeile eingefügt sind. Der Zeilenabstand soll dabei "Einfach" sein, sodass...
  6. Unterschiedliche Kopfzeile wenn mehrere seiten

    in Microsoft Word Hilfe
    Unterschiedliche Kopfzeile wenn mehrere seiten: Gibt es dafür eine Lösung? Ich habe ein Dokument. Wenn einseitig erscheint in der Kopfzeile Logo, Titel, Nummer. Wenn zweiseitig erscheint ab der zweiten Seite nur noch Titel und Nummer....
  7. Kundennummer unterschiedlicher Tarif A oder B

    in Microsoft Excel Hilfe
    Kundennummer unterschiedlicher Tarif A oder B: In der Tabelle sollen die Kunden mit einer A Nummer einen anderen Tarif zahlen, als die Kunden mit einer B Nummer Probiere schon seit ca 7 Stunden rum aber nichts geht, irgendjemand eine Idee,...
  8. Seiten mit unterschiedlichen Werten addieren

    in Microsoft Excel Hilfe
    Seiten mit unterschiedlichen Werten addieren: Hallo, ich möchte kopierte Seiten mit 2 unterschiedlichen Werten berechnen lassen. Beispiel: ich habe 55 Seiten, dann sollen 50 Seiten mit 0,50€ berechnet werden + 5 Seiten mit 0,15€ und das...
  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