0

Ansicht nur mit den letzten Datensätzen

Hallo,

Habe bisher folgende Ansicht:

let thisone := this;
let thisPID := (select Personal where 'Pers-ID' = thisone.Personal.'Pers-ID').'Pers-ID';
let thisSchuljahr := 'Deputat SJ'.Schuljahr;
select DV where Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr

In der Tabelle DV gibt es auch die Felder GRUND (mit verknüpften Einträgen Grund1, Grund2, ...), ANZAHL und ein Datumsfeld. Es gibt in DV pro Schuljahr mehrere Datensätze mit Grund1 oder mit Grund 2 etc., die Einträge mit gleichem Grund unterscheiden sich dann aber auf alle Fälle im Datum. Ich möchte in der Ansicht jetzt alle Einträge des Schuljahres, sodass jeder GRUND nur einmal auftaucht und zwar derjenige mit dem letzten Datumseintrag (ich benötige dann dessen Eintrag in ANZAHL).

Mit fehlt die Idee, ob ich da eine Schleife laufen lassen muss (über die Gründe und Schuljahr) oder das direkt in die Bedingungen des select Befehls packen kann.

Grüße

Maurice

PS: Post leider unter Tipps und Hilfen falsch gepostet gehabt, sorry.

15 Antworten

null
    • + Maßanzug statt Massenware +
    • RonaldP
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Moin Maurice ,

    mir würde hier ein Screenshot eines Datensatzes von DV sehr zum Verständnis helfen.
    Geht das?

    VG Ronald

    • Maurice
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo DIGITOOL ,

    im Datensatz heißt das Feld Deputatsgrund, was ich in der Anfrage mit Grund bezeichnet habe. Es ist so, dass sich für die gleiche Tätigkeit (Deputatsgrund) die Vergütung (Deputatsstunden) ändern kann. Es soll dann in der Ansicht diejenige Anzahl stehen, die zuletzt (nach Datum) für einen bestimmten Grund in einem bestimmten Schuljahr eingetragen wurde.

    Einen Workaround habe ich jetzt derart gestaltet, dass im Datensatz DV ein Funktionsfeld "letzter Eintrag" ist, dass abfragt, ob der jeweilige Datensatz der letzte DS mit den Kriterien Person, Schuljahr, Grund, gleiches Deputatsjahr  ist mit:

    let my := this;
    let maxDatum := max((select 'Deputatsvergütungen')[Person = my.Person and 'Deputat SJ' = my.'Deputat SJ' and 'geleistet im SJ' = my.'geleistet im SJ' and Deputatsgrund = my.Deputatsgrund].Datum);
    if my.Datum = maxDatum then "ja" else "nein" end
    

    In der select-Abfrage der Ansicht frage ich jetzt dieses Feld "letzter Eintrag" auf den Inhalt "ja" ab. Diesen Workaround hatte ich nach meiner Anfrage entwickelt, wollte hier mal noch warten, wie eine Lösung aussehen könnte ohne dieses Workaroundfeld, also direkt in der select-Abfrage der Ansicht. Bin mir sicher, dass das geht, nur meine Skriptfähigkeiten reichen da nicht aus.

    • + Maßanzug statt Massenware +
    • RonaldP
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Verstehe ich richtig, dass die Ansicht in der Tabelle PERSONAL in jedem Datensatz angezeigt wird und nicht in einer anderen Tabelle z.B. DASHBOARD die keine eigenen Datensätze enthält?

    Dein Code im ersten Post deutet daraufhin und es macht für den select der Ansicht einen Unterschied.

    • Maurice
    • vor 2 Jahren
    • Gemeldet - anzeigen

    DIGITOOL  Nein, die Ansicht wird in einer anderen Tabelle als PERSONAL dargestellt. Diese enthält auch eigene Felder ohne Verknüpfungen, besteht aber hauptsächlich aus Verknüpfungen, versch. Ansichten und Funktionen.

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Maurice. Wenn Du das Datum chronologisch vergibst (also keine Rückdatierungen machst), könnte es so gehen. Mirko

    let thisone := this;
    let thisPID := (select Personal where 'Pers-ID' = thisone.Personal.'Pers-ID').'Pers-ID';
    let thisSchuljahr := 'Deputat SJ'.Schuljahr;
    "Vereinzelt die Deputatsgründe";
    let isolate := unique((select DV).Deputatsgrund);
    "Erstellt ein Array aus Datensatznummern mit der höchsten Datensatznummer pro Deputatsgrund und Deinen Filterkriterien";
    let allMaxNr := for i in isolate do
            max(for x in (select DV)[Deputatsgrund = i and Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr] do
                    x.number(Nr)
                end)
        end;
    "Bildet das Record-Array für die Ansicht";
    for x in allMaxNr do
        record(DV,x)
    end
    
    • Maurice
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Mirko, leider wird bei Datum nicht unbedingt aufsteigend eingegeben, also Datum steigt nicht mit der Nr. Wir erhalten manchmal von anderen Stellen Deputatzuweisungen, deren Datum eine Rückdatierung darstellt.  Es gibt scheinbar keine Funktion à la id(max (for ... x.Datum end)) oder übersehe ich etwas?

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Dann vielleicht so:

    let thisone := this;
    let thisPID := (select Personal where 'Pers-ID' = thisone.Personal.'Pers-ID').'Pers-ID';
    let thisSchuljahr := 'Deputat SJ'.Schuljahr;
    "Vereinzelt die Deputatsgründe";
    let isolate := unique((select DV).Deputatsgrund);
    "Erstellt ein Array aus Datensatznummern mit dem jeweils letzten Datum pro Deputatsgrund und Deinen Filterkriterien";
    let allMaxNr := for i in isolate do
            last(for x in ((select DV) order by Datum)[Deputatsgrund = i and Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr] do
                    x.number(Nr)
                end)
        end;
    "Bildet das Record-Array für die Ansicht";
    for x in allMaxNr do
        record(DV,x)
    end
    
    • Maurice
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo  Mirko

    das sieht schon  super aus und klappt auch. Leider habe ich erst jetzt gemerkt, dass weitere Kriterien für den array ISOLATE wichtig sind. Im Snapshot eines Datensatzes sieht man noch die Felder 'geleistet im SJ' und 'Ergänzung Deputatsgrund'.  Es kann also auch sein, dass der gleiche Deputatsgrund vorliegt mit dem gleichem Eintrag 'geleistet im SJ'. Das passiert dann, wenn nachträglich für eine erbrachte Tätigkeit Deputatsstunden erhöht werden. Dann sollte dort auch der letzte Eintrag genommen werden. Ähnliches gilt für 'Ergänzung Deputatsgrund'. Beispiel: ein Datensatz in DV: Deputatsgrund ist 'Verwaltungstätigkeit' geleistet im SJ '2022/23' mit Ergänzung 'Haushalt'; es kann einen  zweiten Datensatz geben mit Deputatsgrund ist 'Verwaltungstätigkeit' geleistet im SJ '2022/23' mit Ergänzung 'Kursorganisation';

    Wenn mehrere Datensätze in Deputatsgrund; geleistet im SJ, Ergänzung (Pers-ID und Deputat SJ sowieso - das klappt ja) gleich sind, soll der letzte verwendet werden.

    Mit dem von mir genannten Hilfsfeld im Datensatz der Tabelle DV, das beinhaltet

    let my := this;
    let maxDatum := max((select 'Deputatsvergütungen')[Person = my.Person and 'Deputat SJ' = my.'Deputat SJ' and 'geleistet im SJ' = my.'geleistet im SJ' and Deputatsgrund = my.Deputatsgrund and 'Ergänzung Deputatsgrund'=my.'Ergännzung Deputatsgrund'].Datum);
    if my.Datum = maxDatum then "ja" else "nein" end
    

    klappt das ja.

    Habe mal in Ansätzen auch mit doppelten Schleifen wie versucht, aber das klappt nicht - logisch. Bekomme aber den gordischen Knoten nicht geknackt.

    Das array ISOLATE hat unten 12 Einträge, mit unique versehen komme ich auf  9, da ja manche der 12  sich in 'geleistet im SJ'  unterscheiden.

    
    let thisPID := this.Personal.'Pers-ID';
    let thisSchuljahr := this.'Deputat SJ'.Schuljahr;
    let selectDG := (select 'Deputatsvergütungen');
    "Vereinzelt die Deputatsgründe und geleistete Schuljahre";
    let isolateSJ := unique(selectDG[Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr].'geleistet im SJ');
    let isolate := selectDG[Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr].Deputatsgrund;
    "Erstellt ein Array aus Datensatznummern mit dem jeweils letzten Datum pro Deputatsgrund und Deinen Filterkriterien";
    let allMaxNr := for i in isolate do
    for j in isolateSJ do
            last(for x in (selectDG order by Datum)[Deputatsgrund = i and Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr] do
                    x.number(Nr)
                end)
        end; end;
    "Bildet das Record-Array für die Ansicht";
    for x in allMaxNr do
        record('Deputatsvergütungen',x)
    end;
    (select 'Deputatsvergütungen')[Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr and 'letzter Eintrag']
    

    Wenn du meinst, die Lösung über das Hilfsfeld ist gut (sie funktioniert), dann kann ich das so lassen. Mich reizt natürlich die Umsetzung Funktionsfeld der Ansicht, um etwas zu lernen. Selbst schaffe ich es nicht. Ich könnte mal heute Abend eine reduzierte und anonymisierte DB erstellen/abspecken und weiß die Unterstützung hier sehr zu schätzen.

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Maurice. Mal sehen ob ich folgen konnte mit allen Bedingungen. Habe ein paar Variablennamen geändert für meine Übersicht. Ggf. mußt Du noch Schreibfehler ausbügeln - ist nur freihand geschrieben. Sonst lieber die Dummy DB.

    let person := Person;
    let schuljahr := 'Deputat SJ';
    let geleistetSJ := 'geleistet im SJ';
    let depGrundErg := 'Ergänzung Deputatsgrund';
    "Vereinzelt die Deputatsgründe";
    let isolate := unique((select DV).Deputatsgrund);
    "Erstellt ein Array aus Datensatznummern mit dem jeweils letzten Datum pro Deputatsgrund und Deinen Filterkriterien";
    let allMaxNr := for i in isolate do
            last(for x in ((select DV) order by Datum)[Deputatsgrund = i and Person = person and 'Deputat SJ' = schuljahr and 'geleistet im SJ' = geleistetSJ and 'Ergänzung Deputatsgrund' = depGrundErg] do
                    x.number(Nr)
                end)
        end;
    "Bildet das Record-Array für die Ansicht";
    for x in allMaxNr do
        record(DV,x)
    end
    
    • Maurice
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Mirko,

    Person und 'Deputat SJ' sind in der Tabelle, in der die Ansicht ist, (verknpüfte) Felder eines Datensatzes, also klar definiert.

    Aber 'geleistet im SJ' und 'Ergänzung Deputatsgrund' sind keine Felder in der Tabelle mit der Ansicht sondern nur in der Tabelle DV. Das ist mein Problem.

    Es ruft nach der Dummy DB.

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Maurice. Hier mal ein Zwischenergebnis. Vielleicht prüfst Du es erstmal. Mirko

    let thisone := this;
    let thisPID := this.Personal.'Pers-ID';
    let thisSchuljahr := 'Deputat SJ'.Schuljahr;
    let isolate := unique((select 'Deputatsvergütungen')[Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr].(Deputatsgrund.Deputatsgrund + "#" + 'Ergänzung Deputatsgrund'));
    let resultAry := for i in isolate do
            last(for x in ((select 'Deputatsvergütungen') order by Datum)[Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr] do
                    let result := 0;
                    let comparison := x.Deputatsgrund.Deputatsgrund + "#" + x.'Ergänzung Deputatsgrund';
                    if comparison = i then
                        result := x.number(Nr);
                        result
                    end
                end)
        end;
    for y in resultAry do
        record('Deputatsvergütungen',y)
    end
    
    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hi Maurice. Ich denke, daß beide Varianten (Deine und meine) noch fehlerhaft sind. Bei besagter Person 552 fehlt bei Dir noch der Deputatsgrund 20 ohne Ergänzungsgrund (Datensatz 37 in der Tabelle Deputatsgründe). Es müßten also 3 Datensätze mit Deputatsgrund 20 und 2 DS mit 21 geben. Bei mir war es noch ungenau, weil ich den Vergleich mit dem Feld 'geleistet im SJ' noch nicht getätigt habe. Habe es jetzt hinzugefügt. Versuche mal  dies:

    let thisone := this;
    let thisPID := this.Personal.'Pers-ID';
    let thisSchuljahr := 'Deputat SJ'.Schuljahr;
    let isolate := unique((select 'Deputatsvergütungen')[Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr].(Deputatsgrund.Deputatsgrund + "#" + 'Ergänzung Deputatsgrund' + "#" + 'geleistet im SJ'));
    let resultAry := for i in isolate do
            last(for x in ((select 'Deputatsvergütungen') order by Datum)[Person.'Pers-ID' = thisPID and 'Deputat SJ'.Schuljahr = thisSchuljahr] do
                    let result := 0;
                    let comparison := x.Deputatsgrund.Deputatsgrund + "#" + x.'Ergänzung Deputatsgrund' + "#" + x.'geleistet im SJ';
                    if comparison = i then
                        result := x.number(Nr);
                        result
                    end
                end)
        end;
    for y in resultAry do
        record('Deputatsvergütungen',y)
    end
    

    Was die Geschwindigkeit betrifft, denke ich, dass es keine Probleme geben wird, da es keine verschachtelten Schleifen sind, sich also die Laufzeit nicht potenziert. Ich würde aber im Zweifelsfall die Variante mit dem richtigen Ergebnis wählen ;-). Mirko

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Vorletzter Satz ist Quatsch. Sind natürlich zwei verschachtelte for-Schleifen. 

    • Maurice
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Mirko, erstmal an dieser Stelle herzlichen Dank für deine Mühen. Mir ist das Prinzip über den Vergleich der Tripel (Deputatsgrund#Ergänzung#geleistet im SJ) klar geworden. Da wäre ich nie drauf gekommen, diese erst über unique zu definieren/herauszulesen und dann über die Datumsanordnung den letzten Eintrag auszumachen.

    In der DB führen die beiden Zugänge (meiner und deiner) (immer) noch zu versch. Ergebnissen (und ich weiß bis jetzt noch nicht wieso, weil mir dein Ansatz einleuchtet). Vielleicht gehen wir von versch. Zielsetzungen aus.

    Ich gehe an dieser Stelle auf die persönliche Kommunikation über, weil ich denke, dass das Grundprinzip für die Interessierten bzw. die Suchenden klar geworden ist. Ich melde mich. Für mich ist gewinnbringend, wie andere Zugänge aussehen können (die mir nicht selbst aktiv gelingen würden), um sie in anderen Settings anwenden zu können.

    Grüße Maurice

    • Maurice
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Korrektur meinerseits: dein Code, Mirko, funktioniert auch. Hatte da bei Copy&Paste was verkehr gemacht. Wie gesagt: habe selbst nicht verstanden, warum er nicht funktionieren sollte. Prima, danke.