0

Durchlaufende Nummerierung auf Grundlage des Datenfelds “Auswahl” - interne Produkt-ID

Hallo,

ich möchte unserem Produktportfolio eine interne ID zuweisen. Es gibt drei verschiedene Produkttypen. Diesen weise ich dem Produkt bei der Erstellung eines neuen Datensatzes mittels Datenfeld “Auswahl” (bei mir: Typ) zu.

Was muss ich machen, dass nun für jeden Produkttyp eine durchlaufende Nummerierung erstellt wird? Derzeit schaffe ich es nur eine durchlaufende Nummerierung zu erreichen mit der Gesamtanzahl der Produkte in der Tabelle.

Zur Info: Die drei verschiedenen Typen starten immer mit “DE-”, “DI-” oder “S-”.

Hier meine laienhafter Ansatz:

let a := if Typ = 1 then “S-”
let b := if Typ = 2 then “DE-”
let c := if Typ = 3 then “DI-”
let x := if a then max(select “10 Produkte” where Typ = 1).number(substr(“ID - intern”, 3))
let y := if b then max(select “10 Produkte” where Typ = 2).number(substr(“ID - intern”, 3))
let z := if c then max(select “10 Produkte” where Typ = 3).number(substr(“ID - intern”, 3))
“ID - intern” := if a then a + format(x + 1, “00000”) else if b then b + format(y + 1, “00000”) else if c then c + format(z + 1, “00000”)

 

Danke für Eure Mithilfe!

22 Antworten

null
    • Ninox-Professional
    • planoxpro
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Hallo Benedikt, hier als Vorschlag mal ein etwas anderer Ansatz mit split() statt substr() zur Berechnung der ID: 

    let myT := switch Typ do
            case 1: “S”
            case 2: “DE”
            case 3: “DI”
        end;
    let myP := last(select “10 Produkte” where first(split(“ID - intern”, “-”)) = myT);
    let myN := number(last(split(myP.“ID - intern”, “-”))) + 1;
    “ID - intern” := myT + “-” + format(myN, “00000”)

    • Benedikt_Klein
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Vielen Dank! Läuft perfekt. Ich wollte eigentlich alles über eine Schaltfläche “Generieren” machen , aber jetzt mach ich es direkt über “Nach Änderungen folgendes Skript ausführen” in der Tabelle. Schon existierend Datensätze lassen sich auch schnell ändern. Danke nochmal.

    • Benedikt_Klein
    • vor 3 Jahren
    • Gemeldet - anzeigen

    irgendwas klappt doch noch nicht und zwar wird fortlaufende Nummer immer um 1 erhöht, sobald ich ein weiteres Feld ausfülle. Das mit den Kürzeln DI, DE und S klappt soweit. Kann mir jemand helfen?

    • Ninox-Professional
    • planoxpro
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Hallo Benedict, das o. a. Skript sollte als Trigger “Nach Änderung” im Auswahlfeld “Typ” laufen, nicht auf Tabellenebene. Denn dort wird es ja bei jeder Änderung des Datensatzes ausgeführt. Deshalb die Neuberechnung nach Ausfüllen weiterer Felder.

    • Torsten_Stang.1
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Hallo,

     

    wenn Du“s auf Tabellenebene unter “Nach Änderungen folgendes Skript ausführen” machst, dann so:

     

    if not ”ID - intern“ then
       let myT := switch Typ do
               case 1: “S”
               case 2: “DE”
               case 3: “DI”
           end;
       let myP := last(select “10 Produkte” where first(split(“ID - intern”, “-”)) = myT);
       let myN := number(last(split(myP.“ID - intern”, “-”))) + 1;
       “ID - intern” := myT + “-” + format(myN, “00000”)
    end

     

    lg, Torsten

    • Torsten_Stang.1
    • vor 3 Jahren
    • Gemeldet - anzeigen

    ... oder wie Copytexter sagt... :-)

    • Benedikt_Klein
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Vielen Dank, Ihr seid echt super. Habe das jetzt über das Auswahlfeld gelöst, aber das Skript von Torsten für die Kdnr genutzt.

    Ich hätte noch ein paar Ideen bzgl. der Produkt-ID:

    Sollte mal ein Produkt aus dem Portfolio rausgenommen werden, so wird die Produkt-ID wieder frei. Kann man diese dann als erstes wieder neu vergeben, wenn man einen neuen Datensatz anlegt?

    &

    Bzgl. Datensatz kopieren (Button oben rechts): Kann ich festlegen, dass der Datensatz die Produkt-ID und Typ leer lässt? Oder kann man festlegen, dass der Datensatz den Typ beibehält und die Produkt-ID dementsprechend fortlaufend weiterführt?

    Gruß,

    Benni

    • Ninox-Professional
    • planoxpro
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Moin Benedikt, zur Wiedervergabe frei gewordener IDs: Also, gehen würde das schon, aber - sorry, für die dumme Frage: Bist du dir sicher, dass du das wirklich willst? ;)

    Ich kenne deine Anwendung nicht, gehe aber mal davon aus, dass die Produkte (und damit auch ihre IDs) in irgendwelchen Unterlagen erscheinen oder innerhalb Ninox sogar mit anderen Tabellen verknüpft sind, z. B. mit Angeboten, Aufträgen oder Projekten. Dann kann es über kurz oder lang zu Problemen führen, wenn aus dem Produkt mit der ID XYZ plötzlich ein ganz anderes wird. Sowohl sachlich als auch technisch. IDs wie Kunden-, Auftrags- oder eben auch Artikelnummern sollten immer eindeutig sein. Das ist übrigens auch der Grund, warum die ninox-internen Datensatz-IDs nie neu vergeben werden, sondern frei bleiben, wenn der dazugehörige Datensatz gelöscht wurde.

    Ich will dir natürlich nicht reinreden, ist allein deine Entscheidung, wollte aber zumindest auf das Problem aufmerksam gemacht haben.

    Zu “Datensatz kopieren”: Die Ninox-eigene Funktion dupliziert den Datensatz 1:1 mit allen Inhalten. Wenn man das nicht will, dann kann man eine eigene Schaltfläche zum “Kopieren” in das Formular setzen und mit dem Code die Inhalte manipulieren. Wenn also ID und Typ im neuen Datensatz leer sein sollen, könnte das bspw. so aussehen:

     

    let newP := duplicate(this);
    newP.(“ID - intern” := null);
    newP.(Typ := null);
    openRecord(newP)

    • Benedikt_Klein
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Moin,

    ja, da hatte ich auch schon gedacht. Ist wahrscheinlich sinnvoller es nicht zu tun.

    Datensatz kopieren klappt super. Danke.

    • Nils
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Hey Copytexter, also ich benötige tatsächlich eine eindeutige ID für jeden Datensatz, die wieder vergeben wird, sollte ein Datensatz gelöscht werden.

    Wenn das nämlich passiert, dann existiert der Gegenstand hinter dem Datensatz nicht mehr in der "Sammlung".

    Wenn man mit ninox eine Sammlung verwaltet, ist das schon sinnvoll. Kannst du mir sagen wie ich das mache?

    • Ninox-Professional
    • planoxpro
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Hallo Nils, “eindeutig” wäre eine ID für mich nur dann, wenn sie NICHT neu vergeben wird. Ansonsten kann sie ja mehrere Bedeutungen haben, und sämtliche Bezüge zu Gegenstand A würden nach der Neuvergabe dessen ID auf Gegenstand B verweisen, was sachlich wie technisch zu Problemen führen kann. Deshalb werden Identifikatoren wie Kunden-, Artikel- und Personalnummern etc. in der Regel nie neu vergeben. Auch dann nicht, wenn der Bezug praktisch nicht mehr gegeben ist, z. B. weil der Artikel aus dem Sortiment genommen wurde oder der Mitarbeiter das Unternehmen verlassen hat. Zumeist wird der betreffende Datensatz aus Gründen der Nachvollziehbarkeit nicht mal wirklich gelöscht, sondern als “inaktiv” o. ä. gekennzeichnet. Das wäre vielleicht auch in deinem Fall zu überlegen.

    Sei“s drum. Um frei gewordene ID-Nummern gelöschter Datensätze ggf. neu zu vergeben, fällt mir jetzt nichts Besseres ein, als die Tabelle Satz für Satz zu durchlaufen, bis man auf eine nicht vorhandene Nummer stößt. Angenommen, die Tabelle heißt ”Sammlung“ und die Identifikationsnummer stünde dreistellig mit führenden Nullen in einem Textfeld namens ”IdNr“, dann könnte man es so versuchen:

     

    let myNr := min(select Sammlung).number(IdNr);
    let myLoop := true;
    while myLoop = true do
       myNr := myNr + 1;
       if cnt(select Sammlung where number(IdNr) = myNr) < 1 then
          myLoop := false
       end
    end;
    IdNr := format(myNr, ”000“)

     

    Bei größeren Datenmengen müsste man sich aber vielleicht eine effizientere Vorgehensweise mittels Array oder so überlegen.

     

    PS: Wenn Code hier aus dem Forum per Copy and Paste in den Ninox-Editor übernommen wird, müssen die Anführungszeichen dort neu eingetippt werden. 

    • Nils
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Hallo @Der Copytexter. Danke für dein Script. Vorab: Irgend etwas funktioniert damit noch nicht.

    Ich brauche das in der Tat eher als “Counter”. Da ist es dann egal dass die Zahl sich ändert. Ich habe noch ein zweites Feld, das eine Eindeutige ID enthält, die sich nie ändert und vom Datensatz ableitet.

    Zum Problem: 

    Das Script habe ich direkt in die Tabelle unter “Nach Änderung folgendes Script ausführen” gesetzt und auf meine Feld-/Tabellennamen abgeändert. Ist das korrekt? 

    Problem: Jedes mal wenn ich am Datensatz etwas ändere, schwankt die Zahl zwischen einer Zahl und der Zahl + 1. Also, z.B. 3 > 4 > 3 > 4 – nach jeder Änderung. 

    Ich vermute mal, das Skript muss unter “Bei neuem Datensatz folgendes Script ausführen” stehen, oder?

    • Nils
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Perfekt wäre es, wenn man dafür sorgen könnte, dass die Zahlen aktualisiert werden, sobald ich einen Datensatz lösche. Dass die Nummer sozusagen aufrückt um die Lücke zu schließen.

    • Ninox-Professional
    • planoxpro
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Ja, das o. g. Skript sollte als Trigger “Bei neuem Datensatz” laufen (oder als Schaltfläche).

     

    Eine einfache, sich automatisch aktualisierende Nummerierung aller Datensätze kann man mit einem Funktionsfeld realisieren:

    let thisNr := number(Nr);
    cnt(select Sammlung where number(Nr) <= thisNr)

    • Nils
    • vor 3 Jahren
    • Gemeldet - anzeigen

    OK, vielen Dank schon mal.

     

    Bei deinem Vorschlag für die automatische Nummerierung schaffe ich es einfach nicht, dass diese Zahl vierstellig wird. Da mit einem Funktionsfeld ja keine Datenänderung gemacht werden kann. Kann man die vierstellige Nummerierung direkt im Funktionsfeld machen oder muss man da Umwege gehen?

    • Ninox-Professional
    • planoxpro
    • vor 3 Jahren
    • Gemeldet - anzeigen

    let thisNr := number(Nr);
    format(cnt(select Sammlung where number(Nr) <= thisNr), “0000”)

    • Nils
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Sorry, das hätte mir auch selbst einfallen können. Vielen Dank.

     

    Nun habe ich das Ganze mal getestet. 5 Datensätze erstellt und dann den dritten gelöscht. 

    <ul><li>Die Ansicht aktualisiert nicht und ich habe eine Lücke</li>

    <li>Wenn ich nun einen neuen Datensatz erstelle, bekommt der Nr. 5, korrekterweise</li>

    <li>Wenn ich die Ansicht gleich nach dem löschen neu lade, stimmt auch die Ansicht und geht nur bis 4</li>

    </ul>

     

    Kann man Ninox irgendwie zum Neu laden der Ansicht bewegen, sobald ein Datensatz gelöscht wurde?

    • Ninox-Professional
    • planoxpro
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Man kann in der Tabellenansicht auf das Aktualisierungssymbol links oben klicken. Per Skript wüsste ich jetzt nicht. Eventuell mit closeRecord() bzw. openRecord(), aber das habe ich noch nicht ausprobiert. 

    • Nils
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Wenn man ein Script in “Nach Änderung folgendes Script ausführen” packen würde, wie müsste das dann aussehen um die selbe Funktion der durchlaufenden (sich sofort aktualisierenden) Nummer zu erzielen?

    • Nils
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Ich möchte jetzt wegen einer Kleinigkeit keinen neuen Thread aufmachen. Ich habe noch mal etwas überlegt und jetzt eine finale Idee wie ich diese fortlaufende Nummer brauche

     

    Im Formular gibts ein Auswahlfeld mit "Yes" und "No" das man angeben muss. Standardwert "Yes".

     

    Wenn das Feld auf "Yes" steht, soll in dem Feld für die Nummer hochgezählt werden, und wenn es auf "No" steht, soll das Feld leer bleiben. 

     

    So sollen nur Einträge eine um 1 höhere Nummer bekommen, wenn das Feld auf "Yes" steht. Wenn ich im Nachhinein einen Eintrag auf "No" stelle, sollen die Nummern nach dem Aktualisieren der Ansicht wieder nachrücken und die Lücke schließen.

     

    Ich habe jetzt 2 Stunden versucht, es mit einer if, then, else Bedingung im Funktionsfeld (wo die Nummer stehen soll) zu machen aber ich habe es nicht hinbekommen. 

     

    Kannst du mir da helfen @Copytexter?

    • Ninox-Professional
    • planoxpro
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Wenn mit mit "Auswahlfeld" eigentlich ein Ja/Nein-Feld gemeint war (unten JNFELD genannt), dann würde ich es so versuchen:

     

    if JNFELD = true then
       let thisNr := number(Nr);
       format(cnt(select TABELLE where number(Nr) <= thisNr and JNFELD = true), "0000")
    end

     

    Zur Frage davor: Das Skript funktioniert nur in einem Funktionsfeld. Für einen Trigger "Nach Änderung" müsste man anders vorgehen.

    • Nils
    • vor 3 Jahren
    • Gemeldet - anzeigen

    Oh Mann, jetzt komme ich mir ziemlich doof vor. Das sieht so einfach aus. Ich habe einfach in die falsche Richtung gedacht. Danke dir, so funktioniert es wie es soll!#

Content aside

  • vor 3 JahrenZuletzt aktiv
  • 22Antworten
  • 2025Ansichten