Autor Thema: Kollision zwischen OnHelp und Continue = False in Querysave  (Gelesen 6965 mal)

Offline Peter Klett

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

folgendes Problem ist bei einem Kunden aufgetreten, das ich mit einer Testdatenbank auf das Wesentliche eingrenzen konnte. Vielleicht kennt jemand eine Umgehung für das Problem.

In einer Maske wird das OnHelp-Event für den Client mit einem Script belegt, z.B.:

Sub Onhelp (Source As NotesUIDocument)
   Print "F1 gedrückt"
End Sub

In einer Teilmaske, die in die Maske eingebunden ist, wird im Querysave das Speichern unterbunden, z.B.:

Sub Querysave (Source As NotesUIDocument, Continue As Variant)
   Msgbox "Speichern verboten"
   Continue = False
End Sub

Beim Versuch, das Dokument mit der Maske zu speichern, wird zwar die Fehlermeldung "Speichern verboten" ausgegeben, das Dokument aber trotzdem gespeichert.

Entfernt man das Script aus dem OnHelp der Maske, kann das Dokument, wie gewünscht, nicht gespeichert werden.

Gleiches Problem tritt auf, wenn zwei Teilmasken in der Maske eingebunden sind und in der ersten Teilmaske das OnHelp ein Script enthält (die Maske selbst enthält nichts im OnHelp), während die zweite Teilmaske im Querysave das Speichern verhindert.

Dreht man jedoch die Reihenfolge der Teilmasken um, also erst die Teilmaske, die das Speichern verhindert und dann die Teilmaske mit dem OnHelp, funktioniert alles so, wie es soll.


Nachvollziehbar ist das Problem unter 7.03 und 8.5.0.

Nun frage ich mich, was ein OnHelp-Event mit dem Continue des Querysave zu tun hat.

Vielen Dank vorab für Eure Beiträge
« Letzte Änderung: 25.05.10 - 13:15:30 von Peter Klett »

Offline it898ur

  • Senior Mitglied
  • ****
  • Beiträge: 478
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #1 am: 20.05.10 - 08:05:42 »
Hallo,

mit dem Setzen von Continue = false im QuerySave von Teilmasken hatte ich auch schon diverse Probleme (Notes 7.0.2), daher habe ich mir angewöhnt alle Prüfungen in einer Scriptbibliothek zu sammeln und diese im QuerySave der Maske abzuhandeln.
Wenn man Code aber gezielt auslagern will, reicht es oft schon aus ein "Validierungsfeld" einzufügen, welches bei Fehlern aus Teilmasken gesetzt wird. Dann kann man darauf im zentralen Code abfragen.

Gruß

André

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #2 am: 20.05.10 - 08:55:09 »
Hallo André,

vielen Dank für Deinen Beitrag. Habe Deinen zweiten Lösungsvorschlag nachgebaut (der erste kommt aufgrund der Modularisierung durch Teilmasken nicht in Frage).

In der Maske setze ich im Querysave Continue auf False, wenn das Validierungsfeld nicht leer ist.

In einer Teilmaske setze ich im Querysave einen Wert in das Validierungsfeld.

Wenn das Dokument gespeichert wird, durchläuft es erst das Querysave der Maske. Das Validierungsfeld ist leer, also wird Continue nicht auf False gesetzt. Dann wird das Querysave der Teilmaske ausgeführt, welches das Validierungsfeld setzt. Das Dokument ist damit gespeichert. Erst beim nächsten Speicherversuch schlägt die Validierung der Maske zu - zu spät.

Mit dem Setzen des Continue auf False in Teilmasken hatten wir noch nie Probleme (das zugrundeliegende System läuft seit 1999, begonnen unter OS/2 und Notes 4.5.x). Es handelt sich um einen modular aufgebauten Baukasten mit unterschiedlichen funktionalen Teilmasken (Workflowteilmaske rein -> Dokument kann Workflow, Workflowteilmaske raus -> Dokument kann kein Workflow usw.). In jeder Maske befinden sich mindestens 2 Teilmasken (Kopf und Fuß) und dazwischen, je nach Bedarf, 1-5 weitere. Der Kunde kann selbst Teilmasken erstellen und parametrisiert in die Maske einfügen. Zur Validierung wird in jeder (relevanten) Teilmaske im Querysave eine Function verwendet, die eine globale Variable mit Fehlermeldungen füllt. Die letzte Teilmaske (Fuß) überprüft dann die Variable und setzt das Continue auf False (das nur zur ungefähren Beschreibung des Umfeldes).

Durch die Verwendung von OnHelp in der kundeneigenen Teilmaske wurde dann die Validierungssystematik ausgeknippst.

Wenn man das weiß, kann man damit umgehen (früher ging es ja schließlich auch ohne OnHelp), aber merkwürdig finde ich das Verhalten schon. Der Vorteil von OnHelp wäre, dass man auch Hilfen direkt zu aktuellen Feldern aufrufen kann, die sich nicht in der eigenen Teilmaske befinden, ohne die fremden Teilmasken zu ändern, was nicht im Sinne des modularen Baukastens wäre.

BigWim

  • Gast
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #3 am: 20.05.10 - 09:58:22 »
Wie wäre es denn mit der Idee, den Ablauf über das Validierungsfeld zu steuern:

1. "Save" wird ausgelöst
2. Wenn Status des Validierungsfeld <> "ja, speichern" dann QuerySave(Maske)-Continue auf False
3. QuerySave der Teilmasken machen ihre Prüfungen
3a. Im "Fehlerfall" wird Validierungsfeld auf Status "nicht speichern" gesetzt.
3b. die weiteren QuerySave in den Teilmasken bräuchten u. U. Ihre Validierung gar nicht mehr ausführen.
4. QuerySave der letzten Teilmaske (Fuß) macht (ggfs.) ihre Prüfungen
4a. bei "OK" - setzt Validierungsfeld auf "ja, speichern"
4b. löst erneutes Speichern aus
5. QuerySave der Maske Continue auf True
6. QuerySave der Teilmasken können bei diesem Status Ihre Validierungen überspringen
7. Dokument gespeichert

Ich hoffe, ich konnte meine Idee einigermaßen verständlich beschreiben.

Markus


Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #4 am: 20.05.10 - 10:51:08 »
Hallo Markus,

auch Deine Idee (vielen Dank dafür) habe ich nachgebaut. Allerdings führt das zuerst gesetzte Continue = False in der Maske dazu, dass das Speichern sofort beendet und das Querysave in den Teilmasken nicht ausgeführt wird.

Man könnte die Validierung in das Postrecalc verlagern und in das Querysave der Maske ein Source.Refresh einfügen, dann stimmt die Reihenfolge. Das hätte dann aber wieder andere Nachteile, z.B. den, dass Werte von Feldern, die nur berechnet zur Anzeige sind, im folgenden Script nicht mehr im Zugriff sind (in solchen Feldern befinden sich allerdings einige wesentliche Daten zu dem aktuellen User im aktuellen Umfeld).

Wirtschaftlich wäre das ganze nicht vertretbar, da dazu in etwa 100 Schablonen alle individuellen Masken und Teilmasken angepasst werden müssten, und dazu noch alle von den Kunden selbst gebauten Teilmasken.

Da ich auch nicht mehr selbst an dem Baukasten aktiv beteiligt bin, hoffte ich auf eine Lösungsmöglichkeit ausschließlich in der kundeneigenen Teilmaske. Da trotz OnHelp das Querysave in allen Teilmasken ausgeführt und nur nicht auf das Continue reagiert wird, scheint es so, dass dadurch entweder die Variable Continue zerstört oder die Verarbeitung der Variablen gestoppt wird.

Es bleibt wohl nur zu hoffen, dass IBM das Problem behebt. Bis dahin ist OnHelp in diesem Kontext tabu.

BigWim

  • Gast
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #5 am: 22.05.10 - 12:58:51 »
Zitat
Bis dahin ist OnHelp in diesem Kontext tabu.
Eine Idee hätte ich noch: Vielleicht kannst Du mit einem "Temp"-Doc arbeiten, also praktisch mit einer Kopie des aktuellen Dokuments vor den Benutzeraktivitäten.

1. Im PostOpen der Maske Dokument mit Notesdocument.CopyAllItems kopieren.
2. Query-Save der Teilmasken führen Prüfungen durch und setzen Stati
4. Query-Save der Fußmaske entscheidet, welche "Version" des Dokuments produktiv bleibt.
4a. Ist Status = "ja, speichern": nix machen
4b. Ist Status = "nein, nicht speichern": aktuelles Dokument löschen, Temp-Doc (aus PostOpen-Maske) speichern mit doc.Save


Markus

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.170
  • Geschlecht: Männlich
    • Foconis Object Framework
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #6 am: 22.05.10 - 13:26:38 »
Vielleicht kannst du, anstatt continue=false das Feld Saveoptions auf "0" seten um das speichern zu verhindern.

Gruß
Roland
Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #7 am: 25.05.10 - 07:38:18 »
Hallo Markus,

Deine Idee mit dem "Temp"-Doc ist grundsätzlich nicht schlecht. Leider hat sie einen entscheidenden Haken: Bei 4b schreibst Du "aktuelles Dokument löschen". Kein gewöhnlicher Benutzer in dem System hat Löschrechte, in der Regel sind alle Benutzer Autor und es wird mit einem Autorenfeld der Zugriff gesteuert.

Natürlich könnte man anstelle des Löschens auch im aktuellen Dokument alle Items löschen und dann aus dem "Temp"-Doc per CopyAllItems den Urzustand wiederherstellen. Doch auch dann bleibt mindestens ein Problem übrig:

Wenn der Benutzer ein neues Dokument erstellt hat und ihm Informationen fehlen, die er nicht sofort beibringen kann, das Dokument aber ohne diese Information nicht gespeichert werden darf (Fehlermeldung bei Validierung), ist dennoch ein unkorrektes Dokument gespeichert.

Viele Grüße

Peter

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #8 am: 25.05.10 - 08:04:34 »
Hallo Roland,

Continue = False durch SaveOptions  = "0" zu ersetzen, hört sich ganz gut an. Hab das in dem abgespeckten Testsystem nachgebaut. Das funktioniert einwandfrei mit und ohne OnHelp.

Ob ein Umbau ratsam ist, muss allerdings gut überlegt werden. Es gibt andere Aktionen, die abhängig davon sind, ob das Dokument gespeichert werden konnte. Hierzu wird ausgewertet, ob das Speichern des UIDocs fehlerfrei erfolgen konnte (Call notesuidocument.Save). Bei einem korrekt funktionierenden Continue = False gibt notesuidocument.Save einen Fehler aus, bei SaveOptions = "0" nicht. Mindestens diese Routine müsste dann auch geändert werden. Niemand weiß, ob in anderen kundenindividuellen Teilmasken so etwas gebaut wurde. Man könnte natürlich beide Wege parallel gehen, Continue und SaveOptions setzen. Ohne OnHelp ist dann alles "wie früher", mit OnHelp zieht dann nur SaveOptions.

Vielen Dank für die Idee. Wenn es zwingend umgesetzt werden müsste, erscheint mir Dein Ansatz auf jeden Fall eine nähere Untersuchung wert zu sein.

Viele Grüße

Peter

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.170
  • Geschlecht: Männlich
    • Foconis Object Framework
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #9 am: 25.05.10 - 10:03:38 »
Hmm, deine Bedenken kann ich verstehen, deshalb noch ein paar Tipps zum Saveoptions-Feld:
Notes verhält sich bzgl des Wertes etwas "komisch", insbesondere die uiDoc.refresh-Methode, deshalb würde ich nur folgende 2 Zustände zulassen:
SaveOptions := "0"
SaveOptions := @Unavailable
(Im Web muss das Feld als "echtes" Feld auf der Maske/Teilmaske vorhanden sein)

OT: gibt es irgendwo eine Auflistung was die SaveOptions-Werte "0","1", 0, -1, @Unavailable,"",... genau bedeuten?
Die Hilfe beschreibt ja nur "0" und "1", In der original-Mail-DB  werden aber rein numerische Werte verwendet.
Zitat von: IBM, OutOfOfficeLib_DE
Call Me.m_noteUIDoc.document.replaceitemvalue(SAVE_OPTIONS, -1)
/OT

ich hab dein Problem übrigens mal nachgebaut und kann bestätigen, dass die Präsenz eines "onHelp"-Codes den ganzen querySave-Mechanismus durcheinanderbringt.

Evtl solltest du dir eine Alternative für das onHelp-Event überlegen:
- Einen Agenten starten (mit Formelsprache tritt das Problem nicht auf)
- OnHelp in einer TM verwenden (auch da tritt das Problem scheinbar nicht auf)

Allerdings erfordern vermutlich beide Lösungen ein Redesign der Help Routine.
Wenn sich der Code in der Maske befindet muss dieser ggf in einen Agenten/Subform ausgelagert werden, deshalb hätt ich hier noch einen zugegeben unschönen "Würgaround"
- im "onHelp" mit Formelsprache ein Feld auf "1" setzen und einen Recalc auslösen
- im QueryRecalc prüfen ob das Feld gesetzt ist und deinen bisherigen Help-Code ausführen, das Feld natürlich wieder zurücksetzen


Gruß
Roland
Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #10 am: 25.05.10 - 12:52:02 »
Hallo Roland,

vielen Dank für den entscheidenden Hinweis (Formelsprache).

Die funktionierende Lösung sieht folgendermaßen aus:

Im OnHelp-Event der kundenindividuellen Teilmaske (kein Zugriff auf fremde Gestaltungselemente notwendig!) wird dieser Formelaufruf eingetragen:

@Command ([ToolsRunMacro]; "(OnHelp)")

Zusätzlich wird ein Agent "OnHelp" erstellt (Auslösen durch Ereignis: Auswahl in der Agentenliste, Ziel: Keines), der folgendes Script enthält (die tatsächliche Hilfefunktion muss dann noch implementiert werden)

Sub Initialize
   Dim workspace As New NotesUIWorkspace
   Dim uidoc As NotesUIDocument
   Set uidoc = workspace.CurrentDocument
   If uidoc.EditMode Then
      Print "F1 gedrückt " & uidoc.CurrentField
   Else
      Print "F1 gedrückt"
   End If
End Sub

Das Verwenden des Agenten hat den Vorteil, dass die Hilfe auch im Lesemodus des Dokuments aufgerufen werden kann. Die Lösung ist genau das, was ich gesucht habe, einfach, ohne Eingriff in das bestehende System und allein in den vom Kunden beeinflussbaren Elementen realisierbar.

Viele Grüße

Peter

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.170
  • Geschlecht: Männlich
    • Foconis Object Framework
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #11 am: 25.05.10 - 17:15:27 »
Hallo Peter,

dann hat sich das Problem doch noch in Wohlgefallen aufgelöst.

kleiner Tipp noch: falls du eine kontextsensitive Hilfe aufbaust, kannst du übrigens den selben Agenten auch im HelpRequest einer View verwenden. Mit workspace.currentviewAlias kannst du feststellen ob und in welcher View du bist.
Komischerweise ist im Help-Request der View nur Formelsprache möglich... (vermutlich klappts deshalb auch in der Maske nicht)

Gruß
Roland
Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #12 am: 25.05.10 - 17:27:41 »
Hallo Roland,

Danke für den Tipp.

Vielen Dank auch noch einmal allen, die hier mitdiskutiert haben.

Viele Grüße

Peter

Offline cebolina

  • Senior Mitglied
  • ****
  • Beiträge: 386
  • Geschlecht: Männlich
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #13 am: 26.05.10 - 08:33:12 »
@Peter

Vielen Dank für's "Kümmern".
Ich habe den Tipp mit Formelsprache und Agent eingebaut und an meine Erfordernisse angepasst - funktioniert!

Gruß Stefan
Server: Lotus Domino 9.0.1FP4 HF70
Client: Release 9.0.1FP6

BigWim

  • Gast
Re: Kollision zwischen OnHelp und Continue = False in Querysave
« Antwort #14 am: 26.05.10 - 13:55:36 »
Zitat
Kein gewöhnlicher Benutzer in dem System hat Löschrechte, in der Regel sind alle Benutzer Autor und es wird mit einem Autorenfeld der Zugriff gesteuert.
Zumindest das haben wir gemeinsam, allerdings entwickle ich Datenbanken ausschließlich für meinen Arbeitgeber. Insofern ist meine Sichtweise (und mein Erfahrungsschatz) bestimmt sehr beschränkt.

In der Regel sollen aber doch Dokumente gelöscht und dann meistens nach dem Vier-Augen-Prinzip. Einer löscht, ein andere bestätigt. Das steuere ich über Flags. Und ein Agent (mit den entsprechenden Berechtigungen natürlich) löscht dann die Dokumente.

Zitat
Wenn der Benutzer ein neues Dokument erstellt hat und ihm Informationen fehlen, ....  ist dennoch ein unkorrektes Dokument gespeichert.
In meiner Welt ja, aber nur bis der Agent läuft. Denn solche (zumindest für mich) umfangreichen Datenbanken haben immer "irgendwelche" Aufräumagenten, die für Ordnung sorgen (sollten). Mit mehr Erfahrung und einem ausgefeilterem Design käme ich wahrscheinlich gar nicht erst in solche Zwangslagen ::)

Einmal mehr habe ich hier wieder gelernt, wie entscheidend manche Details sind. Deshalb von mir auch ein Danke!

Markus


 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz