Autor Thema: Bearbeitung eines einzelnen Feldes festhalten à la "last edited by"  (Gelesen 5640 mal)

Offline Grinsekatze

  • Frischling
  • *
  • Beiträge: 6
  • Geschlecht: Weiblich
Hallo liebe Mitglieder des Notes-Forums,

ich programmiere seit 2 Wochen an einer Notes-Datenbank herum und das Forum hier hat mir schon wahnsinnig gute Dienste geleistet und viele Fragen beantwortet. Zu meinem aktuellsten Problem konnte ich jedoch keine Antwort finden, deshalb bin ich nun selbst aktiv geworden ;)
Ich kenn mich mittlerweile mit den Grundlagen glaub ich ganz gut aus und hab auch schon ein bisschen LotusScript programmiert (aber nur wenige Zeilen!).


Mein Problem ist folgendes:

Ich habe verschiedene Felder in meinem Dokument, deren Aktualität gewährleistet sein muss. Deshalb möchte ich nun zu jedem dieser Textfelder eine Art "last edited by"- Feld zu erstellen, das automatisch abspeichert, von wem und wann dieses eine Feld zuletzt bearbeitet wurde.
Ich dachte daran, Name und Zeit in zwei Hidden Fields abzuspeichern und als Computed Value unter den Informationsfeldern anzeigen zu lassen.

Mir ist bereits bekannt, dass ich über die @Funktionen @Now und @UserName Zeitpunkt und User herausbekomme, aber ich habe es bis jetzt nur geschafft das für das gesamte Dokument zu nutzen und eben anzeigen zu lassen, wer wann das ganze Dokument zuletzt bearbeitet hat.

Kann mir also irgendjemand auf die Sprünge helfen, wie ich dies für ein einzelnes Feld festhalten kann?


Schonmal herzlichen Dank im Voraus für eure Hilfe!
Liebe Grüße,
Sarah

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.885
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Es gibt hier im Forum eine Best Practices für eine Feld- Historie, und ich glaube sogar eine fertige LotusScript- Library... evtl. auch unter dem Stichwort "Audit Trail"...
Einfach mal suchen, das wirst Du sicher finden...
Gruss
Torsten (Tode)

P.S.: Da mein Nickname immer mal wieder für Verwirrung sorgt: Tode hat NICHTS mit Tod zu tun. So klingt es einfach, wenn ein 2- Jähriger versucht "Torsten" zu sagen... das klingt dann so: "Tooode" (langes O, das r, s und n werden verschluckt, das t wird zum badischen d)

Offline Grinsekatze

  • Frischling
  • *
  • Beiträge: 6
  • Geschlecht: Weiblich
Bei den Best Practices habe ich leider nichts gefunden  :-:

Nach weiterer Suche bin ich allerdings hierauf gestoßen: http://sw-guide.de/lotus-notes-domino/lotusscript-history/

Mein Problem ist jedoch, dass mir das ganze etwas zu "mächtig" erscheint und außerdem will ich ja keine komplette Dokumenthistorie, sondern ein einzelner Zeitstempel für ca. 10 Felder ist ja alles, was ich hauptsächlich brauch.

Ich bin jetzt auf die Idee verfallen den Feldinhalt der betreffendem Inhaltsfelder einfach beim Öffnen des Dokumentes in ein Hidden Field zu übertragen und beim Schließen des Docs auf Gleichheit zu prüfen. Wenn der Inhalt geändert wurde wird die aktuelle Zeit gespeichert.

Geht das prinzipiell?
Und ist diese Lösung halbwegs praktikabel oder schlägt jetzt jeder der das liest und sich auskennt die Hände über dem Kopf zusammen?

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Hallo Sarah,

um das Dir Mögliche abzuprüfen: Programmierst Du (nur) in Formelsprache oder geht auch LotusScript?
Weiters: Können wir das prinzipielle Procedere an einem Deiner zu überwachenden Felder fix machen (damit wir dann die gleiche Sprache sprechen)?
Was hast Du schon als Code?

Weitere Frage:
Mit wie vielen Repliken dieser Datenbank arbeitet Ihr? Hintergrund: Wenn (auch nur) ein Feld bei jeder Dokumentänderung einen neuen Wert bekommt (wie jetzt Deine document history), dann kannst Du im Fall der Fälle keine Replizierkonflikte mehr mischen, sondern erzeugst immer Conflicts. In der Regel ist dieses Vorgehen also alles andere als eine gute Idee.

Auf jeden Fall: Dir kann hier geholfen werden!

Bernhard

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Ich denke, das Problem mit den Replizierkonflikten entfällt, wenn zu jedem Feld separate Historienfelder erstellt werden. Ändert sich Feld A, ändert sich auch Historie A, gleiches bei B usw.. Das sieht strukturell schon ganz gut aus.

Willst Du Script verwenden, ist es wohl am einfachsten, die Historienfelder über das onChange-Event des jeweiligen Textfeldes zu setzen.

In Formelsprache halte ich folgenden Ansatz für denkbar. Wichtig ist die exakte Reihenfolge der Felder in der Maske:

Textfeld (bearbeitbar)
HistorienfeldDatum (berechnet) Formel: @If (Textfeld != Vergleichsfeld; @Now; @ThisValue)
HistorienfeldUser (berechnet) Formel: @If (Textfeld != Vergleichsfeld; @Username; @ThisValue)
Vergleichsfeld (berechnet) Formel: Textfeld

Beim Speichern oder beim Aktualisieren werden die Felder von links nach rechts, und von oben nach unten gerechnet. Wurde das Textfeld geändert, werden erst die Historienfelder aktualisiert, bevor das Vergleichsfeld den neuen Wert des Textfeldes erhält (nicht getestet, sollte aber klappen). Einziger Nachteil: Du hast zusätzliche Vergleichsfelder im Dokument. Leider kannst Du das Vergleichsfeld nicht berechnet zur Anzeige machen, da dann beim Berechnen nach dem Öffnen immer eine Historie geschrieben wird, falls das Textfeld nicht leer ist.

Das Vergleichsfeld entfällt bei einer Lösung in Script.

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Prinzipielle Zustimmung insofern, dass Replizierkonflikte und Aushebeln des Mischens von Replizierkonflikten minmiert werden, wenn geändertes Feld und zwangsweise anhängendes Historienfeld gekoppelt sind.

Ich habe aber wieder einen A-Bär:
On Change: Never! Das hat mit der abschliessenden Speicherung nichts zu tun. Selbst die Speicherung an sich muss nicht aussagekräftig sein, da es ja durchaus helle User gibt, die zwischenspeichern.

Daher mein Vorschlag:
1) Zu den betreffenden Feldern gibt es EIN History-Field mit Wer und wann (wozu zwei?)
2) Das ganze passiert mindestens erst beim Speichern (QuerySave). Das geht auch noch mit @Functions ("schön" ist aber in diesem Fall etwas anderes)
3) Besser: Das passiert durch vorher / nachher_Vergleich (PostOpen / QueryClose) erst, wenn das Dokument im Frontend gespeichert wurde und am Schliessen ist (QueryClose).
4) Noch besser: Das ganze ist als Routine ausgelagert, dass es auch Agents verwenden können 8an Entwickler: MÜSSEN), wenn Änderungen im Backend passieren.

Völlig ausgeklammert habe ich hier den Hintergrund / die Notwendigkeit etc. dieser Protokollierung. Dies wird sicher in jedem Anwendungsfall anders aussehen. Ich kenne derartige Anwendungsfälle in erster Linie in Zusammenhängen, wo man wer / wann /warum erkennen muss und ich hierzu Felder überwachen muss (zum Beispiel Urlaubskontingente: Warum hat Mitarbeiter X auf einmal in 2011 33 Tage Urlaub, in 2012 aber nur 27? Weil er per Sondervereinbarung seinen Urlaub wegen Streik verlängern durfte und sich aus dem 2012er Kontingent bedienen durfte).

Soweit meine 2ct.

Bernhard

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Ich möchte eigentlich nicht wieder eine Grundsatzdiskussion lostreten, aber ein paar Anmerkungen habe ich schon noch:

Dem "Never" für das Event onChange muss ich widersprechen. Natürlich gefällt mir die Variante mit Postopen merken und Querysave schreiben selbst auch am besten, ist aber für einen Neuling schwieriger, da in drei verschiedenen Elementen etwas eingetragen werden muss. Declarations, Postopen und Querysave, evtl. auch im Queryclose. Beim onChange ist es ein einziges Script (allerdings pro Feld). Was kann passieren, wenn man onChange nimmt? Der Benutzer ändert den Inhalt des Feldes von A in B und aktualisiert/speichert das Dokument, die Historie wird eingetragen. Dann überlegt er sich das anders und ändert zurück in A. Wieder erfolgt ein Eintrag in die Historie. Was ist daran falsch? Der Benutzer hat definitiv an dem Feld herumgefummelt, auch wenn am Ende faktisch keine Änderung erfolgt ist. Wo ist der Unterschied zu einem Öffnen des Dokuments, Ändern, Speichern, Schließen, Überlegen, wieder Öffnen, Zurückändern, Speichern und Schließen? Warum soll das eine protokolliert werden und das andere nicht? Finde ich nicht wirklich gravierend falsch.

Zum Queryclose: Ein Schreiben einer Historie im Queryclose bedeutet, dass das Dokument beim Schließen, nach dem letzten Speichern, noch einmal gespeichert werden muss. Das funktioniert in schlichten Anwendungen sicher problemlos. Aber wie sieht das in Dokumenten aus, die einem Workflow unterliegen? Möglicherweise ist der Benutzer beim Schließen des Dokumentes nicht mehr Autor des Dokuments, weil er es an den nächsten Bearbeiter weitergegeben hat (da muss dann im Querysave ein temporäres Autorenfeld gesetzt werden, was im Queryclose wieder entfernt werden muss, weil sonst der Workflow dahin ist). Eventuell gibt es durch die Veränderung im Workflow nun neue Validierungsregeln, die ein Speichern im Frontend verhindern, also müsste das Speichern im Backend erfolgen. Ggf. hat ein solches Dokument zum fehlerfreien Schließen ein SaveOptions = "0" eingetragen, das im Falle des Speicherns im Backend ins Dokument gelangt und das zukünftige Speichern verhindert, wenn man es nicht wieder entfernt, usw.. Hier würde ich fast ein "Never" anbringen wollen, obwohl man ja nie nie sagen soll, und es auch Notwendigkeiten gibt, im Queryclose speichern zu müssen (Dateianhangshandling z.B., genau dabei hatte ich mal alle o.g. Problematiken zu lösen, und das alles in einer allgemeingültigen Teilmaske, ohne zu wissen, welche "Schweinereien" von anderen (zukünftigen, kundenindividuellen) Teilmasken verursacht werden, was die Sache nicht einfacher machte).

Um es kurz zu machen: Sowas würde ich nicht jemandem empfehlen, der "auch schon ein bisschen LotusScript programmiert" hat, denn schließlich soll das Resultat von der/demjenigen auch verstanden und bewältigt werden können.

Zu Historien ganz allgemein: Um wirklich eine genaue Historie darzustellen, baue ich Dokumente so, dass sie freigegeben werden müssen. Erst dann sind sie gültig und können im System verwendet werden. Diese Dokumente sind nicht mehr von Benutzern änderbar. Änderungen erfolgen, in dem man eine neue Version des Dokuments erstellt, mit Freigabe der neuen Version wird die alte Version ungültig (periodischer Agent, z.B. per agent.RunOnServer), verbleibt aber in der Datenbank. So kann ich später "durch die Zeit reisen" und jede Änderung des Dokuments nachvollziehen, vom Inhalt, vom Datum und vom Verursacher. Welchen Wert hat die Information, wer wann ein Feld zuletzt geändert hat, wenn es öfter geändert wurde und wenn ich nicht weiß, welchen Inhalt es vorher hatte?

Offline Grinsekatze

  • Frischling
  • *
  • Beiträge: 6
  • Geschlecht: Weiblich
Wow - es ist ja unglaublich wie schnell man hier ausführliche Antworten bekommt!
Erst einmal ganz herzlichen Dank an alle, die sich zum Thema geäußert haben.

Das einzige Problem ist, dass ich nur die Hälfte eurer Antworten versteh. Ich stell gerade fest, dass ich wohl doch nur einen kleinen Bruchteil von dem was ich dachte wohl wirklich kann.

Ich habe gestern nochmal mit meiner Chefin über die Anforderung gesprochen und sie meinte, dass sie eigentlich doch ganz gerne das mit der History Class umgesetzt hätte, nachdem ich ihr davon erzählt habe.
Also dachte ich "Super, da hats 'ne schöne Anleitung, das bekommst du hin."
Aber weit gefehlt...

Da es den Anschein hat, als sei die History Klasse von Michael Wöhr hier einigen ein Begriff erzähl ich einfach mal, wo's hakt...

Also ich habe die Anleitung mit den sechs Schritten so weit befolgt und bekomme in meiner Script Library auch keine Fehler angezeigt.

Allerdings hängt es bei mir gerade irgendwie bei der Sache mit dem History-Textfeld an sich im Dokument. Ich weiß einfach nicht, was ich als "value" eintragen muss (das ganze ist ja ein "computed when composed"-Feld, also muss da ja wohl irgendeine Formel rein, die die Funktion aufruft oder ähnliches?).
Zudem beschleicht mich die leise Vermutung, dass man im Code an sich vielleicht ja auch noch irgendwelche Änderungen machen muss... sollte dies der Fall sein, welche?

Würde mich über jegliche Ratschläge freuen!
Solltet ihr der Meinung sein, dass mir bei solchen Wissenslücken nicht zu helfen ist, dann würde ich an der von euch beschriebenen Umsetzung mit Formelsprache versuchen und das muss dann eben doch ausreichen.

Liebe Grüße,
Sarah

Offline Grinsekatze

  • Frischling
  • *
  • Beiträge: 6
  • Geschlecht: Weiblich
Nachtrag:
Hab gerade wohl wirklich an einer Hirnblockade gelitten... Das mit dem "value" des Textfelds hat sich erledigt!

Jetzt zeigt es mir immerhin schon an, wann ich das Dokument erstellt habe :)

Driri

  • Gast
Damit dann auch Änderungen an bestimmten Felder dokumentiert werden, mußt Du im Postopen der Maske noch tätig werden. Das sollte aber in der Anleitung beschrieben sein.

Offline Grinsekatze

  • Frischling
  • *
  • Beiträge: 6
  • Geschlecht: Weiblich
Unglaublich, es tut!!
Bin restlos begeistert.

Danke für alle Hilfe.

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz