0

Abhängig vom Feldinhalt eines Feldes einen entsprechenden Datensatz aus der verknüpften Tabelle suchen

Hallo liebes Ninox Forum, 

folgende Aufgabenstellung: 
Tabelle LOG (Logeinträge) mit den Feldern:  Nr, LogID, MStdLfd, .... 
Tabelle Betriebsmittel mit Feldern: Nr, Log.Nr, Betriebsmittel, Menge.... 
Tab Betriebsmittel ist über das Feld Log.Nr mit der Tab LOG verknüpft.
Die Tabelle Betriebsmittel enthält zB. folgende Einträge
Nr/Log.Nr/Betriebsmittel/Menge --> verknüpfte Tab LOG.MStdLfd
1/25/Diesel/90 --> Tab LOG: MStdLfd = 50
2/70/Motoröl/3--> Tab LOG: MStdLfd = 74
3/80/Diesel/55--> Tab LOG: MStdLfd = 86
....
in der Tab Betriebsmittel möchte ich nun den Betriebsmittelverbrauch je Betriebsmittel errechnen, die entsprechenden Stundenwerte sind in der Tab LOG unter MStdLfd enthalten. Um für den Datensatz 3 aus Tab Betriebsmittel den Dieselverbrauch zu errechnen, brauche ich die MStdLfd vom letzten Dieseleintrag - sprich Datensatz Nr 1 bzw 25 in der Tab LOG mit 50 Stunden. Die Rechnung wäre dann: 55 Liter / (86 -50 Std = 36 Std) = 1,5 L/h

Wie mach ich das am Besten? 
Danke für eure Tips
LG

8 Antworten

null
    • rainless
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Michael,

    zuerst mal kurz die Nachbildung Deiner Daten in Tabellen - ich weiß nicht, ob Du das auch so hast:

     

    Betriebsmittel ist eine Auswahl:

    Die Tabelle kommt dann so heraus:

    Dieselverbrauch/MStd ist als neue Spalte vom Typ formula angelegt und folgende Funktion ist dahinter:

    let prevVal := 0;
    let logno := LogNr.Nr;
    let log := (select LOG where Betriebsmittel.Betriebsmittel = 1 and Nr < logno);
    if count(log) > 0 then prevVal := first(log).MStdLfd end;
    format(Menge / (LogNr.MStdLfd - prevVal), "#,##0.00")
    

    Probier mal aus, ob das tut.

    • 46wcxg
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Lars, 
    danke mal für deine Mühe! Die Tabellen sehen soweit so aus wie meine, und ja Betriebsmittel ist eine Auswahl in der Tabelle Betriebsmittel! Hab deinen Code gerade ausprobiert, leider rechnet er falsch, aber immerhin rechnet er ja schon mal! 
    Die Variable 'logno' ist ok, zeigt auf den aktuellen Datensatz in der Tab Betriebsmittel.

    Die Variable 'log' müsste jetzt denjenigen Datensatz in der Tabelle Betriebsmittel suchen, der als Betriebsmittel "Diesel" (also 1) hat UND der dem aktuellen vorangeht- das kann aber einige Datensätze vorher sein --> Nr < logno ist richtig. 
    Ich habe jetzt deine Tabellen der Einfachheit nachgebildet und folgende Werte angesetzt: 

    Tabelle LOG

    weiten gezeigt die Tabelle Betriebsmittel. Ich habe jetzt mal irgendwelche Motorstunden angesetzt, da ich deine nicht kannte. 
    wie man unten an der Berechnung sieht rechnet der Code nicht richtig: 

    1. die ersten Datensätze müssten leer sein
    2. Berechnung 4. DS: 55/(281-245)=1,5l und nicht 0,2 Liter - weiß gar nicht wie er hier auf 0,2 kommt, dazu muss er mit 55/0,2 Stunden = 110 Stunden rechnen??? 

    • rainless
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Ok, es war etwas knifflig die Struktur nachzubilden. Die Motorstunden kamen aus Deinem Beispiel oben:

    • 1/25/Diesel/90 --> Tab LOG: MStdLfd = 50
    • 2/70/Motoröl/3--> Tab LOG: MStdLfd = 74
    • 3/80/Diesel/55--> Tab LOG: MStdLfd = 86

    Der Fehler bei mir war, dass ich nicht sauber die Einträge sortiere. Mit folgendem Code müsste es jetzt aber klappen und es wird auch nur noch für Diesel angezeigt. Sonst muss man noch etwas weiter aufbohren:

    let prevVal := 0;
    let logno := LogNr.Nr;
    let log := ((select LOG where Betriebsmittel.Betriebsmittel = 1 and Nr < logno) order by LogID);
    if count(log) > 0 then
        prevVal := first(log).MStdLfd
    end;
    if Betriebsmittel = 1 then
        format(Menge / (LogNr.MStdLfd - prevVal), "#,##0.00")
    else
        ""
    end

    Was die ersten Datensätze angeht: Ich habe einfach mal angenommen, dass dann der vorherige Wert bei 0 liegt (prevVal := 0 und keine Änderung mehr, wenn kein vorheriger Eintrag gefunden wird). Aber das kann man natürlich einfach anpassen: Wenn prevVal = 0 wird einfach "" ausgegeben:

    let prevVal := 0;
    let logno := LogNr.Nr;
    let log := ((select LOG where Betriebsmittel.Betriebsmittel = 1 and Nr < logno) order by LogID);
    if count(log) > 0 then
        prevVal := first(log).MStdLfd
    end;
    if Betriebsmittel = 1 and prevVal > 0 then
        format(Menge / (LogNr.MStdLfd - prevVal), "#,##0.00")
    else
        ""
    end

    Jetzt aber ... ?

      • 46wcxg
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Lars das mit den ersten und nicht Diesel Datensätze funktioniert jetzt, die Berechnung leider nein... schau meinen vorhergehenden Post an. In Zeile 3 muss die Bedingung "and Nr < logno.... weg, da sie keine Datensätze liefert. Wenn du das wegmachst, funktioniert die Berechnung, nur nimmt sie immer nur den ersten (first) Datensatz, was ja nicht richtig ist.... 
      mit der Bedingung... 

      ohne die Bedingung: 

      Ohne die Bedingung funktioniert die Berechnung des Datensatzes Nr 4. Die Berechnung DS Nr 5 ist wieder falsch.... Mit first nimmt er die 245 Stunden, mit last die 310 Stunden.... 

      • 46wcxg
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Lars Lieber Lars, vielen Dank für deine Idee! Ich habs folgendermaßen hinbekommen: 

      let prevVal := 0;
      let logno := LogNr;
      let log := ((select LOG where Betriebsmittel.Betriebsmittel = 1 and Betriebsmittel.LogNr < logno) order by LogID);
      if count(log) > 0 then
          prevVal := last(log).MstdLfd
      end;
      if Betriebsmittel = 1 and prevVal > 0 then
          format(Menge / (LogNr.MstdLfd - prevVal), "#,##0.00")
      else
          ""
      end
      

      Der Clou war in Zeile 3: < ... and Betriebsmittel.LogNr < logno...> und in Zeile 5 <.. := last (log).MstdLfd...> 

      Mit der kleinen Anpassung kommt folgendes richtige Ergebnis raus: 

      Danke nochmals und liebe Grüße

    • 46wcxg
    • vor 2 Jahren
    • Gemeldet - anzeigen

    ich hab den Code jetzt soweit geändert dass er zwar rechnet, aber dennoch den falschen Datensatz auswählt, mit first oder last wird immer nur der erste oder letzte statt denjenigen, der vom aktuellen DS der vorherige ist. Hier der Code der um dieses Faktum noch verbessert werden muss: 

    let prevVal := 0;
    let logno := LogNr.Nr;
    let log := (select LOG where Betriebsmittel.Betriebsmittel = 1);
    if count(log) > 0 then
        prevVal := last(log).MstdLfd
    end;
    format(Menge / (LogNr.MstdLfd - prevVal), "#,##0.00")
    
    • rainless
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Michael,

    aus irgendeinem Grund war ich ein Weilchen auf "on hold" und konnte nichts posten. Das mit dem last() habe ich auch schon entdeckt - da habe ich die Sortierung falsch herum gedacht. Final müsste es so funktionieren (bei mir jedenfalls):

    let prevVal := 0;
    let logno := LogNr.Nr;
    let log := ((select LOG where Betriebsmittel.Betriebsmittel = 1 and Nr < logno) order by LogID);
    if count(log) > 0 then
        prevVal := last(log).MStdLfd
    end;
    if Betriebsmittel = 1 and prevVal > 0 then
        prevVal + " " + format(Menge / (LogNr.MStdLfd - prevVal), "#,##0.00")
    else
        ""
    end
    

    Wahrscheinlich kann man "Nr < logno" lassen, aber ich habe noch etwas Zweifel.

    Freut mich, wenn ich helfen konnte.

      • 46wcxg
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Lars  "Nr < logno" lassen... kann sein, vlt hatte ich eine etwas andere Bezeichnung wo es bei mir nicht anders ging. Egal, funkt! Das ist wichtig. Merci nochmals