0

JSON Datengruppierung aus ninox Tabelle/Abfrage für externe API Anbindung

Guten Morgen, ich bin wieder mal an einem Punkt angekommen, bei dem ich etwas externe Hilfe für die Lösung meiner Problematik benötige. Ich möchte über einen POST eine externe API mit Daten aus einer ninox Tabelle beliefern. Wie das für einzelne Datensätze funktioniert, ist mir soweit klar. Nun möchte ich aber Datensätze über Gruppierungen und Summen zusammenfassen und lediglich diese Werte per JSON an die Drittapplikation senden. 

Hier ein Beispiel:

Ich habe eine Tabelle A mit den Feldern Zahl, Gruppe und Datum. Nun möchte ich z.B. über eine Abfrage auswerten, wie die Summe der Zahlen der Gruppen je Datum ist. Als Ergebnis hätte ich dann gerne folgendes:  Summe des Feldes Zahl für Gruppe A,B usw. gruppiert nach Datum (Jan.,Feb.,usw.). Diese Daten würde ich dann im JSON Post an die externe Applikation senden. 

So sieht ein Teil des JSON-Ergebnisses aus, welches ich aus der Tabelle/Abfrage generieren müsste:

data: {
labels: ['January', 'February', 'March', 'April', 'May'],
datasets: [{
label: 'Dogs',
data: [ 50, 60, 70, 180, 190 ]
}]
}

Wie könnte hier ein Lösungsansatz aussehen? Muss ich dafür eine temporäre Tabelle anlegend und die Werte da zunächst reinschreiben und diese dann nutzen, oder geht das einfacher?

Wenn das ganze funktioniert, wäre das übrigens eine elegante Möglichkeit Charts über das Drittsystem (Opensource) in ninox einzubetten und dann auch drucken zu können, was ja bisher im Druckgenerator nicht funktioniert. Zudem gibt es für die Charts diverse Gestaltungsmöglichkeiten (Layout, Farbe usw.). Sollte das klappen, werde ich mal eine Musterdatenbank aufsetzen, um das ans Forum zurückzugeben, welches mir bereits zahlreiche Unterstützung gegeben hat :-)....

Frank

14 Antworten

null
    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Frank
    Möchtest du nun wissen wie du die Werte für den JSON-Body ermittelst oder wie du mit den ermittelten Werten den JSON-Body erstellst?

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Ich habe mal dein JSON-Konstrukt an mein NodeRed gesendet um zu sehen wie es ankommt.
    Dabei habe ich den JSON-Body in Ninox wie folgt erstellt:
    let payloadJsonV3 := {
    data: {
    labels: ["January, February, March, April, May"],
    datasets: [{
    label: "Dogs",
    data: [50, 60, 70, 180, 190]
    }]
    }
    };
    Als ergebnis erhalte ich in NodeRed ab 'JSON:'  folgendes:(siehe Bild)
    Bildschirmfoto 2021-07-24 um 07.41.46I

    Ist es das, was als Ergebnis ankommen soll?

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Mein Fehler, ich habe gesehen, dass du die Monate auch als Array haben möchtest.
    Das Scrpt sieht dann wie folgt aus:
    let payloadJsonV3 := {
    data: {
    labels: ["January", "February", "March", "April", "May"],
    datasets: [{
    label: "Dogs",
    data: [50, 60, 70, 180, 190]
    }]
    }
    };

    und das Ergbnis dann so:
    Bildschirmfoto 2021-07-24 um 07.58.35

    • Pro BoutiquenFonds GmbH
    • Eichelfr
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Guten Morgen Uwe, vielen Dank für deine Unterstützung bei meinem Thema. Mir geht es in der Tat zunächst um die Ermittlung der Werte für den JSON Body, den ich dann per Post an die externe Applikation sende.

    Mir ist noch nicht klar, wie ich die Daten, die ich im Post benötige, über einen select aus meiner Grundtabelle (TabelleA) zusammenstelle. In obigem Beispiel benötige ich ja folgende Werte/Arrays zur Erstellung einer Grafik:

    1. Datum

    2. Label / Gruppe mit den eigentlichen Werten (Summen gruppiert nach Label/Gruppe)

     

    text(unique (select 'TabelleA'.year(Datum))) zaubert mir z.B. die Datumsgruppierung aus meiner Tabelle. Nun bräuchte ich natürlich noch die passenden Werte für diese Zeiträume für die jeweiligen Gruppen. Mit diesen Werten könnte ich dann den POST bestücken. Was dann notwendig ist, klappt bereits alles. Werte über POST an externe Applikation senden und die Applikation sendet einen Link mit der erstellten Grafik, die dann über ein Script in die ninox Tabelle geladen wird. Mir fehlt lediglich der erste Teil mit der Auswertung und Aufbereitung der Quelldaten und der Formatierung für den JSON-Post. Ich hoffe, das hilft etwas weiter. Ansonsten könnte ich auch mal eine Musterdatenbank basteln und posten.

    Frank

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Frank
    Eine Beispieldatenbank wäre für mich hilfreich. Bin mehr der Praktiker als Theoretiker.

    • Pro BoutiquenFonds GmbH
    • Eichelfr
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Uwe,

    habe mal hier eine kleine DB erstellt und hochgeladen. Hoffe der Zugriff klappt.

    Hier meine kurze Erläuterung zur DB:

    In der Tabelle Chart ist ein Button, der den Code für den POST an die externe API enthält. Darüber erfolgt dann der Chartaufbau und das rendern in der externen Applikation. In dem Bildfeld spiele ich dann die finale Chartdatei zurück.

    Die Quelldaten für den Chart befinden sich in der Tabelle Historie. Hier ist meine Idealvorstellung, dass ich in diesem Beispiel über das Datum und die Gruppe Summen über für Feld Volumen_EUR bilde und diese dann an die API über den POST sende. 

    https://www.dropbox.com/s/9yzacfnytg3cqr2/Test_Chart.ninox?dl=0

    Vielleicht geht das ja auch in der Form gar nicht, wie ich mir das vorstelle und ich muss doch eine temporäre Tabelle bauen, die die Summenbildung und Gruppierung übernimmt?

    Frank

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Frank
    Ich habe mir mal die DB angesehen.
    Verstehe ich es richtig?
    Wenn du eine Gruppe auswählst möchtest du alle Werte summiert nach dem Monat erhalten. Was ist, wenn die Monate verschiedene Jahreszahlen haben? Sollen alle Monate in dem Chart auftreten oder soll es eine Einschränkung (Beginn/Ende) geben oder nur für ein ausgewähltes Jahr? Oder sollen bei betätigen des Buttons die ermittelten Werte der gesamten Tabelle in ein entsprechendes JSON umgewandelt werden? Soll das JSON immer nur für eine Gruppe oder alle Gruppen erstellt werden? 

    • Pro BoutiquenFonds GmbH
    • Eichelfr
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Guten Morgen Uwe,

    danke, dass Du dich mit meinem Thema beschäftigst! In der Endversion würde ich mir vermutlich ein Dashboard bauen, in dem ich zumindest den Zeitraum auswählen könnte. Für meinen "Testfall" würde ich in der Tat gerne die das Datum (nach Jahr/Monat) und die Gruppen gruppieren und jeweils die Summe des Zahlenfeldes aufweisen. D.h. in dem Testfall sollen alle Werte der Tabelle in ein entsprechendes JSON umgewandelt werden (über alle Gruppen). Konkret würde das im "Testfall" so aussehen:

    Datum                 Gruppe                Volumen_EUR (summe)

    31.12.2019           Aktien                   123456 

    31.12.2019          Mischfonds              123456 usw. über alle bestehenden Gruppen

    ......

    30.06.2021          Aktien                      123456

    30.06.2021          Mischfonds                123456 

     

    Ich hoffe, die Erläuterung hilft beim Verständnis...

     

    Frank

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Frank.
    Ich bin noch nicht dazu gekommen, werde mich aber diese Woche noch ransetzten. Ich schreibe, wenn ich was habe.

    • Pro BoutiquenFonds GmbH
    • Eichelfr
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Super nett, danke! Ich vermute, dass ich um eine temporäre Tabelle nicht herumkomme, bin aber für andere kreative Ideen natürlich sehr offen. Wenn das gut funktioniert werde ich die Datenbank für alle User zugänglich machen. Damit würden sich dann einige Probleme lösen lassen, die derzeit mit ninox Bordmitteln nicht umgesetzt werden können.

    So z.B. eigenes Corporate Design für grafische Auswertungen (bisher stehen lediglich die Standardfarben von ninox zur Verfüung). Wenn der Chart/die Grafik als Bild eingefügt wird, ist das ganze im Druckgenerator auch druckbar. Bisher ist das bei dem bestehenden Grafikeditor ja nicht möglich. Und das Schöne an der externen API ist, dass es sich um Open Source handelt.

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Frank
    Ich habe was gebaut, was dir die x- und y-Achse für die eine ausgewählte Gruppe  ermittelt.(Hier Aktien)
    Ich habe mal getestet, wie es als JSON in NodeRed ankommt.
    Eine Version gibt die x-Achse als Jahr/Monat wieder im Textformat:

    Bildschirmfoto 2021-07-29 um 07.47.12

    ScriptCode hierfür:

    'Ergebnis Volumen_EUR' := null; -> {Neu angelegtes Textfeld(mehrzeilig)}
    'Ergebnis Datum' := null; -> {Neu angelegtes Textfeld(mehrzeilig)}
    let v_yAchse := text(Auswahl); -> {Neu angelegtes Auswahlfeld mit den Gruppennamen}
    let xAchseJahrMonat := unique(((select Historie) order by Datum)[Gruppe = v_yAchse].yearmonth(Datum));
    let 'vArrayZähler' := cnt(xAchseJahrMonat);
    let AbfrageArray := [];
    let yAchse := [];
    for i from 0 to 'vArrayZähler' do
    AbfrageArray := sum(((select Historie) order by Datum)[Gruppe = v_yAchse and yearmonth(Datum) = item(xAchseJahrMonat, i)].Volumen_EUR);
    let BindingArray := array(yAchse, AbfrageArray);
    yAchse := BindingArray
    end;
    'Ergebnis Volumen_EUR' := join(yAchse, ",");
    'Ergebnis Datum' := join(xAchseJahrMonat, ",")

    Die andere Variante gibt die x-Achse nur als Jahr wieder im Zahlenformat:

    Bildschirmfoto 2021-07-29 um 10.07.20

    ScriptCode hierfür:

    'Ergebnis Volumen_EUR' := null;  -> {Neu angelegtes Textfeld(mehrzeilig)}
    'Ergebnis Datum' := null;  -> {Neu angelegtes Textfeld(mehrzeilig)}
    let v_yAchse := text(Auswahl); -> {Neu angelegtes Auswahlfeld mit den Gruppennamen}
    let xAchseJahrMonat := unique(((select Historie) order by Datum)[Gruppe = v_yAchse].yearmonth(Datum));
    let 'vArrayZähler' := cnt(xAchseJahrMonat);
    let AbfrageArray := [];
    let yAchse := [];
    for i from 0 to 'vArrayZähler' do
    AbfrageArray := sum(((select Historie) order by Datum)[Gruppe = v_yAchse and yearmonth(Datum) = item(xAchseJahrMonat, i)].Volumen_EUR);
    let BindingArray := array(yAchse, AbfrageArray);
    yAchse := BindingArray
    end;
    let DurchlaufNurJahr := cnt(xAchseJahrMonat);
    let xAchseNurJahr := [];
    let AbfrageArrayNurJahr := [];
    for i from 0 to DurchlaufNurJahr do
    AbfrageArrayNurJahr := number(substr(item(xAchseJahrMonat, i), 0, 4));
    let BindingArrayNurJahr := array(xAchseNurJahr, AbfrageArrayNurJahr);
    xAchseNurJahr := BindingArrayNurJahr
    end;
    'Ergebnis Volumen_EUR' := join(yAchse, ",");
    'Ergebnis Datum' := join(xAchseNurJahr, ",");

    Damit erhälst du die Array's für die X- und Y-Achse des Charts.
    Du musst es nur noch sehen, wie du die beiden Variablen in den ChartBody bekommst.
    Ein Beispiel hierfür wäre vielleicht:
    ChartText := "{ type: 'bar', data: { labels: [" + join(xAchseNurJahr, ",") + "], datasets: [ { label: '" + v_yAchse + "', data: [" + join(yAchse, ",") + "], }, options: { scales: { yAxes: [ { ticks: { callback: (val) => { return val + 'k'; }, }, }, ], }, }, }";  -> {Neu angelegtes Textfeld(mehrzeilig)}
    Ich kenne mich mit quickchart nicht aus und weiss deshalb nicht in welchen Formaten die X- und Y-Werte übertragen werden müssen., deshalb musst du eventuell die Formate gemäß Quickchart-Vorgabe noch anpassen.
    In den Textfeldern(Mehrzeilig) siehst du die Ergbnisse der Abfrage.
    Ein Hinweis zu deinem Zahlenfeld in der Tabelle. Du solltest beim Zahlenformat das Dezimaltrennzeichen auf Punkt setzen wenn du keine ganzen Zahlen benutzt.

    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen
    • UweG
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Frank

    Habe festgestellt, dass man den Button 'Chart abfrufen'  nochmal drücken muss, bevor die Änderung übertragen wird.

    Weiss nicht weshalb. Wirst du aber sicherlich rausfinden.

    • Pro BoutiquenFonds GmbH
    • Eichelfr
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo lieber Uwe, herzlichen Dank für die grandiose Unterstützung, echt unschlagbar! Ich schau mir das in den nächsten Tagen an und hoffe, dass ich das weiter vorantreiben kann. Wenn das Muster durch ist, werde ich versuchen mal eine Datenbank zu bauen, die für andere Nutzer hoffentlich auch hilfreich ist.

    Frank

Content aside

  • vor 2 JahrenZuletzt aktiv
  • 14Antworten
  • 892Ansichten