0

Verschiedene Nummerierungen erzeugen und kombinieren

Hallo!

Vielleicht kann mir jemand auf die Sprünge helfen.

A.) Ich benötige eine ganz normale Zählung von Datensätzen, die 2-stellig (also 00, 01, 02 ... 99) Zahlen erzeugt, die einmalig für einen Datensatz vergeben werden und nicht mehr änderbar sind. Die Datensätze werden auch nie wieder gelöscht, also ist der letzte auch der mit der höchsten Nummer - immer.

B1.) Ich benötige eine Zählung von Datensätzen auf ein Jahr bezogen (aus einem Datumsfeld heraus), beginnend bei 01 für das Jahr bis 99 für dieses vorgegebene Jahr. Auch das soll einmal festgelegt werden und darf nicht mehr änderbar sein. Ein anderes Jahr fängt dann auch wieder bei 01 an.

B2.) Wie bekomme ich aus dem vorgegebenen Jahr die beiden letzten Stellen (also für 2022 nur die 22) herausgezogen? Ich vermisse (oder habe es noch nicht gefunden) die Möglichkeit, eine Zahl in Text umzuwandeln, um dann die beiden letzten Stellen zu extrahieren.

Punkte B: Am besten wäre es, glaube ich, wenn diese Zahlenwerte mit einem Klick auf einen Button (z.B. "Jetzt Wert berechnen" oder so) erzeugt werden. Und dann nicht mehr geändert werden können. Es wird nur das Datum eingetragen, der Rest muss dann aus diesem Datum erzeugt werden.

Je nach Aufwand für diese Hilfe bin ich bei einer praktikablen Lösung gerne bereit eine angemessene Zahlung (vorher vereinbart) gegen Rechnung zu leisten. Könnte ja vielleicht doch bisschen Zeit in Anspruch nehmen ;-)

Gerne mit persönlicher Kontaktaufnahme.

37 Antworten

null
    • Ninox-Professional
    • planoxpro
    • vor 1 Jahr
    • Gemeldet - anzeigen

    Hallo Bernhard, das sollte hier im Rahmen des Forums zu lösen sein.

     

    1A: Das entspeicht nach meinem Verständnis im Grunde der internen Record-Nr., die automatisch für jeden neuen Datensatz vergeben wird und nicht manipulierbar ist. Abrufen kann man sie mit

    number(Nr)
    

    Oder, wenn man sie zweistellig mit führender Null angezeigt bekommen möchte (Anzahl der Nullen entspricht den Stellen) :

    format(number(Nr), "00")
    

     

    B2: Zu Umwandlung von Zahlen in Text gibt es die Funktion text(ZAHL), umgekehrt geht es mit number(ZIFFERNFOLGE). Zum Extrahieren eines Teilbereichs gibt es substr(). Beispiel:

    let myYear_num := 2022;
    let myYear_str := substr(text(myJahr_num), 2, 2);
    

    Wert der Variable 'myYear_str' wäre der String "22".

     

    B1: Auch die Funktionen format() und styled() wandeln Werte in Texte um. Wenn es um fortlaufende Nummerierung innerhalb einer zweistelligen Jahreszahl geht, könnte man folgendes Script in den Tabellenoptionen als "Trigger bei neuem Datensatz" eintragen (am Beispiel des aktuellen Tagesdatums):

    let myYear := format(today(), "YY");
    let myMaxNr := max((select TABELLE where substr(XYNUMMER, 0, 2) = myYear).substr(XYNUMMER, 2, 2));
    let myNewNr := number(myMaxNr) + 1;
    XYNUMMER := myYear + format(myNewNr, "00")
    

    Wobei XYNUMMER für den Namen des Textfeldes steht, in dem die fortlaufende Nummer gespeichert wird. Die Zählung würde im nächsten Jahr automatisch wieder bei 0 beginnen ("2401", "2402" usw). Will man dieses Feld für manuelle Änderungen sperren, kann man in den Feldoptionen unter "Schreibbar wenn" einfach das Schlüsselwort "false" eingeben (ohne Anführungszeichen).

     

    Eine Übersicht der Ninox-Funktionen mit kurzen Beschreibungen findet sich hier:

    https://docs.ninox.com/de/skripten/funktionen-ueberblick/funktionen-nach-kategorien

    • Bernhard_Schulze
    • vor 1 Jahr
    • Gemeldet - anzeigen

    Hallo!

    planox. pro said:
    1A: Das entspeicht nach meinem Verständnis im Grunde der internen Record-Nr., die automatisch für jeden neuen Datensatz vergeben wird und nicht manipulierbar ist. Abrufen kann man sie mit
    number(Nr)

    Danke für die schnelle Antwort. An diesem Punkt habe ich das Problem, dass bereits Datensätze existieren, die aber nicht in der natürlichen (also angelegten) Reihenfolge nummeriert sind, sondern ich habe bereits manuell nummeriert und das stimmt nicht mit den Record-Nummern überein. Schade. Da werde ich wohl über eine maxNr.-Formel anders vorgehen müssen. Habe ich noch nicht herausgefunden. Hoffe, das ist nicht zu kompliziert ;-)

      • Ninox-Professional
      • planoxpro
      • vor 1 Jahr
      • Gemeldet - anzeigen

      Bernhard Schulze Wenn du etwas konkreter beschreibst, was genau du eigentlich erreichen willst, kann dir sicher auch gezielt geholfen werden.

      • Bernhard_Schulze
      • vor 1 Jahr
      • Gemeldet - anzeigen

      planox. pro Hi! Ja nun, ich habe schon einen Schwung Datensätze, bei denen ich manuell eine Zahl reingeschrieben habe, bis mir aufgefallen ist, dass ich noch ein Record mit 00 benötige. Dieser hat nun allerdings intern nicht die Nummer 00 sondern 14 und der Datensatz, der intern die 15 hat, hat nun manuell bereits 16 und so weiter.

      Nun sollen die Nummern neu generiert werden, wobei die bestehenden erhalten bleiben müssen und neue Nummern dann automatisch weiter hochgezählt werden. Ich denke also, mit einer +1 auf die maximale Nummer dann.

      Schwer zu erklären, da ich als Ninox Starter die Scriptsprache noch so gut wie überhaupt nicht durchblickt habe. Verschiedene Sachen habe ich daher erst mal manuell gemacht, bis ich gesehen habe, wie und wo ich gewisse Automatismen benötigen könnte.

    • Bernhard_Schulze
    • vor 1 Jahr
    • Gemeldet - anzeigen

    Sodala!

    planox. pro said:
    B2: Zu Umwandlung von Zahlen in Text gibt es die Funktion text(ZAHL), umgekehrt geht es mit number(ZIFFERNFOLGE). Zum Extrahieren eines Teilbereichs gibt es substr(). Beispiel:
    let myYear_num := 2022;
    let myYear_str := substr(text(myJahr_num), 2, 2);
    Copy
    Wert der Variable 'myYear_str' wäre der String "22".

     Ich denke mal, dass myJahr eigentlich myYear sein sollte?

    Habe nun diese Formal versucht:

    let myYear_num := year(Auftragsdatum);
    let myYear_str := substr(text(myYear_num), 2, 2);

    Wobei Ninox von selbst "void" hinten dran gehängt hat und das Ergebnis leer ist.

    Der Auszug des Jahres sollte aus dem Feld "Auftragsdatum" genommen werden, aber das scheint so wohl nicht zu klappen. Bestimmt irgend eine Klammer zu viel oder zu wenig, wobei mir kein Fehler angezeigt wird, bis eben auf das "void" am Ende.

    • Bernhard_Schulze
    • vor 1 Jahr
    • Gemeldet - anzeigen

    Hallo!

    planox. pro said:
    als "Trigger bei neuem Datensatz" eintragen (am Beispiel des aktuellen Tagesdatums):

    Ok, klingt gut, aber da fehlt wohl auch eine genauere Info von mir. 

    Also, das Datum wird eingetragen und ist nicht gezwungenermaßen das Erstellungsdatum des Datensatzes. Das kann mit Versatz passieren, also ich trage heute das Datum von z.B. vorgestern ein - gilt übrigens für verschiedene Vorgänge in der Datenbank, das ist exemplarisch. Manche Vorgänge bedürfen eventuell erst einer Rücksprache oder Bestätigung, das kann halt leider mit Verzögerungen erfolgen. Ausschlag gebend ist das Datum, das ich eintrage.

    • ZitronenKiller
    • vor 1 Jahr
    • Gemeldet - anzeigen

    die format Funktion kann da vielleicht helfen:

    format(today(),"YY")

    gibt bspw. das aktuelle Jahr zweistellig aus. 

    Schau mal unter dem Begriff in die Doku, die Format Funktion ist sehr mächtig. Das Ergebnis lässt sich dann in ein Datenfeld eintragen, z.B.:

    Textfeld:=text(format(today(),"YY") ) 

    und somit wieder im Datensatz festschreiben.

    • Ninox-Professional
    • planoxpro
    • vor 1 Jahr
    • Gemeldet - anzeigen

    Okay, ich versuche mal, die verschiedenen Fragen und Postings zusammenzufassen und gehe von folgenden Voraussetzungen aus:

    • Es gibt eine laufende, zweistellige Nummer, die in einem Textfeld gespeichert wird (XYNUMMER).
    • Es wurden manuell bereits Nummern eingetragen ("01", "02" ... "16" usw.).
    • Die vorhandenen Nummern sollen einmalig geändert werden auf "2201", "2202" ... "2216" usw., wobei die zweistellige laufende Nummer am Ende erhalten bleiben soll.

    Dafür könnte man einen Button erstellen (zu finden in der Werkzeugleiste unter "Layout-Felder"). Der Code hängt davon ab, ob die vorhandenen Nummern alle in einem Jahr liegen (am Beispiel 2022) ...

    for i in TABELLE do
       i.XYNUMMER := "22" + i.XYNUMMER
    end
    

    ... Oder ob es verschiedene Jahre sind und die zweistellige Jahreszahl jeweis aus dem Auftragsdatum gezogen werden soll. Dann würde ich es so versuchen:

    for i in TABELLE do
       if i.Auftragsdatum then
          let myJJ := format(Auftragsdatum, "YY");
          i.XYNUMMER := myJJ + i.XYNUMMER
       end
    end
    

    So oder so: Damit wären alle vorhandenen Nummern der Tabelle ins neue, vierstellige Format gebracht. Der Button würde nicht mehr gebraucht und könnte wieder gelöscht werden.

    Hinweis: Ich würde zur Sicherheit ein neues Textfeld namens NEUNUMMER o. ä. erstellen und die mit dem Button generierte Nummer darin speichern. Also im Script "i.NEUNUMMER := ..." statt "i.XYNUMMER := ...". Dann das Ergebnis der Aktion überprüfen und, wenn es korrekt ist, das alte Feld XYNUMMER löschen und NEUNUMMER umbenennen. Auf diese Weise kann man sich nicht versehentlich durch einen Fehler im Script seine ganzen vorhandenen Nummern verlieren.

    Nun sollten, wenn ich es richtig verstanden habe, alle neuen Datensätze automatisch in dem neuen vierstelligen Format mit vorangestellter Jahreszahl nummeriert werden (anhand des Auftragsdatums). Da das mit dem "Trigger bei neuem Datensatz" in diesem Fall ja nicht passt, könnte man sich einen kleinen Button erstellen und an geeigneter Stelle im Formular platzieren:

    if Auftragsdatum then
       let myJJ := format(Auftragsdatum, "YY");
       let myLast := max((select TABELLE where substr(XYNUMMER, 0, 2) = myJJ).substr(XYNUMMER, 2, 2));
       XYNUMMER := myJJ + format(number(myLast) + 1, "00")
    end
    

    Mit dem "if Auftragsdatum" fragt man ab, ob schon ein Auftragsdatum eingegeben wurde. Ansonsten kann ja keine Nummer generiert werden.

    So, ich hoffe, die Aufgabenstellung richtig interpretiert und mit meinen Vorschlägen weitergeholfen zu haben.

      • Bernhard_Schulze
      • vor 1 Jahr
      • Gemeldet - anzeigen

      planox. pro Hallo! Vielen Dank für die Mühe. Leider haben Sie nun dabei die Anforderung aus  A und B miteinander verwurstelt. Ich werde mir jedoch die Formeln genauer ansehen, und versuchen, das daraus zu extrahieren, das für den jeweiligen Bereich zutreffend ist.

      Die Formeln für die Jahres- und Monatszahlen habe ich schon erfolgreich umsetzen können. Danke an dieser Stelle auch an ZitronenKiller  - mir fehlt nur noch der Teil mit der automatischen Nummerierung im Bereich A bzw. B. Aber mit den Hinweisen von Ihnen beiden sollte ich das nun schon umsetzen können.

      Wenn nicht, melde ich mich auf jeden Fall nochmal ;-)

      Um ein Überschreiben bzw. Ändern von Inhalten zu verhindern, sollte das auch mit einer Auswahl "ja/nein" klappen, oder? Wenn ein Vorgang z.B. abgeschlossen oder abgesegnet ist.

      PS: Ich nehme an, dass ich TABELLE durch die aktuelle Tabelle ersetzen muss. Wenn der Name Leerräume hat, muss ich wohl "" darum setzen.

    • Ninox-Professional
    • planoxpro
    • vor 1 Jahr
    • Gemeldet - anzeigen
    Bernhard Schulze said:
    let myYear_num := year(Auftragsdatum); let myYear_str := substr(text(myYear_num), 2, 2);
    Wobei Ninox von selbst "void" hinten dran gehängt hat und das Ergebnis leer ist.

    Die Formel ist unvollständig. Mit den beiden "let"-Zeilen werden lediglich zwei Variablen definiert, aber nicht weiter verarbeitet. Das Script halt also de facto keine Wirkung, da die Variablen nur temporär innerhalb des Scriptes existieren. Es wird zwar irgendwas berechnet, aber nichts mit dem Ergebnis gemacht. Deshalb das "void" als Hinweis.

    In einem Formelfeld müsste man das Ergebnis auch noch anzeigen lassen, in dem man den Namen der Variable "myYear_str" noch mal in die letzte Zeile schreibt. Oder in einem Button/Trigger den Wert der Variable einem Datenfeld zuweisen. So, wie oben in den Scripten ("YXNUMMER := ..."). 

    • Ninox-Professional
    • planoxpro
    • vor 1 Jahr
    • Gemeldet - anzeigen
    Bernhard Schulze said:
    Leider haben Sie nun dabei die Anforderung aus  A und B miteinander verwurstelt.

     Ja, das hatte ich befürchtet. Es ist halt manchmal sehr mühselig, aus den Fragmenten eine konkrete Aufgabenstellung herauszulesen. Entweder versucht man dann, zu interpretieren, oder man lässt gleich die Finger davon. Ich lasse mich leider manchmal zum Interpretieren verleiten ... ;)

      • Bernhard_Schulze
      • vor 1 Jahr
      • Gemeldet - anzeigen

      planox. pro Kein Problem. Somit lerne ich auch, wie ich Anforderungen für Ninox besser formulieren muss. Auch geben mir solche Interpretationen eventuell auch den einen oder anderen Denkanstoss für bessere Lösungen. Oder für eine andere Vorgehensweise.

    • Ninox-Professional
    • planoxpro
    • vor 1 Jahr
    • Gemeldet - anzeigen
    Bernhard Schulze said:
    PS: Ich nehme an, dass ich TABELLE durch die aktuelle Tabelle ersetzen muss.

     So ist es. Wenn der Fragesteller keine reale Tabellenbezeichnung nennt, nimmt man halt einen Platzhalter.

    • Ninox-Professional
    • planoxpro
    • vor 1 Jahr
    • Gemeldet - anzeigen
    Bernhard Schulze said:
    Um ein Überschreiben bzw. Ändern von Inhalten zu verhindern, sollte das auch mit einer Auswahl "ja/nein" klappen, oder? Wenn ein Vorgang z.B. abgeschlossen oder abgesegnet ist.

    Ich habe so spontan keine Idee, wie das mit einem Ja/Nein-Feld funktionieren soll. Aber es führen ja viele Wege nach Rom ...

      • Bernhard_Schulze
      • vor 1 Jahr
      • Gemeldet - anzeigen

      planox. pro Ich kann doch als Formel bei Feldern angeben "Schreibbar wenn". Dann gebe ich ein "Auswahl = nein" und das sollte doch gehen, bilde ich mir mal so ein ;-)

    • Bernhard_Schulze
    • vor 1 Jahr
    • Gemeldet - anzeigen

    Hi, ich nochmal!

    planox. pro said:
    Da das mit dem "Trigger bei neuem Datensatz" in diesem Fall ja nicht passt, könnte man sich einen kleinen Button erstellen und an geeigneter Stelle im Formular platzieren:

    Vom Verständnis her kann ich nachvollziehen, was das Script tun soll. Habe den Button nun mit meinen Feldnamen umgesetzt und bis auf eine Fehlermeldung scheint es ja zu passen:

    "JahrYY" wird testweise bereits generiert und gibt einen korrekten Wert heraus.

    Fehlermeldung:

    Wenn der Fehler eliminiert ist, denke ich, dass der ganze Vorgang nun so funktioniert wie vorgesehen. Für die bereits existierenden Datensätze muss ich wohl noch eine jeweilige Startzahl manuell vorgeben.

    • ZitronenKiller
    • vor 1 Jahr
    • Gemeldet - anzeigen

    Ein J/N Feld

    z.B. wie "Bearbeitung sperren"

    Beim Schliessen des Datensatzes (oder Button etc) "Bearbeitung sperren":=1

    Im Datensatz oder pro Feld einzeln unter "Schreibbar wenn" muss dann stehen "Bearbeitung sperren"!=1

    Bei der Neuanlage eines Datensatzes hat ein J/N Feld keinen Wert. Daher prüfe ich hier, ob der Wert auf Sperren (=1) gesetzt ist oder eben nicht (!=1 also ungleich 1)

      • Bernhard_Schulze
      • vor 1 Jahr
      • Gemeldet - anzeigen

      ZitronenKiller Genau so dachte ich mir das. Das mit der anfänglichen Prüfung müsste ich doch auch mit einem Standardwert umgehen können, oder nicht? Würde ich so machen in meinem jugendlichen Leichtsinn :-)

      • Ninox-Professional
      • planoxpro
      • vor 1 Jahr
      • Gemeldet - anzeigen

      ZitronenKiller Da haben wir wohl aneinander vorbei geredet, ;)

      Mir ging es um die einmalige Änderung vorhandener Daten per Script. Dazu nutze ich immer erst mal ein neues Feld, um die vorhandenen Daten nicht versehentlich mit falschen Werten zu überschreiben. Das ist deutlich bequemer und schneller, als ein aktuelles Backup zu erstellen (und ggf. wiederherzustellen), gibt aber zusätzliche Sicherheit für den Fall, dass mal was schief geht.

    • ZitronenKiller
    • vor 1 Jahr
    • Gemeldet - anzeigen

    natürlich.. ich bin da gelegentlich "schreibfaul".. 😉

    • ZitronenKiller
    • vor 1 Jahr
    • Gemeldet - anzeigen

    Die Tabelle muss mit einfachen Anführungszeichen versehen werden, wenn sie Leerzeichen oder Umlaute enthält 'TABELLE mit Ö'

    • ZitronenKiller
    • vor 1 Jahr
    • Gemeldet - anzeigen

    Bez. des "Select" Kommandos weiter oben:

    max gibt den höchsten Wert (nicht den Datensatz mit dem höchsten Wert) zurück, der durch das select Kommando erreicht wird. Dabei muss es sich um eine Zahl oder Zeit handeln, Text geht nicht. Du musst also ggf. Text in Zahl umwandeln bzw umgekehrt. 

    siehe Doku Funktionen text() und number()

      • Bernhard_Schulze
      • vor 1 Jahr
      • Gemeldet - anzeigen

      ZitronenKiller Genau damit kämpfe ich grad. Der fängt immer wieder bei 01 an. Also erst den Feldinhalt in Zahl umwandeln, dann neuen Wert berechnen und als Text eintragen. Richtig?

      Sieht aktuell so aus:

      if Auftragsdatum then
         let myJJ := JahrYY;
         let myLast := max((select '01.1 Aufträge' where substr(LfdNrYY, 0, 2) = myJJ).substr(LfdNrYY, 2, 2));
         LfdNrYY := format(number(myLast) + 1, "00")
      end
      

      "LfdNrYY" ist Text. Also erst mal "number(LfdNrYY)" mit

      let LfdNrYYn := number(LfdNrYY)

      Und dann diese Variable dort einsetzen wo gerechnet wird und dann ganz am Ende in Text zurück verwandeln. Richtig?

      • Ninox-Professional
      • planoxpro
      • vor 1 Jahr
      • Gemeldet - anzeigen

      ZitronenKiller max() funktioniert selbstverständlich auch mit Text! Es wird eben nur alphanumerisch sortiert, was aber bei Ziffernfolgen mit führenden Nullen kein Problem ist.

      • Bernhard_Schulze
      • vor 1 Jahr
      • Gemeldet - anzeigen

      planox. pro Ach, ok. Aber ich fange jetzt nix Neues an und versuche die Formel so zu lösen, wie vorgeschlagen.

      Habe nun die Formel gändert:

      Sind aber doch nun Fehler drin, die ich nicht nachvollziehen kann:

      Wo mag der Wurm nun versteckt sein? Das hat wohl was mit den kleinen Unterstrichen bei den =-Zeichen und der Klammer zu tun. Muss das evtl := sein? Klammeranzahl 4 auf 4 zu stimmt ja wohl?

      Oder geht das mit dem "substr" in Verbindung mit einer Zahl nicht?

Content aside

  • vor 1 JahrZuletzt aktiv
  • 37Antworten
  • 250Ansichten
  • 3 Folge bereits