0

Rechnungsnummer

Hallo zusammen,

ich habe die Vorlage Rechnung installiert. Wenn ich eine neue Rechnung anlege, wird die Rechnungsnummer wie folgt generiert: 2018-001 (Jahr-Fortlaufende Nummer)

Hierzu ist folgende Formel hinterlegt:

let y := year(Datum);
let c := cnt(select Rechnung where year(Datum) = y);
Rechnungsnummer := y + "-" + format(c, "000“)


Wie bekomme ich es hin, dass das Jahr nur mit den letzten beiden Ziffern (also 18 statt 2018) und der Monat mit angehängt wird? Also dass die Rechnungsnummern im Endeffekt wie folgt geführt werden: 18-01-001, 18-01-002, 18-01-003

36 Antworten

null
    • Leonid_Semik
    • vor 6 Jahren
    • Gemeldet - anzeigen
    let y := year(Datum);
    let c := cnt(select Rechnung where year(Datum) = y);
    Rechnungsnummer := format(Datum, "YY-MM-") + format(c, "000")
    • Selcuk
    • vor 6 Jahren
    • Gemeldet - anzeigen
    Hallo Leo,

    vielen Dank für Deine Lösung. Grundsätzlich funktioniert die Lösung, an dem letzten Anführungszeichen hat sich allerdings der Fehlerteufel eingeschlichen... Schau die mal die Anführungszeichen genauer an, man sieht auch dass die unterschiedlich ausschauen..

    Gruß
    • Leonid_Semik
    • vor 6 Jahren
    • Gemeldet - anzeigen
    Das ist grundsätzlich hier im Forum so, dass die Mac Anführungszeichen anders interpretiert werden. In deinem Beitrag sind die Anführungszeichen nach dem 000 auch anders.
    • AxelE
    • vor 6 Jahren
    • Gemeldet - anzeigen
    Sorry, wenn ich wieder mal blöd frage, aber: Funktioniert die Lösung? Müsste man beim where nicht auch den Monat einbeziehen?
    • Leonid_Semik
    • vor 6 Jahren
    • Gemeldet - anzeigen
    Ich habe so verstanden, dass die Rechnungsnummernkreis sich nur nach Jahren richtet und die Monatsanzeige nur optisch da ist. Wenn man die Nummern jeden Monat neu gesetzt werden, dann wäre die Formel:
    ---
    let y := yearmonth (Datum);
    let c := cnt(select Rechnung where yearmonth(Datum) = y);
    Rechnungsnummer := format(Datum, "YY-MM-") + format(c, "000")
    ---
    • AxelE
    • vor 6 Jahren
    • Gemeldet - anzeigen
    yearmonth() hat in der deutschsprachigen Version ja standardmäßig das Format YYYY/MM. Mein Ansatz wäre deshalb dieser gewesen:

    let y := format(Datum), "YYMM");
    let c := cnt(select Rechnung where substr(Rechnungsnummer, 0, 4) = y) + 1;

    Oder denke ich da wieder falsch/zu kompliziert?

    PS: Die Bindestriche habe ich vergessen hinzuzufügen. Mit dann so:

    let y := format(Datum), "YY-MM-");
    let c := cnt(select Rechnung where substr(Rechnungsnummer, 0, 6) = y) + 1;
    • Selcuk
    • vor 6 Jahren
    • Gemeldet - anzeigen
    Tatsächlich ist es so gedacht, dass die Rechnungsnummer jeden Monat von 0 anfangen soll.

    Vielen Dank!!
    • Leonid_Semik
    • vor 6 Jahren
    • Gemeldet - anzeigen
    Wenn die Ergebnisse gleich sind, kann man natürlich verwenden.
    Es ist nur so: wenn ich die Variable als yearmonth deklariere und dann yearmonth(Datum) mit der Variable vergleiche, habe ich weniger zu schreiben und keine Gefahr, dass ich mich beim Formatieren vertippe. Die Rechnungsnummer formatiere ich später von "Datum" aus und nicht von yearmonth. Aber, wie gesagt, manche mögen Milchschokolade, manche - Bitter.
    • AxelE
    • vor 6 Jahren
    • Gemeldet - anzeigen
    Ich glaube, ich verstehe allmählich deinen Ansatz: Du ziehst für das "select" gar nicht die Rechnungsnummer im Format "YY-MM-000" heran, sondern das Datum der Anlage des Datensatzes. Oder? Okay, stimmt, das wäre natürlich noch effizienter, setzt aber wohl voraus, dass die Rechnungsnummer immer automatisch "Bei neuem Datensatz" erzeugt wird. Bei mir ist das halt nicht zwangsläufig so, deshalb hatte ich mich von vornherein auf die Rechnungs-/Belegnummer als Vergleichskriterium versteift. Wobei ich zur Ermittlung der laufenden Nummer natürlich auch das Belegdatum heranziehen könnte, denn das wird bei mir zeitgleich mit der Belegnummer generiert und ist nicht änderbar.

    Wieder was zum Nachdenken ... ;)
    • Leonid_Semik
    • vor 6 Jahren
    • Gemeldet - anzeigen
    Ja, der Trigger ist auch auf Tabellenebene bei neuem Datensatz angelegt.
    • kontakt.1
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo!

    Ich habe hierzu auch eine Frage. Bei mir (Fotografin), werden die Datensätze nach Reihenfolge der Kundenanfrage nummeriert, das Finanzamt benötigt aber eine Rechnungsnummer nach Reihenfolge der Rechnungstellung - was sich durchaus signifikant unterscheiden kann. Momentan löse ich es so, dass bei Neuanlage eines Datensatzes das folgende Skript läuft:

    Rechnungsnummer := max((select Hochzeitspaare).Rechnungsnummer) + 1

    Das hilft aber natürlich nicht für die Rechnungstellung. Wer kann helfen?

    Vielen Dank,

    Johanna

    • Leonid_Semik
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ich würde für Rechnungen eine Extra Tabelle erstellen und dort die Verknüpfung zu der Tabelle Hochzeitspaare erstellen. Dann hast du die Lückenlose Reihenfolgung der Rechnungen und kannst die Paare belibig verknüpfen.

    Leo

    • kontakt.1
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Vielen Dank! Aktuell ist es allerdings so gelöst, dass Angebot und Rechnung einfach als zwei verschiedene Drucklayouts eines einzelnen Datensatzes realisiert werden, nicht als eigene Tabelle. Die einzelnen Positionen der Rechnung sind als Verknüpfung zu einer gesonderten Produktdatenbank mit diesem Datensatz verknüpft. Hier jetzt eine neue Tabelle nur für die Rechnungsstellung zu eröffnen ist ein vermutlich unnötiger Mehraufwand - wenn denn die Rechnungsnummer stimmt. Zur Not geht natürlich auch die manuelle Rechnungsnummer, eine automatisierte Lösung wäre aber natürlich vorzuziehen :-)

    Gruß,

    Johanna

    • kontakt.1
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Habe jetzt eine Zwischenlösung gefunden in der ich alle Datensätze zähle, bei denen das Feld "Rechnung gestellt am" mit einem Datum gefüllt ist. Also so:

    cnt((select Hochzeitspaare).'Rechnung gestellt am') 

    Hat natürlich den Nachteil, dass jetzt in allen Datensätzen die gleiche Zahl steht. Kann ich das irgendwie so eingrenzen "Zähle alle Datensätze vor dem in diesem Feld genannten Datum" ? Das wäre die Lösung für mein Problem.

    Danke nochmal,

    Johanna

    • Leonid_Semik
    • vor 5 Jahren
    • Gemeldet - anzeigen

    if 'Rechnung gestellt am' then

    let my:=this;

    cnt((select Hochzeitspaare)['Rechnung gestellt am' and 'Rechnung gestellt am'<my.'Rechnung gestellt am') +1+cnt((select Hochzeitspaare)['Rechnung gestellt am' and 'Rechnung gestellt am'=my.'Rechnung gestellt am' and number(Nr)<my.number(Nr))

    end

    ---

    Ist ein bisschen kompliziert. Die zweite cnt ist dür den Fall falls du an einem Tag zwei Rechungen schreibst.

     

    Leo

    • kontakt.1
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Vielen Dank für Deine Hilfe, Leo! Leider scheint da in der Formel noch irgendwo eine ] zu fehlen und ich finde leider nicht heraus, wo...

    Johanna

    • kontakt.1
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Habe des doch noch selbst herausgefunden! Es funktioniert wunderbar! Danke für Deine Hilfe!

    Johanna

    • jam_boom
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Könnt ihr mir helfen? Ich möchte die Rechnungsnummer wie folgt generieren:

    YYYYMM000-KdNr. 

    Also JahrMonatNr.-Kundennummer.

    Hat da jemand eine Idee? 

     

    DANKE

    • Leonid_Semik
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Also wenn die Nummer so aussehen sollte: 2020090002, 2020090003.......2020110012 dann als Trigger auf Tabellenebene nach neu:

    ---

    Kundennummer := format(today(), "YYYYMM") + format(max((select DEINETABELLE).number(substr(Kundennummer, 6))) + 1, "0000")

    ---

    Leo

    • jam_boom
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Hm.... also es soll so aussehen, wenn die 0 für die Rechnungsanzahl und KR für die Kundennummer steht:

     

    YYYYMM000-KR

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

    Hallo, versuch's mal so:

    Rechnungsnummer := format(today(), "YYYYMM") + format(max((select DEINETABELLE).number(substr(Rechnungsnummer, 6))) + 1, "000") + "-" + Kundennummer

    Der letzte Teil mit der 'Kundenummer' wird als Trigger "Bei neuem Datensatz" aber nicht funktionieren, weil die Kundennummer zu dem Zeitpunkt noch gar nicht im neuen Datensatz steht. Entweder macht man das also mit einer Schaltfläche, nachdem man die Kundennummer eingegeben hat oder man holt die Kundennummer irgendwo anders her.

    • Leonid_Semik
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Da kommen mehr Rückfragen:

    1. Wie sehen die Nummerkreise für Rechnungen aus. wird die Rechnungsnummer immer fortgesetzt oder kommt am Jahresanfang(Monatsanfang) wieder die nummer 1?. Sind die Rechnungsnummer von dem Kunden abhängig (ist zwar ungewönlich aber auch möglich)? 

    Leo

    • Andreas_Schmitz
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Hallo, ich beschäftige mich schon sehr lange mit dem Problem der Rech.-Nummer bei Ninox. Auf der einen Seite soll man nicht die interne Datensatz-Nummer verwenden, weil der Index sich ändern kann, auf der anderen Seite besteht das Problem, dass beim Kopieren eines Datensatzes auch die Rech.-Nr. kopiert wird und damit die Eindeutigkeit verloren geht. Man benötigt also auf der einen Seite Metadaten, die sich in einem Funktionsfeld ständig ändern, auf der anderen Seite bedeutet eine Rech.-Nr. in einem Textfeld, dass die Eindeutigkeit nicht garantiert werden kann! Die Lösung, die ich gefunden habe, ist folgende:

    let a := “Erstellt am”;
    let b := format(a, “YYMM-DDHH-mmss”);
    let c := substring(lpad(format(a, “x”), 16, “0”), 12, 16);
    “R-” + b + “-” + c

    Gibt man diesen Code in ein Funktionsfeld ein, dann nutzt man die Metadaten des Erstellungsdatum des Datensatzes, das im Gegensatz zur laufenden Index-Nummer für den jeweiligen Datensatz immer gleich bleibt, auf der anderen Seite beim Kopieren sich immer ändert! Es ist es zwar theoretisch möglich, einen Datensatz innerhalb einer Millisekunde zweimal zu kopieren, praktisch aber nicht. Das schöne an der Darstellung ist, dass man sehr schnell ablesen kann aus welchem JahrMonat die Rechnung stammt und an welchem TagStunde die Rechnung erstellt wurde. Die letzten 8 Ziffern sind dann ein Zähler für die Rech.-Nr. und zur besseren Lesbarkeit in MinuteSekunde - Millisekunden getrennt worden. Auf die Millisekunden darf nicht verzichtet werden, da es praktisch möglich ist, die Kopierfunktion innerhalb einer Sekunde zweimal zu drücken. Einfacher wäre es natürlich, wenn bei Ninox endlich die Funktionen Neu erstellen und Kopieren getrennt angesteuert werden könnten. Bis dahin ist dies die einzige Lösung, die alle Härtetest überstanden hat. Der Vorteil das Rech.-Datum mit in die Rech.-Nr. einzubauen liegt auch in den Buchungen, da viele Kunden vergessen, dass Rech.-Datum separat anzugeben, was aber beim Buchen dringend benötigt wird. Lg Andreas

    • Andreas_Schmitz
    • vor 4 Jahren
    • Gemeldet - anzeigen

    PS: Ninox wäre nicht Ninox, wenn es nicht noch ein kleines Problem gäbe. Wenn man nach einem Funktionsfeld suchen möchte, geht das nur in der primären Tabellenansicht, aber nicht, wenn die Tabelle über eine Verknüpfung als Nachschlagetabelle fungiert. Bereits bei der Eingabe von R verschwinden dann alle Datensätze. Um dies zu umgehen, muss man ein Textfeld Rechnungsnummer anlegen! Bei jeder Ändeurng des Datensatzes muss man dann eingeben: if Rechnungsnummer != Funktionsfeld then Rechnungsnummer := Funktionsfeld end. Beim Kopieren existieren dann zwar zwei verschiedene Wert, bei der nächsten Änderung des Datensatzes werden die Werte aber wieder angeglichen! Über das Feld Rech.-NR. kann man aber nach der Rech.-Nr. suchen, was in Datenbänken ja nicht gerade unüblich ist. Ich habe noch eine visuelle Warnung eingebaut: if Rechnungsnummer != Funktionsfeld then icon(“stop”) else icon(“check”) end. Lg Andreas

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

    Hallo Andreas, wieso kann “die Eindeutigkeit nicht garantiert werden”, wenn man die Rechnungsnummer in einem Textfeld speichert? Die meisten Nutzer, die mit Ninox fortlaufende Rechnungs- und ähnliche Identifikationsnummern erzeugen, gehen so vor, dass sie die bisher höchste Nummer ermitteln und den Wert um 1 erhöhen. Das geht selbstverständlich auch mit Textfeldern und variablen Bestandteilen wie Jahr und/oder Monat.

    Ich finde es eher ungewöhnlich, die Rechnungsnummer mit einem Funktionsfeld abzubilden, wo sie immer wieder neu berechnet werden muss (auch, wenn das Ergebnis in diesem Fall immer dasselbe ist). Unabhängig vom Verfahren zum Generieren der Nummer würde ich sie deshalb immer dauerhaft in einem Textfeld speichern.