Zähler

  • Hallo Notes-Gemeinde,


    hat jemand von Euch eine gute Lösung für einen Zähler in Notes. Ich möchte eindeutige Nummern für bestimmte Vorgänge vergeben. Dabei dispatcht ein Agent teilweise bis zu 10 Vorgänge in einem Durchgang, d.h., daß die fortlaufende Nummer dann auch um bis zu 10 erhöht werden kann. Und dies kann sich zu Spitzenzeiten mit anderen Abfragen überschneiden.


    Nun, denke ich, ist es ja eine gangbare Lösung, dafür ein separates Profildokument bereit zu stellen, in dem ich immer ein Feld durch den Agenten pflege. Ich glaube aber, daß das ständige speichern ziemlich viel Zeit und ressourcen kostet. Gibt es noch eine andere Lösung?


    Danke,


    Bernd.

  • Müssen die Nummern fortlaufend sein? Ansonsten nimm @Unique

    Life is not a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside, thoroughly used up, totally worn out, and loudly proclaiming "Wow, what a ride!!! :evil:
    Beschleunigung ist, wenn die Tränen der Ergriffenheit waagrecht zum Ohr hin abfliessen - Walter Röhrl

  • Ich hab vor vielen Jahren mal was gebaut.
    Funktioniert natürlich nur auf einem Server und unter der Massgabe, daß es auch mal ein bisserl dauern kann.


    Die Lösung sah ungefähr so aus:
    1. Bau eine Ansicht mit den Auftragsnummern in der ersten Spalte und sortiere diese Absteigend.
    2. Lasse einen Agenten auf neue und geänderte Dokumente rennen.
    3. Prüfe ob das Dokument neu ist und addiere zur Nummer des ersten Dokumentes der Ansicht eine 1 und schreibs in das neue Dokument.


    Natürlich muss noch ein wenig geprüft werden, ob z.B. das neue Dokument schon eine Nummer hat (Kopie via Zwischenablage) usw.


    Aber das kriegst du dann sicher schon hin.

    Bye
    Torsten


    IBM Advanced Certified System Administrator - Lotus Notes and Domino 8.5

  • Hallo,


    Zähler geht auch einfach:


    Zuersteine Maske erstellen:


    (System Zähler) alias System_Versuchsnummer


    mit folgenden Feldern:
    System_Versuchsnummer -- hier gehört auch der Startwert rein zB 1 oder 00001 etc (Textfeld bearbeitbar)


    Document_ID (Text berechnet beim anlegen) Wert = @Text(@DocumentUniqueID)
    System (Text berechnet) Wert = System_Versuchsnummer


    hiddenfield : $PublicAcess (Text berechnet beim anlegen)das brauchst Du damit immer eine Nr erzeugt wird (Autor)und nicht nur bei Editorrechten.


    +++++++++++++++++++++++++++++++++++++++
    so jetzt eine Ansicht erstellen:
    name:
    (system_Zähler) alias System_Versuchsnummer


    1. Spalte enthält das Feld : System
    2. Spalte enthält das Feld : System_Versuchsnummer
    3. Spalte enthält das Feld : Dokument_ID



    Unter Ansicht - Eigenschaften der Reiter mit dem Schlüssel mußt Du noch einen Haken Unter "Verfügbar für Benutzer mit öffentlichem Zugriff " machen.


    +++++++++++++++++++++++++++++++++++
    jetzt bist Du bald fertig :-D



    Jetzt legst Du in der Maske in der der Zähler sein soll ein Feld an, Name egal Wert =
    REM "aktuellen Zähler auslesen und inkrementieren";
    Counter := @DbLookup( "" : "NoCache" ; "" : "" ; "System_Versuchsnummer" ; "System_Versuchsnummer" ; 2);
    CounterPlus1 := @Right("000" + @Text( @TextToNumber(Counter) + 1); 4);


    REM "Inkrementierten Zähler zurückschreiben";
    DocID := @DbLookup( "" : "NoCache" ; "" : "" ; "System_Versuchsnummer" ; "System_Versuchsnummer" ; 3);
    @SetDocField(DocID ; "System_Versuchsnummer" ; CounterPlus1);


    REM "Feld Nummer zusammensetzen aus MoC + Zähler und ins Dokument schreiben";
    Nummer_Temp := Counter;
    @Return(Nummer_Temp)


    Unter Maske - Eigenschaften der Reiter mit dem Schlüssel mußt Du noch einen Haken Unter "Verfügbar für Benutzer mit öffentlichem Zugriff " machen.


    und schon bist Du fertig und hast einen Schönen Zähler.


    Ich willauch den Nachteil nicht verheimlichen. Jedesmal wenn Du ein neues Dok erzeugtst wird eine Nr vergeben auch wenn das Dok nicht gespeichert wird. :-)


    Ich hoffe das hat Dir geholfen.


    Gruss
    Bernd99

  • Bernd99


    Und noch ein zwei weitere Probleme:
    Wird bevor das angelegte Dokument gespeichert wurde ein neues erzeugt, dann ist die Nummer doppelt vergeben.


    Arbeitest du mit verschiedenen Repliken dann werden da ebenfalls Nummern doppelt vergeben, da die Dokumente ja nicht zeitgleich auf allen vorhanden sind.



    Die sinnvollste Variante eine laufende Nummer zu vergeben ist das ganze im Hintergrund mit einem Agenten auf einem Server zu machen.
    Der Agent bekommt wenn Leserfelder vorhanden sind mit einer Rolle Zugriff auf alle Dokumente.


    Das ist meines Wissens nach die einzige Möglichkeit fortlaufende Nummern sicher zu vergeben

  • taurec


    Hallo Taurec,


    ich muß da leider wiedersprechen, es werden keine Nummern doppelt vergeben auch wenn das neue Dok noch nicht gespeichert ist.


    REM "Inkrementierten Zähler zurückschreiben";
    DocID := @DbLookup( "" : "NoCache" ; "" : "" ; "System_Versuchsnummer" ; "System_Versuchsnummer" ; 3);
    @SetDocField(DocID ; "System_Versuchsnummer" ; CounterPlus1);


    beim öffnen eines weitern Doks ist die erste Nummer schon zurückgeschrieben.


    Das einzige Problem ist halt das die Nummern von nicht gespeicherten Doks " verlorengehen.


    PS : Ich habe das so bei einigen DB's schon lange so in Benutzung.


    Gruss


    Bernd :-)

  • OK, die Zeile hatte ich übersehen,
    Gefährlich ist daran dann nur wenn viele Leute neue Dokumente anlegen, dann wird es nicht ausbleiben dass das ab und zu mehrere gleichzeitig machen. Das ergibt dann nen Speicherkonflikt und dann hast du auch wieder doppelte Zähler.


    Wie gesagt verwende ich da immer nen Background Agenten der nur an genau einer Stelle ausgeführt wird. Damit umgehe ich nahezu alle Probleme

  • Hallo Zusammen,


    mir ist gerade noch eine Lösung eingefallen.


    Erst beim speichern eine neue Nummer erzeugen. Das sollte doch sicher sein. Ich hoffe dann halt, das nicht gerade zwei User in der gleichen Millisekunde speichern.


    Gruss


    Bernd 99 :-D

  • mehrere Server, die nur alle X Stunden replizieren und schon ist das Problem wieder da. Die einzigste Lösung, die keine Probleme macht, ist die von taurec.


    Gruß
    Dirk

    Rein logisches Denken verschafft uns keine Erkenntnis über die wirkliche Welt.
    Alle Erkenntnis der Wirklichkeit beginnt mit der Erfahrung und endet mit ihr.
    Alle Aussagen, zu denen man auf rein logischen Wegen kommt, sind, was die Realität angeht, vollkommen leer.
    Albert Einstein

  • Es gibt schon eine Möglichkeit, sicher eindeutige Nummern zu vergeben, und zwar über das Setzen von UNIDs von neuen Dokumenten. Wenn man auf mehreren Servern arbeitet, braucht man ein Profildokument, das für die erlaubten Server die Nummernkreise festlegt.


    Das Ganze funktioniert dann so, daß man von den 32 Stellen der UNID 20 Nullen, 4 serverspzifische Zeichen (0000 bis FFFF) und anschließend 8 fortlaufende "Zahlen" einführt.


    Wenn man eine Nummer benötigt, legt man ein "Zaehler"-Dokument an, sucht sich aus dem Konfigurationsdokument die entsprechenden Daten heraus und geht auf die absteigend nach UNID sortierte Ansicht der Zaehlerdokumente mit GetDocumentByKey(xxx,False). Bekommt man keinen Wert zurück, nimmt man die erste Nummer des Nummernkreises und baut die UNID zusammen und vergibt sie dem neuen ZAEHLERDOKUMENT und speichert dieses ab (ganz wichtig!) - bei ERROR4000 probiert man die nächste Nummer. Wenn man ohne Error4000 aus der Prozedur eine Nummer hat (und diese Nummer nicht größer als die maximale Nummer des Nummernkreises ist), gibt man diese seinem Dokument und speichert auch das Dokument ab.


    Der Trick besteht darin, daß man mit der UNID zum Einen sehr schnell ist und vor allem auf einem "inneren Notes-DB-Feature" aufsetzt - sprich: defekte Ansicht-Indizes o.ä. können einem keinen Streich spielen. Und man vergibt die Nummer erst und nur dann, wenn man das ZAEHLERDokument mit dieser Nummer auch erfolgreich abspeichern konnte. Das sorgt für die Sicherheit, daß nicht die berühmte "Millisekunde" zwischen Auswahl und Abspeichern eine Rolle spielt. Das Modell ist insofern also "transaktionsorientiert".


    Am besten läßt man dann nachts einen Agenten laufen, der die überflüssigen ZAEHLER-Dokumente (für jeden Server alle unterhalb der höchsten bisher vergebenen Nummer) wieder löscht.

  • LN4ever ,


    hört sich ja gut an bin aber leider noch nicht soweit fortgeschritten das ich mir das alles selber erarbeiten könnte.


    Zeig uns doch mal den Quelltext vielleicht auch mit einer kleinen Anleitung.
    Ich würde Deine Programmierung gerne mal ausprobieren.


    Gruss


    Bernd99

  • HAllo kurze korrektur für alle die ausprobieren möchten:


    Hallo,


    Zähler geht auch einfach:


    Zuersteine Maske erstellen:


    (System Zähler) alias System_Versuchsnummer


    mit folgenden Feldern:
    System_Versuchsnummer -- hier gehört auch der Startwert rein zB 1 oder 00001 etc (Textfeld bearbeitbar)


    Document_ID (Text berechnet beim anlegen) Wert = @Text(@DocumentUniqueID)
    System (Text berechnet) Wert = System_Versuchsnummer


    hiddenfield : $PublicAccess (Text berechnet beim anlegen)das brauchst Du damit immer eine Nr erzeugt wird (Autor)und nicht nur bei Editorrechten.


    +++++++++++++++++++++++++++++++++++++++
    so jetzt eine Ansicht erstellen:
    name:
    (system_Zähler) alias System_Versuchsnummer


    1. Spalte enthält das Feld : System
    1. muß sortiert sein damit dblookup funktioniert
    2. Spalte enthält das Feld : System_Versuchsnummer
    3. Spalte enthält das Feld : Dokument_ID


    Ansichtenauswahl lautet: SELECT(System = "System_Versuchsnummer" )


    Unter Ansicht - Eigenschaften der Reiter mit dem Schlüssel mußt Du noch einen Haken Unter "Verfügbar für Benutzer mit öffentlichem Zugriff " machen.


    +++++++++++++++++++++++++++++++++++
    jetzt bist Du bald fertig



    Jetzt legst Du in der Maske in der der Zähler sein soll ein Feld an, Name egal Wert =
    REM "aktuellen Zähler auslesen und inkrementieren";
    Counter := @DbLookup( "" : "NoCache" ; "" : "" ; "System_Versuchsnummer" ; "System_Versuchsnummer" ; 2);
    CounterPlus1 := @Right("000" + @Text( @TextToNumber(Counter) + 1); 4);


    REM "Inkrementierten Zähler zurückschreiben";
    DocID := @DbLookup( "" : "NoCache" ; "" : "" ; "System_Versuchsnummer" ; "System_Versuchsnummer" ; 3);
    @SetDocField(DocID ; "System_Versuchsnummer" ; CounterPlus1);


    REM "Feld Nummer zusammensetzen aus MoC + Zähler und ins Dokument schreiben";
    Nummer_Temp := Counter;
    @Return(Nummer_Temp)


    Unter Maske - Eigenschaften der Reiter mit dem Schlüssel mußt Du noch einen Haken Unter "Verfügbar für Benutzer mit öffentlichem Zugriff " machen.


    und schon bist Du fertig und hast einen Schönen Zähler.


    Ich willauch den Nachteil nicht verheimlichen. Jedesmal wenn Du ein neues Dok erzeugtst wird eine Nr vergeben auch wenn das Dok nicht gespeichert wird.


    Ich hoffe das hat Dir geholfen.


    Gruss
    Bernd99 :-D