0

Frage zu globalen Funktionen

Hallo liebe Ninoxer,

habe in meiner DB ca. 100 Berechnungsfelder in denen dann der folgende Code "beim Anklicken" drin steht.

Ist dieser Code als globale Funktion herzustellen und wenn ja, wie.

let Art := 1;
let myG := this;
let myGast := GastName;
let myDia := first((select Einstellungen)[Zeile = "Dialog_Bestellungen"].Text);
let myDia1 := first((select Einstellungen)[Zeile = "Bestellungen"].Text);
let myDia2 := first((select Einstellungen)[Zeile = "bestellt"].Text);
let myDia3 := first((select Einstellungen)[Zeile = "Menge"].Text);
let myArt := first(select Verkaufsartikel where Nr = Art).Artikel;
let myArt1 := first(select Verkaufsartikel where Nr = Art).Bezeichnung;
let result := dialog(raw(myDia), raw(myDia1) + myGast + raw(myDia2) + text(myArt1) + raw(myDia3), ["1", "2", "3", "4", "5", "6", "abbrechen"]);
if result = "1" then
let X := (create Belegbuchung);
X.(Menge := 1);
X.(Artikel_ := myArt);
X.(Gast := myG)
else
if result = "2" then
let X := (create Belegbuchung);
X.(Menge := 2);
X.(Artikel_ := myArt);
X.(Gast := myG)
else
if result = "3" then
let X := (create Belegbuchung);
X.(Menge := 3);
X.(Artikel_ := myArt);
X.(Gast := myG)
else
if result = "4" then
let X := (create Belegbuchung);
X.(Menge := 4);
X.(Artikel_ := myArt);
X.(Gast := myG)
else
if result = "5" then
let X := (create Belegbuchung);
X.(Menge := 5);
X.(Artikel_ := myArt);
X.(Gast := myG)
else
if result = "6" then
let X := (create Belegbuchung);
X.(Menge := 6);
X.(Artikel_ := myArt);
X.(Gast := myG)
else
if result = "7" then
let X := (create Belegbuchung);
X.(Menge := 7);
X.(Artikel_ := myArt);
X.(Gast := myG)
else
if result = "8" then
let X := (create Belegbuchung);
X.(Menge := 8);
X.(Artikel_ := myArt);
X.(Gast := myG)
else
if result = "9" then
let X := (create Belegbuchung);
X.(Menge := 9);
X.(Artikel_ := myArt);
X.(Gast := myG)
else
if result = "10" then
let X := (create Belegbuchung);
X.(Menge := 10);
X.(Artikel_ := myArt);
X.(Gast := myG)
end
end
end
end
end
end
end
end
end
end

 

mit bestem Dank und gutem Start in neue Jahr

Alex

14 Antworten

null
    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Alex, mal abgesehen davon, dass sich solche if-Abfragen meist besser mit einer switch-case-Struktur abbilden lassen: Wenn ich es richtig sehe, dann ändert sich bei den Abfragen immer nur die Zahl für 'Menge', entsprechend der dialog()-Auswahl (wobei die Dialog-Optionen bis "6", die if-Abfragen bis "10" gehen). Das könnte man auch effizienter lösen, in dem man die Ziffer einfach in einen numerischen Wert umwandelt. Dann spart man sich den ganzen Rattenschwanz:

    [...]
    let result := dialog(raw(myDia), raw(myDia1) + myGast + raw(myDia2) + text(myArt1) + raw(myDia3), ["1", "2", "3", "4", "5", "6", "abbrechen"]);
    if result not "abbrechen" then
       let X := (create Belegbuchung);
       X.(Menge := number(result));
       X.(Artikel_ := myArt);
       X.(Gast := myG)
    end

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Und noch zum Thema "Globale Funktion" (war zwischendurch Mittagessen ;)

    Es müssen halt alle benötigten Daten, die nicht in der Funktion selbst generiert werden, als Parameter mit dem jeweiligen Datentyp übergeben werden. In diesem Fall wären das wohl 'myG' (ID) und 'myGast' (Text), wenn ich mich nicht irre.

    Der Aufruf der Funktion in einem Script/einer Formel würde dann so aussehen:

    getBestellmenge(this, GastName)

    Die Funktion selbst würde diese Werte in der entsprechenden Reihenfolge übernehmen und verarbeiten:

    function getBestellmenge(myG: TABELLE, myGast: text) do
     HIER DEIN CODE
    end

    Es gibt aber eine Besonderheit: Für Datensatz-IDs, wie sie von "this" zurückgegeben werden, existiert meines Wissen kein Übergabeformat. Deshalb soll man stett des Datentyps den Namen der Tabelle mit angeben, auf welche sich die ID bezieht. Das schränkt aber wiederum die Nutzung als globale Funktion in verschiedenen Tabellen ein. Ob es dafür inzwischen eine Lösung oder einen Workaround gibt, entzieht sich meiner Kenntnis. Vielleicht weiß jemand anderes mehr.

    • Firmeninhaber eines Dienstleistungsunternehmens (SHK)
    • Alexander_Prochnow
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Copytexter,

    ich bedanke mich für deine schnelle und ausführlichen Antwort.

    Das mit den switch case habe ich mir leider noch nicht so recht angeschaut, wollte dieses aber dann in nächster Zeit mal tun.

    Habe deine vorgeschlagenen Code mal ausprobieren wollen aber ninox meckert da.

    nach not wird ein Symol erwartet.... ich weiß aber nicht was. Mit dem "not" habe ich schon oft zu kämpfen gehabt, weswegen ich immer wieder diese if then else geschichte verwende.

    mit der globalen Funktion, wollte ich erreichen, das ich nicht immer alle (120 Brechnungsfelder) im Code ändern muss, wenn mir etwas einfällt, was ich da eventuell ändern kann.

    Die Brechnungsfelder befinden sich in der Tabelle Gast. Was sich bei den Feldern ändert ist der Artikel (definiert durch "let Art := 1" das muss ich wohl jeweils im Feld belassen).

     

    Mit bestem Dank

    Alex

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ach so, ja, "ungleich" passt hier wohl besser. Versuch's mal mit "!=":

     

    if result != "abbrechen" then [...]

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ups, zu schnell auf "Senden" geklickt ...

     

    Wenn man den code mehrfach an verschiedenen Stellen braucht, macht eine globale Funktion natürlich Sinn. Ich kenne den größeren Zusammenhang nicht (und das mit "Art := 1" verstehe ich auch nicht), aber versuch's doch mal so (in DB-Optionen unter "Globale Funktionsdefinitionen"):

     

    function getMenge(myG: Gast, myGast: text) do
       let Art := 1;
       NeueBuchung := false;
       let myDia := first((select Einstellungen)[Zeile = "Dialog_Bestellungen"].Text);
       let myDia1 := first((select Einstellungen)[Zeile = "Bestellungen"].Text);
       let myDia2 := first((select Einstellungen)[Zeile = "bestellt"].Text);
       let myDia3 := first((select Einstellungen)[Zeile = "Menge"].Text);
       let myArt := first(select Verkaufsartikel where Nr = Art).Artikel;
       let myArt1 := first(select Verkaufsartikel where Nr = Art).Bezeichnung;
       let result := dialog(raw(myDia), raw(myDia1) + myGast + raw(myDia2) + text(myArt1) + raw(myDia3), ["1", "2", "3", "4", "5", "6", "abbrechen"]);
       if result not "abbrechen" then
          let X := (create Belegbuchung);
          X.(Menge := number(result));
          X.(Artikel_ := myArt);
          X.(Gast := myG);
          NeueBuchung := true
       end;
       NeueBuchung
    end

     

    Durch die Variable "NeueBuchung" könnte man sich von der Funktion "true" oder "false" zurückgeben lassen, um weitere Aktionen/Auswertungen vornehmen zu können. Aufruf der Funktion im Script wäre dann bspw.:

     

    if getMenge(this, GastName) = true then
       machdies
    else
       machjenes
    end

     

    Jetzt mal so aus der Hüfte geschossen ...

    • Firmeninhaber eines Dienstleistungsunternehmens (SHK)
    • Alexander_Prochnow
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Das sieht schon fast gut aus....wenn ich das, dann noch richtig verstehen würde, käme ich vieleicht auch selbst drauf.

    Das mit dem Artikel... ich habe in der Tabelle Gast bzw. in der Formularansicht ca. 120 Berechnungsfelder die jeweils einen anderen Artikel zeigen... Funktion "(select Verkaufsartikel where Nr = 1).Bezeichnung"...(select Verkaufsartikel where Nr = 2).Bezeichnung....(select Verkaufsartikel where Nr = 3).Bezeichnung....

    Beim klicken, soll dann eben dieser im Feld angezeigter Artikel mit Gast und Menge in die Belegbuchung geschrieben werden. Mit dem Code von dir funktioniert das aber jetzt nur mit Artikel 1 aus der Tabelle Verkaufsartikel, da die Variable "Art" ja in der Funkionsdefinition steht. Wie kann ich das ändern? Ist es möglich in Funktionen selbst definierte  Funktionen auszuführen?

    Ich bedanke mich nochmal recht herzlich für deine Zeit, Mühe und ich hoffe das ich das dann bald mal etwas mehr verstehe...

    • Firmeninhaber eines Dienstleistungsunternehmens (SHK)
    • Alexander_Prochnow
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Habe mal die betreffende DB ins Webinarteam hochgeladen.... 300_Bistro V7_0 (Demo)

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ja, die 120 Berechnungsfelder hatte ich bisher geflissentlich ignoriert ... ;)

    Gut, jetzt verstehe ich die Idee, aber das ist natürlich ein echter Performance-Killer, denn sämtliche select-Befehle, Filter und Anzeigen-wenn-Abfragen werden ja bei jedem Aufruf des Formulars wieder neu ausgeführt. Bei mir hat die Aktualisierung der Anzeige nach Kategorie-Filterung zwei bis drei Sekunden gedauert.

    Aber wenn du diese 120 Berechnungsfelder nun mal hast und auf diese Weise Artikel auswählen willst (statt über eine Verknüpfung), dann bleibt im Grunde wohl gar nichts anderes übrig, als den "Beim Anklicken"-Code bei jedem Feld zu hinterlegen und jeweils anzupassen.

    Man könnte bei der Variable "Art" zwar auf das Ergebnis der Funktion zugreifen, aber dazu müsste man das Berechnungsfeld ja auch benennen. Und die haben ja ebenfalls alle unterschiedliche Namen.

     

    Ich sehe deshalb unter den gegebenen Voraussetzungen so auf Anhieb leider keine andere Möglichkeit, als den o. a. "Beim-Anklicken"-Code 120 mal anzupassen: let Art = 1, let Art = 2 usw. Aber mir schwirrt auch gerade der Kopf, vielleicht schaut jemand anderes noch mal in die DB und hat eine Idee.

    • Firmeninhaber eines Dienstleistungsunternehmens (SHK)
    • Alexander_Prochnow
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Guten Morgen,

    ja das Thema Performance hat mit schon beschäftigt. In den ursprünglichen Versionen hatte ich Verküpfungen drin. da hatte sich aber herrausgestellt das dieses von der Bedienung her unpraktisch war. Auch hier hatte ich das  Performance-Thema, da in den verknüpften Tabellen auch einige Abfragen vorhanden waren. Ich lerne ja dazu -hoffe ich-  

    • Firmeninhaber eines Dienstleistungsunternehmens (SHK)
    • Alexander_Prochnow
    • vor 5 Jahren
    • Gemeldet - anzeigen

    habe etwas propiert und es scheint zu funktionieren.

    den code habe ich in globale Funktionen drin

    function getMenge(myG : Gast,myGast : text,Art : number) do
    let Art := Art;
    let NeueBuchung := false;
    let myDia := first((select Einstellungen)[Zeile = "Dialog_Bestellungen"].Text);
    let myDia1 := first((select Einstellungen)[Zeile = "Bestellungen"].Text);
    let myDia2 := first((select Einstellungen)[Zeile = "bestellt"].Text);
    let myDia3 := first((select Einstellungen)[Zeile = "Menge"].Text);
    let myArt := first(select Verkaufsartikel where Nr = Art).Artikel;
    let myArt1 := first(select Verkaufsartikel where Nr = Art).Bezeichnung;
    let result := dialog(raw(myDia), raw(myDia1) + myGast + raw(myDia2) + text(myArt1) + raw(myDia3), ["1", "2", "3", "4", "5", "6", "abbrechen"]);
    if result != "abbrechen" then
    let X := (create Belegbuchung);
    X.(Menge := number(result));
    X.(Artikel_ := myArt);
    X.(Gast := myG)
    end
    end

    und das im Berechnungsfeld beim klicken

    let Art := 1;
    Art := Art;
    getMenge(this, GastName, Art)

    muss jetzt natürlich die 120 Felder erstmal ändern, aber es scheint zu tun

    • Firmeninhaber eines Dienstleistungsunternehmens (SHK)
    • Alexander_Prochnow
    • vor 5 Jahren
    • Gemeldet - anzeigen

    naja Rechtschreibung ist auch nicht meine Stärke "propieren" .... kopf klatsch

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Moin Alex, freut mich, wenn es für dich so funktioniert. Aber das "Art := Art" ist eigentlich in beiden Fällen überflüssig.

    • Firmeninhaber eines Dienstleistungsunternehmens (SHK)
    • Alexander_Prochnow
    • vor 5 Jahren
    • Gemeldet - anzeigen

    ja stimmt... vielen, vielen Dank für deine Hilfe. Jetzt verstehe ich zumindest teileweise mal die Geschichte mit der globalen Funktion bzw. wie man es anwenden kann. Habe bisher einen großen Bogen darum gemacht, da ich nicht wusst wie das funktioniert. Jetzt tauchen da wieder weitere Ideen auf die ich damit machen kann. Mit Ninox wird es mir nicht langweilig... und ich finde es super, das ich als Laie hier sowas hinbekomme (geht natülich alles besser)

    in diesem Sinne einen guten Start ins neue Jahr

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    👍 🥂 😉