[Gelöst] Record Variable als Funktionsparameter

6. Juni 2018 07:18

Hallo Community,

vermutlich handelt es sich nur um ein Verständnisproblem und lässt sich schnell klären, deswegen versuche ich es kurz zu halten. Eine Codeunit mit 3 Funktionen:

Code:
Beispieldatensatz:
Record 123:
    Field1 -> 10
    Field2 -> 10

PROCEDURE FunctionA();
VAR
    RecordVariable : Record 123;
BEGIN
    RecordVariable.GET;
    FunctionB(RecordVariable);
    FunctionC(RecordVariable);
END

PROCEDURE FunctionB(RecordVariable : Record 123);
BEGIN
    RecordVariable.Field1 := 20;
    RecordVariable.Modify;
END

PROCEDURE FunctionC(RecordVariable : Record 123);
BEGIN
    RecordVariable.Field2 := 20;
    RecordVariable.Modify;
END


Ich hoffe das geht als lesbarer Pseudocode durch :D. Was nun passiert ist, dass in meinem Datensatz nur Field2 geändert wurde. Wenn ich die Funktionen einzeln aufrufe funktioniert es aber.

Lösung:
Während ich das schreibe fällt es mir selbst auf :roll: , ich schreib den Beitrag aber mal trotzdem vielleicht hilft es ja doch dem einen oder anderen:
Da ich mir in FunctionA die RecordVariable nicht nochmal lade (z.B. mit GET) und die Übergabe nur "Call By Value" ist (VAR ist nicht angehakt) wird bei dem Aufruf von FunctionC der Datensatz mit dem Stand vor FunctionB übergeben und in diesem Zustand auch nochmal (+ die Änderung von Field2) in die DB geschrieben.

Lösungsvorschlag A:
In FunctionB und C nochmal eine lokale Variable zu Record 123 anlegen und diese mit GET holen und dann diese verändern.

Lösungsvorschlag B:
VAR anhaken bei dem Übergabeparameter von von FunctionB und C.

Da vielleicht nochmal kurz in die Runde was die bessere Lösung wäre, hinsichtlich Performance und/oder Sauberkeit und Robustheit des Codes?
Zuletzt geändert von jkahnt am 6. Juni 2018 12:23, insgesamt 1-mal geändert.

Re: Record Variable als Funktionsparameter

6. Juni 2018 09:07

jkahnt hat geschrieben:Lösungsvorschlag B:
VAR anhaken bei dem Übergabeparameter von von FunctionB und C.

Zu bevorzugen ;-)
Meistens (nicht immer) sollte man vermeiden, einen Record neu zu lesen.
Und ein Modify am Ende reicht, in deinem Pseudocodebeipsiel am Ende von FunctionA - dort holst du den Datensatz auch erstmalig, also solltest du ihn auch da beenden.

Also nochmal:

Code:
PROCEDURE FunctionA();
VAR
    RecordVariable : Record 123;
BEGIN
    RecordVariable.GET;
    FunctionB(RecordVariable);
    FunctionC(RecordVariable);
    RecordVariable.MODIFY;
END

PROCEDURE FunctionB(VAR RecordVariable : Record 123);
BEGIN
    RecordVariable.Field1 := 20;
END

PROCEDURE FunctionC(VAR RecordVariable : Record 123);
BEGIN
    RecordVariable.Field2 := 20;
END

Re: Record Variable als Funktionsparameter

6. Juni 2018 12:22

Hallo Natalie,

vielen Dank für den Tipp. Was ich vergessen habe:
Die Funktionen können und werden auch alle separat gerufen. FunctionA ist im Prinzip eine Abkürzung (im richtigen Quellcode kümmert die sich auch noch um andere Voraussetzungen und Logiken). Deswegen hatte ich die Modify-Befehle in den Einzelfunktionen aufgerufen. Aber ich werde es jetzt mit VAR auf Call By Reference umbauen und das Thema auch damit erstmal auf Gelöst stellen. Nochmals vielen Dank.