0

Problem bei Globaler Funktion

Hallo Zusammen,

ich sehe den Wald vor lauter Bäumen nicht :-(.
Folgendes Problem, bei meiner Firma werden nicht jeden tag die gleichen Stunden als Arbeitszeit gezählt. Somit habe ich für jeden Arbeitstag einen Wert als Stunden. Diesen ermittel ich aus der Tabelle Arbeitgeber. Dies nur zum Rande als Info. Nun werden die Urlaubstage nicht in tagen, sondern in Stunden berechnet. Um dies zu bewerkstelligen möchte ich dies über eine Globale Funktion aufrufen, da die gleiche Formel mehrmals verwendet wird.
Allerdings scheitere ich an folgender Funktion:

function Versuch(Wert : number) do
let VerDo := cnt(select Zeiterfassung where Art = Wert and (select Zeiterfassung).weekday(Datum) = 3);
VerDo
end;

Normalerweise müssten jetzt vom aktuellen Monat alle Donnerstage, die einen Feiertag haben gezählt werden. In einem Berechnungsfeld in der Tabelle funktioniert es Reibungslos.

let Mo := cnt(Zeiterfassung[weekday(Datum) = 0 and Art = 3]) * Arbeitgeber.Montag;
let Di := cnt(Zeiterfassung[weekday(Datum) = 1 and Art = 3]) * Arbeitgeber.Dienstag;
let Mi := cnt(Zeiterfassung[weekday(Datum) = 2 and Art = 3]) * Arbeitgeber.Mittwoch;
let Do := cnt(Zeiterfassung[weekday(Datum) = 3 and Art = 3]) * Arbeitgeber.Donnerstag;
let Fr := cnt(Zeiterfassung[weekday(Datum) = 4 and Art = 3]) * Arbeitgeber.Freitag;
if number(Mo + Di + Mi + Do + Fr) > 0 then
number(Mo + Di + Mi + Do + Fr)
else
void
end

Allerdings mit dieser Globalen Funktion bekomme ich als Rückgabewert nur eine 0.

Irgendjemand eine Idee?

Guten Rutsch und Grüße Michael

13 Antworten

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

    Hallo Michael, Idee: Schon mal ohne das zweite "select" versucht?

     

    function Versuch(Wert : number) do
       let VerDo := cnt(select Zeiterfassung where Art = Wert and weekday(Datum) = 3);
       VerDo
    end

    • Michael_Martin
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Copytexter,

    ja hatte ich versucht und die Funktion zählt nicht richtig.
    Habe mal zwei Fotos gemacht:

    Bildschirmfoto 2019-12-31 um 12.33.37Bildschirmfoto 2019-12-31 um 12.33.09

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

    Hallo Michael, kannst du vielleicht die Datenbank mit allen relevanten Tabellen mal irgendwo hochladen? Dann könnte man sich das mal genauer ansehen.

    • Michael_Martin
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Copytexter,

    anbei die abgespeckte Version:

    https://www.icloud.com/iclouddrive/0mNll7sincH6a6yNZ6KiKoHgw#DB_Zeit

     

    Vielen Dank :-)

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

    Okay, ich schaue mal rein (nachdem ich mich um den Kartoffelsalat gekümmert habe).

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

    Hallo Michael, schreibe den an die Funktion zu übergebenden Wert vorher mal in eine Variable, also bspw. so

     

    let myArt := 3;
    let Global := Versuch(myArt);

     

    statt

     

    let Global := Versuch(3);

    • Michael_Martin
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Mach in Ruhe. Heute ist Silvester, also Rutsch gut rüber ins Neue Jahr.

     

    gruß Michael

    • Michael_Martin
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ein frohes Neues 2020!

    Hallo Copytexter,
    dein voorgeschlagener Ansatz bringt leider das selbe falsche Ergebnis.

     

    Gruß Michael

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

    Hallo Michael, besten Dank und ebenfalls ein gutes neues Jahr!

    Zu Ninox: Ich habe den Code mal ein bisschen geordnet, und jetzt geht's, soweit sich das mit den vorhandenen Daten testen ließ. Ich kann nicht mal ganz sicher sagen, woran genau es gelegen hat. Aber man sollte select-Abfragen wohl nach Möglichkeit mit Variablen durchführen statt mit festen Werten.

    Um flexibel testen zu können, hatte ich zwei Auswahlfelder für 'Art' und 'Wochentag' hinzugefügt (siehe Screenshot) und die Abfrage-Variablen 'myDay' und 'myArt' daraus bestückt. Der Code im Berechnungsfeld 'GG' mit dem Aufruf der globalen Funktion sieht jetzt so aus:

    let myDay := weekdayIndex(text(Wochentag));
    let myArt := number(Art);
    let AnzTage := cnt(Zeiterfassung[weekday(Datum) = myDay and Art = myArt]);
    let Global := Versuch(myDay, myArt);
    text("Formel Direkt: " + AnzTage + " | Globale Funktion: " + Global)

    Wobei die Variablen 'myDay' und 'myArt' ihre Werte natürlich auch auf andere Weise beziehen können, also auch durch direkte Angabe eines Wertes (z.B. "let myDay := 3;" für den Wochentag). Es muss halt nur ein numerischer sein. Ich habe den Bezug zu den Auswahlfeldern hier zur Veranschaulichung so belassen. 

     

    Die Globale Funktion selbst habe ich auch etwas geändert. Und dadurch, dass mit 'myDay' und 'myArt' jetzt beide benötigten Werte übergeben werden, passt die Funktion auch für jede im Aufruf festgelegte Kombination von Art und Wochentag: 

    function Versuch(myDay : number,myArt : number) do
        let Anzahl := cnt(select Zeiterfassung where weekday(Datum) = myDay and Art = myArt);
        Anzahl
    end;

     

    Das Ergebnis der lokalen und globalen Berechnungen stimmte in allen getesteten Konstellationen überein.

     

    2020-01-01_GlobaleFunktion02

    • Michael_Martin
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Guten Morgen Copytexter,

    erstmal Danke für deine Hilfe und Mühe. Wie ich mittlerweile Denke muss da noch eine Abfrage des Jahres mkit Monats herein. Wenn Du mehrere Monate nimmst kommt auch deine Lösung ins Schleudern. Ich denke ich werde wohl auf die Globale Funktion in diesem Fall verzichten. Scheint vielleicht noch ein Bug in der Software zu sein.

    Bildschirmfoto 2020-01-02 um 03.15.26

    Gruß Michael

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

    Moin Michael, 'Zeiterfassung' ist eine Untertabelle von 'Auswertung' und über den Monat verknüpft. Das heißt, wenn du über das Plus-Zeichen einen neuen Datensatz in der 'Zeiterfassung' erstellst, ist dieser automatisch mit dem aktuellen Datensatz in 'Auswertung' verknüpft. Bei der lokalen Berechnung werden dann auch nur diese verknüpften Datensätze des betreffenden Monats berücksichtigt (hier: Januar). In der globalen Funktion wird aber nicht auf die Verknüpfung Bezug genommen, sondern per "select" auf die gesamte Tabelle 'Zeiterfassung'. Mir war das nicht aufgefallen, weil in der DB von dir nur Daten aus Januar enthalten waren. Man kann das aber ganz einfach überprüfen, indem man auch dem lokalen cnt() ein "select" voranstellt:

    let AnzTage := cnt(select Zeiterfassung[weekday(Datum) = myDay and Art = myArt]);

    Dann müsste bei beiden Berechnungen eigentlich dasselbe Ergebnis herauskommen. Klar, zur Ermittlung der monatlichen Werte müsste man die Datensätze der 'Zeiterfassung' natürlich entsprechend filtern. Aber das wäre ja ein Leichtes. Wobei vielleicht sogar eine Ansicht besser wäre als eine Verknüpfungstabelle. Ich habe allerdings auch gesehen, dass du mit dem Button "Tage eintragen" die Tabelle 'Zeiterfassung' jedes Mal wieder löscht. Wieso, konnte ich so auf die Schnelle nicht durchschauen. Die Daten zu behalten wäre von der Menge her ja kein Problem.

    Aber ich kenne natürlich deine speziellen Anforderungen nicht und will dir auch nicht reinreden. Mir scheint aber, dass du die Sache generell etwas zu kompliziert angehst, völlig unabhngig von der Frage, ob du die eine oder andere Berechnung nun als lokale oder globale Funktion ausführst.

    • Michael_Martin
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo Copytexter,

    die DB ist seit 2017 stetig gewachsen. Da meine Programmierkenntnisse noch von ganz früher sind, ist es mit vielem nicht leicht. Wie wir ja alle wissen ist die Dokumentation bei Ninox immer noch stark verbesserungswürdig: Des Wegen ist die Datenbank so wie es für mich am einfachsten war zu realisieren.

    Mit den ganzen Filtern usw. tue ich mich mittlerweile sehr schwer, da der Frust Faktor manchmal doch recht groß ist.

    Anbei wie meine Erfassung aufgebaut ist:

    Bildschirmfoto 2020-01-02 um 10.59.41

    Aber wirklich vielen Dank für deine Hilfsbereitschaft. Kann Dir noch nicht mal ein Bier ausgeben :-(

    Es gibt für jedes Jahr eine Untertabelle Zeiterfassung.

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

    Wenn es für dich so funktioniert, dann ist es doch in Ordnung. Viele Wege führen nach Rom. Hauptsache, man kommt an. Was die nutzerdefinierten Funktionen angeht (ob lokal oder global): Du musst halt immer überlegen, was genau du berechnen bzw. abfragen willst und alle dazu erforderlichen Parameter im benötigten Format an die Funktion übergeben. Das können ggf. auch deutlich mehr als zwei sein, technisch wäre das kein Problem.

    Viel Erfolg! Bei weiteren Fragen gerne melden.

    PS: Ich trinke eh nur Malzbier. ;)