0

Definition einer rekursiven Funktion?

Hallo,

ich habe eine geschachtelte Struktur aufgebaut durch Verlinkung einer Tabelle mit sich selbst (als Untertabelle):

Textfeld "Name"
Zahl      "Wert"
=>        "Teil von"
<=        "enthaltene Teile"

Die Idee ist, dass sich "Wert" jeweils berechnet als Summe über alle enthaltenen Teile. Die Wertestruktur berechnet sich automatisch selbst, wenn ein Datensatz geändert wird:

if 'Teil von' then
   'Teil von'.(Wert := sum('enthaltene Teile'.Wert))
end

Sobald der Wert eines Kind-Datensatzes geändert wird, berechnet sich der Wert des Eltern-Datensatzes neu als Summe über alle Kinder. Das funktioniert sehr schön, solange es bei einer zweistufigen Hierarchie bleibt. Sobald aber auch der Eltern-Datensatz einen Großeltern-Eintrag über sich hat, greift das nicht mehr. Die Änderung des Eltern-Wertes löst nicht automatisch die Neuberechnung des Großeltern-Wertes aus. 

Ich habe mir daher folgendes überlegt:

function neuberechnen(x: tabelle) do
    'Teil von'.(Wert := sum('enthaltene Teile'.Wert));
    for y in 'enthaltene Teile' do
        neuberechnen(y)
    done
done;
neuberechnen(this)

Das funktioniert aber nicht. Die Funktion lässt sich nicht rekursiv in sich selbst verwenden, da sie ihre Definition noch nicht kennt. 

Hat jemand eine Idee?

4 Antworten

null
    • CGR
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Sorry, in der letzten Formel fehlt natürlich ein "x":

    x.'Teil von'.(Wert := sum('enthaltene Teile'.Wert));

    • Leonid_Semik
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo CGR,

    man kann das System austricksen indem man mit Ids arbeitet. Dein Trigger nach Änderung bei Wert kann dan so aussehen:

    ---

    let myID := number(Nr);
    let myParent := record('DEINE TABELLE',myID).'Teil von';
    while myParent do
    myParent.(Wert := sum('enthaltene Teile'.Wert));
    myID := number(myParent.Nr);
    myParent := record('DEINE TABELLE',myID).'Teil von'
    end

    ---

     

    Leo

    • CGR
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Vielen Dank Leo,

    das klappt wunderbar! 

    Ich hatte es zwischendurch mit einem ähnlichen Ansatz versucht,

    function nb(x : Zahlung) do
    if x.'Teil von' then
    x.'Teil von'.(Wert := sum('enthaltene Teile'.Wert))
    end
    end;
    nb(this);
    let r := 'Teil von';
    while r do
    nb(r);
    let s := r.'Teil von';
    let r := s;
    nb(r)
    end;

    Hat auch funktioniert, war aber seltsamerweise viiiieeel langsamer. 

    Schöne Grüße

    Christian

    • CGR
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Vielen Dank Leo,

    das klappt wunderbar! 

    Ich hatte es zwischendurch mit einem ähnlichen Ansatz versucht,

    function nb(x : Zahlung) do
    if x.'Teil von' then
    x.'Teil von'.(Wert := sum('enthaltene Teile'.Wert))
    end
    end;
    nb(this);
    let r := 'Teil von';
    while r do
    nb(r);
    let s := r.'Teil von';
    let r := s;
    nb(r)
    end;

    Hat auch funktioniert, war aber seltsamerweise viiiieeel langsamer. 

    Schöne Grüße

    Christian

Content aside

  • vor 5 JahrenZuletzt aktiv
  • 4Antworten
  • 1600Ansichten