0

Wert jedes Monatsletzten aus Tabelle in eine neue Tabelle schreiben

Hallo - bitte um kurze Unterstützung zu folgendem Thema.

Durch excel import habe ich viele Stromzähler Werte, diese sind sehr viele Werte, viel zu viele.  Jetzt möchten wir nur den letzten Wert jedes Monats in eine neue Tabelle schreiben. In dieser neuen Tabelle soll dann nur 1 wert jedes letzten Monats eingetragen sein. Es geht um PV-Zähler Werte die mittels csv Datei importiert werden und über Ninox verwaltet werden.

Tabelle 1: = Source = import von Excel –hier gibt es einen Button import, der dann die Werte vom Monatsletzten in eine neue Tabelle (Zähler) schreibt.

Tabelle 2: = Zieltabelle = Zählertabelle mit Werten nur des jeweiligen Monatsletzten.

Inhalt von dem Import Button:

Hier nimmt er mir meistens den Monatsletzten, es sind leider aber manchmal auch andere Werte vom Monat drinnen.... bitte um Hilfe

do as server
    for a in select import do
        let d := date(year(a.Datum), month(a.Datum) + 1, 1) - 1;
        let x := format(d, "DD");
        let checkexist := last(select 'Zähler' where d = a.Datum or last(Datum) = unique(max(a.Datum)));
        if not checkexist then
            let crePV := (create 'Zähler');
            crePV.(
                Datum := a.Datum;
                Wert := a.Zahl
            )
        end
    end
end

 

Vielen Dank

15 Antworten

null
    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Bernhard_F  Kannst du eine Dummy-DB mit csv-Werten zur Verfügung stellen, damit man mal sehen kann, wie sich die Excel Daten zusammensetzen?

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

     Bernhard_F

    Probiere mal folgendes Script:

    for a in select Import do
        let d := date(year(a.Datum), month(a.Datum) + 1, 1) - 1;
        if a.Datum = d then
            if cnt((select 'Zähler')[Datum = d]) = 0 then
                let crePV := (create 'Zähler');
                crePV.(
                    Datum := a.Datum;
                    Wert := a.Zahl
                )
            end
        end
    end

    • Bernhard_F
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo UweG!

    BINGO, vielen, vielen DANK - funktioniert auf Anhieb!!
    SUPER

    • Bernhard_F
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo UweG!
    Hallo community, ein Problem gibt es noch, welches ich noch nicht lösen konnte.

    Mit Deiner Lösung bin ich einen großen Schritt weiter gekommen. Jetzt habe ich noch das Problem, wenn mehrere Werte am letzten Tag im Monat sind, nimmt er allerdings aktuell die 1. Zahl vom letzten Tag im Monat, ich bräuchte hier immer die letzte Zahl im Monat.

    Hier die Beispiel Datenbank:
    https://app.ninox.com/#/teams/cZRtHt9HkFRu7FyX9/database/bbw5osuutnju/module/home/view/tables

    in der „Import „Tabelle gibt es jetzt einen neuen Button „Schritt weiter“. Dieser macht prinzipiell schon das was er soll, ein Punkt ist jedoch noch nicht ganz richtig.

    Aufgabe:
    Der Button „Schritt weiter“ in der Import Tabelle, importiert jeweils eine Zahl vom letzten Tag im Monat. Wenn mehrere Werte am letzten Tag im Monat sind, nimmt er allerdings aktuell die 1. Zahl vom letzten Tag im Monat, ich bräuchte hier immer die letzte Zahl im Monat.

    Der button macht folgendes:
    source: -> Import Tabelle:

    Datum:                 Zahl:
    24.05.22              55
    31.05.22              58
    31.05.22              59
    01.06.22              60
    03.06.22              68
    30.06.22              72
    03.07.22              89
    31.07.22              105

    Nach Aufruf des „Schritt weiter“ Buttons stehen dann in der Tabelle Zähler folgende Werte:

    Target: -> Zähler Tabelle: 
    31.05.22              58
    30.06.22              72
    31.07.22              105
    31.08.22              125
    ...

    Am 31.05.22 sollte 59 in der Zähler Tabelle stehen, nicht 58 -  eben der letzte Werte an diesem Tag.

    Im Echtbetrieb gibt es viele Zählereinträge am gleichen Tag, deshalb bräuchte ich dann immer den letzten Wert an diesem Tag, aktuell nimmt er den 1. Wert an diesem jeweils letzten Tag im Monat.

    Vielen Dank

      • UweG
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Bernhard_F Probiere mal folgendes:

      do as server
          for a in ((select Import) order by Zahl * -1).Nr do
              let d := date(year(a.Datum), month(a.Datum) + 1, 1) - 1;
              if a.Datum = d then
                  if cnt((select 'Zähler')[Datum = d]) = 0 then
                      let crePV := (create 'Zähler');
                      crePV.(
                          Datum := a.Datum;
                          Wert := a.Zahl
                      )
                  else
                      "// Prüfe, ob nachträglich an diesem Tag ein größßerer Wert in der Import-Tabelle eingetragen wurde und ersetze Ihn ggf. ";
                      if first((select 'Zähler')[Datum = d]).Wert < a.Zahl then
                          first((select 'Zähler')[Datum = d]).(Wert := a.Zahl)
                      end
                  end
              end
          end
      end

      Prämisse ist, das die Importtabelle absteigend nach dem Zählerstand sortiert wird bevor sie die Schleife durchläuft. 
      Damit ist beim Vergleich, ob das Datum bereits in der Tabelle Zähler vorhanden ist, der höchste, eingetragene Wert der Erste aus der Liste, der übernommen wird.
      Darüber hinaus wird geprüft, ob nachträglich für ein in Tabelle 'Zähler' vorhandenes Datum ein Zählerstand mit größerem Wert importiert wurde und dieser größere Wert eingetragen.
       

      • UweG
      • vor 2 Jahren
      • Gemeldet - anzeigen

      UweG 
      Man kann das .Nr weglassen und es so schreiben:

      for a in (select Import) order by Zahl * -1 do

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Versuche doch mal so. Es ist Uwes Script erweitert um Deinen Wunsch. Mirko

    let uniqueDate := unique((select Import).Datum);
    let maxNr := for i in uniqueDate do
            max(for x in (select Import)[Datum = i] do
                    x.number(Nr)
                end)
        end;
    for i in maxNr do
        let rI := record(Import,i);
        if rI.date(year(Datum), month(Datum) + 1, 0) = rI.Datum and count((select 'Zähler')[Datum = rI.Datum]) = 0 then
            (create 'Zähler').(
                Datum := rI.Datum;
                Wert := rI.Zahl
            )
        end
    end
    
    • Bernhard_F
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Vielen Dank für die sehr kreativen Lösungen!
    Prinzipiell funktioniert es jetzt, allerdings überspringt das Script von

    UweG bei meinen Echtdaten die Monate 10,11,12 - von
    Mirko bei meinen Echtdaten die Monate 11, 12
    Der Jänner (01) ist dann mit beiden Scripts wieder vorhanden.

    Ich glaub an den Daten liegt es nicht, an dieser Stelle einen Riesen Respekt !!!!

    Vielen Dank

    • Bernhard_F
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Vielleicht liegt es auch an meinen Zähler Zahlen, wenngleich ich bis jetzt noch keinen Fehler bei den Quellzahlen sehen konnte, mal schauen ob ich noch etwas entdecke :).

      • UweG
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Bernhard_F Kannst du mal die vollständige Import-Tabelle reinstellen.
      Ich habe es in der Beispiel-DB mit einem kompletten Jahressatz getestet und dort werden alle 12 Monate übernommen. 
      Ohne prüfen zu können, wie die Tabelle mit dem vollständigen csv-Import aussieht ist es schwer nachzuvollziehen, warum die Script nicht das gewünschte Ergebnis liefern. 

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Bernhard_F  Kannst du mir bitte eine Bsp-csv mailen, die du importierst.
    Dann kann ich das mal testen.

    foren.uwe@gmx.de

    • Bernhard_F
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Uwe

    Ich hab es dir geschickt.
    Ich denke ich habe den Grund gefunden, es lag teilweise tatsächlich an den Daten, nur der Oktober funktioniert bei der Uwe Abfrage noch nicht.

    Die Mirko Abfrage funktioniert jetzt.

    Vielleicht wäre es doch super, wenn auch geprüft wird, wenn am letzten Tag im ausgewählten Monat keine Daten da sind, dann nimm die letzten vorhandenen Daten vom ausgewählten Monat. Bei deinem Script gefällt mir die Funktion:

    // Prüfe, ob nachträglich an diesem Tag ein größerer Wert in der Import-Tabelle eingetragen wurde und ersetze Ihn ggf. "

    Wenn das Script dann zu einem späteren Zeitpunkt läuft, und neue Daten im ausgewählten Monat vorhanden sind, würde es diese aktualisieren...

    Vielen Dank für Eure Bemühungen, da steckt schon sehr viel Erfahrung dahinter :)

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Ich habe das Script angepasst, da ich gesehen habe, dass du Berechnungen mit den erstellten Werten durchführen möchtest und die Reihenfolge der Recorderstellung dabei wichtig ist.
    Zusätzlich habe ich dir ein csv-Importmodul mit einem Bildfeld erstellt, in das du die csv reinkopierst. Per Button werden dann die Daten in die ImportTabelle eingefügt.
    Ich habe mal Mirkos sehr gutes Script und meines nebeneinander gestellt.
    Die Ergebnisse sind völlig identisch. Du hast also die Auswahl.
    Die Prüfung auf nachträglich vorhandene Daten mit größerem Wert funktioniert auch.

    Den Punkt: Vielleicht wäre es doch super, wenn auch geprüft wird, wenn am letzten Tag im ausgewählten Monat keine Daten da sind, dann nimm die letzten vorhandenen Daten vom ausgewählten Monat.

    habe ich nicht mehr berücksichtigt.

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Vielleicht so?

    do as server
        let uniqueYM := unique((select Import).yearmonth(Datum));
        let maxNr := for i in uniqueYM do
                let maxiImp := max((select Import)[yearmonth(Datum) = i].Datum);
                let maxiZael := max((select 'Zähler_Mirko')[yearmonth(Datum) = i].Datum);
                if maxiImp >= maxiZael then
                    delete (select 'Zähler_Mirko')[yearmonth(Datum) = i]
                end;
                max((select Import)[yearmonth(Datum) = i and Datum = maxiImp].number(Nr))
            end;
        for i in maxNr do
            let rI := record(Import,i);
            (create 'Zähler_Mirko').(
                Datum := rI.Datum;
                Wert := rI.Zahl
            )
        end
    end
    
    • Bernhard_F
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo UweG!
    Hallo Mirko!

    Vielen herzlichen Dank für Euren großartigen Einsatz!
    Zwischenstatus

    UweG
    vielen Dank für die Bereitstellung, auch mit dem csv-import Modul, wusste nicht das so etwas möglich ist, eine coole Optimierung. Ich muß noch weiter testen :), ich bekomme beim csv-Importmodul nach einiger Zeit während dem Import - folgende Meldung: "Der Server antwortet nicht, bitte prüfen Sie ihre Netzanbindung..." auch mit dem bereits "embedded csv". dann ist der csv import abgebrochen.
    Wenn ich das csv file manuell importiere fehlen dann in der Zähler Tabelle die Daten vom Oktober... muß ich noch genauer ansehen, alle anderen Daten sind da - wollte mich zwischendurch herzlich bedanken :=). Die Daten werden denke ich schon wo sein :)

    @Mirko
    auch Dir vielen herzlichen Dank für Deine Bemühungen. Dein letzter Post löst jetzt auch das Problem, falls Daten in einem Monat, nicht bis zum Monatsletzten vorhanden sind, dann nimmt er die vorhandenen Daten. - GENIAL - ich muß das Script allerdings noch öfters lesen, um es irgendwie zu verstehen :=).
    jedenfalls sind alle Daten wie gewünscht in der Zähler Tabelle!!