3

Auswertung von Daten, evaluation, Klassenhäufigkeit

Hi Freunde von optischer Datenauswertungen. Ich teile hier mal eine Idee für eine Möglichkeit der Darstellung von Daten in Ninox. Ich habe an anderer Stelle

https://forum.ninox.de/t/q6hw503/statistik-klassenhaufigkeit

schon ähnliches gepostet, das war aber eher für statistische Auswertung eines Merkmals in Klassen gedacht und nicht für zwei Parameter.

Hier habe ich sie mal erweitert und erkläre kurz. Am Beispiel einer Tabelle mit Rechnungspositionen werden hier die Merkmale Preis und Menge/Anzahl gewählt. Um übersichtlich darzustellen, welcher Umsatz in welcher Preisklasse generiert wurde, ist also beides zu berücksichtigen. Die Tabelle gibt also vollständig wieder, welche Mengen bestimmter Produkte im Preissegment verkauft (eingekauft) wurden und wie hoch das gesamte, in dieser Preisklasse generierte Umsatzvolumen ist.

Datensätze die in Anzahl oder Preis "0" enthalten, bleiben in der Rechnung aussen vor.

Die beiden Auswahlfelder darüber bestimmen die Anzahl der Klassen, was also die Preisklassen weitet oder einengt und die Jahre, falls man diese Splittung wünscht.

In der Preisklasse ist die untere Grenze exclusive und die obere inklusive. Der oberste Wert der letzten Preisklasse wird rechnerisch bestimmt und liegt stets leicht oberhalb des Wertes des teuersten Produkts.

Das rote Feld gibt den niedrigsten Wert für Umsatz und Anzahl an und der grüne natürlich den höchsten. Hat man also rot für Umsatz und grün für Anzahl in einer Zeile, bedeutet dies also unter Umständen viel Aufwand für wenig Wolle.

Ich habe meine Dummydatei mit ca. 4000 DS benutzt. Die Geschwindigkeit in der web-app ist bei mir okay, auf dem Mac und Ipad fast ohne Verzögerung.

Die Benutzung für beliebige Tabellen ist denkbar einfach. Alle Variablen bis zur gestrichelten Linie sind anzupassen: Tabellenname, Feldnamen für Preis und Anzahl. Die Tabelle sollte ein Datumsfeld enthalten, wenn die Version für die Jahresunterscheidung benutzt wird. Wer die komplizierte Variante nicht mag, kann auf dem zweiten Tabulator das Script für die stand-alone-Version wählen und in ein beliebiges Funktionsfeld, auch im Dashboard einfügen. Ich habe zwar die Daten mit unabhängigen Funktionsfeldern geprüft und durch Filter in der Tabellenversion und keine Fehler mehr gefunden, aber wer weiß… Ich lege eine Datei bei und wer die nicht downloaden möchte, kann ganz unten das "einfache" Script zum probieren kopieren. Wie immer wäre ich dankbar, wenn mich jemand auf Fehler hinweist. Mirko

 

"1. select 2. Feldname für Preis, 3. Feldname für Anzahl, 4.Einheit des Datenfelds";
let selectionOfTable := (select TABELLE)[PREIS != null or ANZAHL != 0];
let price := "PREIS";
let quantity := "ANZAHL";
let unit := " €";
let cntClass := 5;
"------------------------------------------------------------------------------------------------";
"Bestimmung des oberen Grenzwertes der letzten Range";
let lastRange := round(number(max(selectionOfTable.eval(---
{ price }
---, this))) + 1);
while lastRange % cntClass != 0 do
    lastRange := lastRange + 1
end
;
"Bestimmung des Abstands der Ranges";
let rangeDistance := lastRange / cntClass;
"Arraybildung der Absolutwerte von sum(price * quantity) in den Ranges";
let resultSum := for i in range(rangeDistance, lastRange + 1, rangeDistance) do
        let lowerBound := i - rangeDistance;
        round(number(sum(for j in selectionOfTable do
                if j.eval(---
{ price }
---, this) <= i and j.eval(---
{ price }
---, this) > lowerBound then
                    number(j.eval(---
{ price }
---, this)) * number(j.eval(---
{ quantity }
---, this))
                end
            end)), 1)
    end;
"Arraybildung der Absolutwerte von sum(quantity) in den Ranges";
let resultCnt := for i in range(rangeDistance, lastRange + 1, rangeDistance) do
        let lowerBound := i - rangeDistance;
        sum(for j in selectionOfTable do
                if j.eval(---
{ price }
---, this) <= i and j.eval(---
{ price }
---, this) > lowerBound then
                    number(j.eval(---
{ quantity }
---, this))
                end
            end)
    end;
"Arraybildung der Relativwerte von sum(price * quantity) in den Ranges";
let resultRelativeSum := for i in resultSum do
        round(i / sum(resultSum) * 100, 1)
    end;
"Arraybildung der Relativwerte von sum(quantity) in den Ranges";
let resultRelativeCnt := for i in resultCnt do
        round(i / sum(resultCnt) * 100, 1)
    end;
"Bildung der Ranges";
let rangeParts := unique(for i in range(0, lastRange, rangeDistance) do
            "[" + lpad(text(i), 3, "0") + " - " + lpad(text(i + rangeDistance), 3, "0") + "]" + unit
        end);
"Die nächsten 4 Funktionen dienen der Einfärbung der Zelle für den niedrigsten oder höchsten Wert";
let sumGreen := number(for i in range(0, length(resultSum)) do
        if item(resultSum, i) = max(resultSum) then
            i + 1
        end
    end);
let cntGreen := number(for i in range(0, length(resultCnt)) do
        if item(resultCnt, i) = max(resultCnt) then
            i + 1
        end
    end);
let sumRed := number(for i in range(0, length(resultSum)) do
        if item(resultSum, i) = min(resultSum[!= 0]) then
            i + 1
        end
    end);
let cntRed := number(for i in range(0, length(resultCnt)) do
        if item(resultCnt, i) = min(resultCnt[!= 0]) then
            i + 1
        end
    end);
let content := "
<style>
table {
    width:100%;
    background-color: #999;
    border-radius: 2.3em  2.3em  2.3em  2.3em;
}
.right   { text-align: right; }
.left   { text-align: left; }

td,th{
    padding: .3em 1em .3em 1em;
}

td {
    font-family: Courier;
    font-size: medium;
    background-color: #eee;
}
th {
    font-family: Garamond;
    font-size: large;
    text-align:center;
    background-color: #aaa;
}
thead tr:nth-of-type(1) th:nth-of-type(1)  {
      border-radius: 1.5em 0em 0em 0em;
}
thead tr:nth-of-type(1) th:nth-of-type(4)  {
    border-radius: 0em 1.5em 0em 0em;
}
tfoot tr:nth-of-type(1) th:nth-of-type(1){
    border-radius: 0em 0em 0em 1.5em;
    }
tfoot tr:nth-of-type(1) th:nth-of-type(3){
    border-radius: 0em 0em 1.5em 0em;
    }
tr:nth-child(odd) td{
      background-color: #ccc;
}

tbody tr:nth-of-type(" + cntRed + ") td:nth-of-type(5){
    background-color: #c82f04 ;
    }
tbody tr:nth-of-type(" + sumRed + ") td:nth-of-type(3){
    background-color: #c82f04  ;
    }
tbody tr:nth-of-type(" + cntGreen + ") td:nth-of-type(5){
    background-color: #93b946 ;
    }
tbody tr:nth-of-type(" + sumGreen + ") td:nth-of-type(3){
    background-color: #93b946 ;
    }
</style>
<table>
    <thead>
        <tr>
            <th></th>
            <th> Preisspanne </th>
            <th scope='colgroup' colspan='2'> Umsatz pro Preisspanne </th>
            <th scope='colgroup' colspan='2'> Anzahl pro Preisspanne </th>
        </tr>
    </thead>
    <tbody>
                " + for i in range(0, cntClass) do
        "<tr><td class = 'center'> " + (i + 1) + " </td><td class = 'center'> " + item(rangeParts, i) + " </td><td class= 'right'> " + item(resultRelativeSum, i) + "&#37;" + "</td><td class= 'right'> " + format(item(resultSum, i), "#,##0.00") + unit + " </td><td class= 'right'> " + item(resultRelativeCnt, i) + "&#37;" + " </td><td class= 'right'> " + item(resultCnt, i) + " </td></tr>"
    end + "
    </tbody>
    <tfoot>
        <tr>
            <th></th>
            <th scope='colgroup' colspan='3' class = 'right'> " + "&#8721; " + format(sum(resultSum), "#,##0.00") + unit + "</th>
            <th scope='colgroup' colspan='2' class = 'right'>" + "&#35; " + sum(resultCnt) + " </th>

        </tr>
    </tfoot>
</table>
";
html(content)

11 Antworten

null
    • Rafael_Sanchis
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hi Mirko 

    Hi.
    One think I hope you undersatd me, I need the Preisspanne ( PriceRange) when select class don't change the range I need place only the right price. That is possible.

    Thanks
     

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hi Rafael. Unfortunately, I don't understand what you're writing. My English skills are limited to simple facts. Do you think, that you only want to see the upper price limit in the Price Range column? Mirko

      • Rafael_Sanchis
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Mirko Hi Mirko something like that, no range Price.

      Preisspanne 2022
       
      20 €
      35 €
      45 €
      75 €
      120 €
    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hi Rafael. Look for this in code...

    "Bildung der Ranges";
    let rangeParts := unique(for i in range(0, lastRange, rangeDistance) do
                "[" + lpad(text(i), 3, "0") + " - " + lpad(text(i + rangeDistance), 3, "0") + "]" + unit
            end); (empty)

    ...and change it to

    "create the upper price limit";
    let rangeParts := unique(for i in range(0, lastRange, rangeDistance) do
                lpad(text(i + rangeDistance), 3, "0") + unit
            end);
    

    Change the name of headline "Preisspanne" to. Mirko

      • Rafael_Sanchis
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Mirko Excelent Appreciate your help.👍

      • Rafael_Sanchis
      • vor 2 Jahren
      • Gemeldet - anzeigen

       Mirko

      Hi Mirko again one help 

      In the Dashboad Tab I need place the data in the table Staff_Project the field Tarifa, Ihave no more than 10 Tarifas, but maybe yes more Staff with the same Tarifa. No need a range need the exact value, is possible.

      thank.

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hi Raphael. Sure it is possible, but, my formula, which I have provided here, is a statistical way to study frequencies in statistical bins, in german: classes. These bins are calculated, not fixed. That was my intention. You need something else. For example, a simple categorical order with subsequent frequency of a numeric variable, or sum of two numeric variables. Mirko

      • Rafael_Sanchis
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Mirko 

      sorry Mirko I'm a bit annoying, the only I need is a simple categorical order, the info on Staff_Project (Tarifa) Rate show on the first column of your table. 

      Please, if possible, if not, I don't want you to waste time on this. You have already helped me a lot in other posts.

      Thanks.

      • mirko3
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Rafael Sanchis  No Problem, no sorry. It was a little error in your script in the selection of the week. And in the rest of your post, i misunderstood you ;-). Try this, or continue your question. Mirko

      let xselect1 := number(text(SeleccionW));
      let selectionOfTable := (select Data)[TARIFE != 0 or HORAS != 0 and if xselect1 then
                          week(FECHA) = xselect1
                      else
                          true
                      end];
      let price := "TARIFE";
      let quantity := "HORAS";
      let unit := " €";
      .
      .
      .
      
      • mirko3
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Rafael Sanchis for year! and week.

      let xselect1 := number(text(SeleccionW));
      let xselect2 := number(text(Seleccion));
      let selectionOfTable := (select Data)[(TARIFE != 0 or HORAS != 0) and if xselect2 then
                          year(FECHA) = xselect2
                      else
                          true
                      end and if xselect1 then
                      week(FECHA) = xselect1
                  else
                      true
                  end];
      let price := "TARIFE";
      let quantity := "HORAS";
      let unit := " €";
      let cntClass := number(text(Filas));
      "------------------------------------------------------------------------------------------------";
      

      If week() used, you get a problem next year, because it is the same number of week. Better is, to use yearweek().

      • Rafael_Sanchis
      • vor 2 Jahren
      • Gemeldet - anzeigen

      Mirko Yes excellent now very well, works with weeks and year 👍

Content aside

  • 3 „Gefällt mir“ Klicks
  • vor 2 JahrenZuletzt aktiv
  • 11Antworten
  • 266Ansichten
  • 2 Folge bereits