Twitter

 6.5.x  7.x  8.5.x 

Programmatische Aktualisierung von privaten Gestaltungselementen

Manfred Meise  4 Januar 2013 16:23:00
 
Wenn eine Domino Anwendung private Gestatungselemente verwendet und die zu aktualisierenden Ansichten/Ordner identifiziert wurden, stellt sich die Frage: "Wie wird die Gestaltungsaktualisierung einer privaten Ansicht / eines privaten Ordners angestoßen?

Ansichten


Private Ansichten könnten aktualisiert werden, müssen Sie jedoch nicht. Man kann den Lösungsansatz verfolgen, ein Namenschema zu entwerfen, bei dem der Ansichtsname eine Versionkennung enthält, der AliasName jedoch stets unverändert beibehalten wird: z.B.:
 
AllByName-300 | AllByName

Wenn nun programmatisch mit
 
      Set view = db.GetView ("AllByName")
     
      If Not IsEmpty (view.readers) Then
              Call view.Remove
      End If


jeweils die privaten Kopie (das Gestaltungselement, welches mit einen Reader Feld mit meinem Namen geschützt ist) der Ansicht löscht, dann wird diese private Kopie vom Lotus Notes Client erneut erstellt, wenn der User auf den Ansichtsnamen (Gliederungseintrag) der Navigation klickt. Selbst alte private Ansichtskopien stören nicht, da sie vom Indexer nicht berücksichtigt werden.


Ordner


Verwendung undokumentierte @Formel


Bei Ordnern ist das Aktualisieren unvergleich schwieriger, da deren Inhalt ja zur Laufzeit vom Benutzer festgelegt und beim Update nicht verloren gehen soll. Schnell stößt man auf eine undokumentierte Formelfunktion (aus dem Mailfile) How does the mail template's new agent upgrade folder designs:

@UpdateViewDesign (; )

und fragt sich, ob die helfen würde. Doch schon beim Schreiben der Formel stellt sich die Frage: Welcher Ordner ist die Vorlage und welcher das Ziel? Heißen doch beide gleich... Erste Tests ergeben schnell, das keine Aktualsierung stattfindet (wenn beide Argumente den gleichen Wert haben), weil wohl jeweils auf die private Kopie der Gestaltung referenziert wird. Kein Problem: "Benenne ich die Kopie des Ordners um, bevor ich diese Funktion ausführe, und danach wieder zurück. Hierdurch erhält man zwar eine Aktualisierung (ersichtlich im Designer), doch läßt sich das Gestaltungselement anschließend nicht mehr im Client öffnen (geht in eine Endlosschleife "Öffne Ansicht ..."). Somit kein gültiger Lösungsansatz.

Löschen/Neuanlage eines privaten Ordners


Somit bleibt nur der Weg: Ordner per Script löschen und durch den Client beim Klick neu anlegen lassen. Ach ja, die darin enthaltenen Dokumente müssen natürlich erhalten bleiben. Kein Problem denke ich: Mit set veCol = view.Allentries hole ich mir alle Dokumente aus dem veralteten Ordner ab, lege sie mit call veCol.PutAllInfolder ("Temp-Folder") in einem temporären Ordner ab, lösche den Ordner und hole die Dokumente nach dem Öffnen des Ordners (im PostOpen Event) wieder aus dem Temp-Folder ab. Kaum zu gleuben, das hat funktioniert ! Bis ich diesen Lösungsansatz mit normalen Benutzerrechten getestet hatte: Der Zwischenordner, welcher mit .PutAllInFolder verwendet/erstellt wird, ist vom Typ "Gemeinsamer Ordner". Leider können Benutzer mit "Autor-Berechtigung" dieses Attribut nicht erhalten. Wenn es sich bei der zu aktualisierenden Anwendung um z.B. eine Workflowanwendung handelt, wo man aus anderen Gründen den Benutzern nicht mehr Berechtigungen geben kann/will, scheidet somit auch diese Variante aus.

Wir erstellt man mit LotusScript eine private Ansicht? Längere Recherchen legten den Verdacht nahe: "Gar nicht!". Das kann doch wohl nicht wahr sein ! Ist doch ein Gestaltungsdokument nichts anderes als ein "Dokument" mit bestimmten Feldern. Somit müsste man doch mit nachfolgendem Code die private Kopie eines gemeinsamen Gestaltungselementes "MyDocs" dublizieren und anschließend umbenennen können:

 
Set
view = db.GetView ("MyDocs")
If
(View.isPrivate) And (View.Isfolder) And Not IsEmpty (view.Readers) Then

      'Erstelle eine Kopie des Gestaltungselementes (weil wir ggf. keine Public folder erstellen dürfen)
      Set docOld = db.GetDocumentByUNID (view.UniversalID)
      Set doc = docOld.CopyToDatabase (db)
      doc.~$Title = "Temp-Folder"  '...und benenne diese um
      Call doc.Save (True, True)
End
If  


Super! Hiermit erhalte ich eine Kopie eines privates Ordners, die wiederum einen privaten Ordner des Benutzers darstellt (und sogar alle zuvor darin abgelegten Dokumente mit übernimmt).

Wenn man diesen Lösungsansatz mit dem anschließenden Löschen des Ordners (siehe Beispiel unter Ansichten), der Erstellung eines neuen privaten Gestaltungselementes durch den Lotus Notes Client mit ein wenig Code im Postopen Event des Ordners kombiniert, erhält man eine aktualisierte Fassung des Ordners - auch für Benutzer mit max. Autor-Recht- ohne deren Inhalt zu verlieren. Auch die Performance ist mehr als akzeptabel.

 
Sub
ProcessPostOpen (Source As NotesUIView)
       
       Dim db                                         As NotesDatabase
       Dim view                                         As NotesView
       Dim veCol                                         As NotesViewEntryCollection

       On Error Resume Next
       
       Set db = source.View.Parent
       
       'Lokalisiere meinen temporären Odner
       Set view = db.GetView ("Temp-Folder")
       If Not view Is Nothing Then
               
               'Inhalte nur bearbeiten, wenn dieser Ordner nicht der temporäre Ordner ist
               If Not IsEmpty (Source.view.Readers) Then
                       'Da könnten/müssten noch Dokumente "geparkt" sein....
                       Set veCol = view.AllEntries
                       Call vecol.PutAllInFolder (source.View.Name)
                       
                       'Temporären Ordner löschen
                       Call view.Remove
                       
               End If
       End If
       
End
Sub

Sag ich doch: "Geht nicht, gibt's nicht (oder mindesten nicht zu häufig).

Dieser Artikel ist Teil der Artikelserie
:  Gestaltungsaktualisierung privater Ansichten und Ordner stellt eine echte Herausforderung dar