EMails mit iPhone vom Lotus Notes Traverler Server recht langsam

20. Februar 2013 Posted by Manfred Meise

Grundsätzlich hat sich ein EDV Benutzer heutiger Tage ja an Sanduhren und Fortschrittsbalken gewöhnt (nicht, das ich dazu gehöre...). Doch in letzter Zeit war es schon sehr zäh, meine Mails auf mein iPhone zu holen. Ich war unsicher, ob die Bugreports bei Apple zu ActiveSync auch mich betreffen.

Umsomehr hat mein heutiges Update auf iOS 6.1.2 eine positive Überraschung gebracht. Mein Traveler Server reagiert jetzt wieder wie gewohnt schnell.

EMails mit iPhone vom Lotus Notes Traveler Server recht langsam

20. Februar 2013 Posted by Manfred Meise

Grundsätzlich hat sich ein EDV Benutzer heutiger Tage ja an Sanduhren und Fortschrittsbalken gewöhnt (nicht, das ich dazu gehöre...). Doch in letzter Zeit war es schon sehr zäh, meine Mails auf mein iPhone zu holen. Ich war unsicher, ob die Bugreports bei Apple zu ActiveSync auch mich betreffen.

Umsomehr hat mein heutiges Update auf iOS 6.1.2 eine positive Überraschung gebracht. Mein Traveler Server reagiert jetzt wieder wie gewohnt schnell.

Zugriff auf Notes.ini Variablen erfolgt gecachet

17. Januar 2013 Posted by Manfred Meise

Gelegentlich speichere ich innerhalb von Domino Anwendungen Werte in der Notes.ini (ja, ich weiĂź dass Profildokumente in vielen Fällen flexibler sind...).  Seit einigen Produktversion (mir ist nicht ganz klar, ab welcher Major-/Mino-Release) werden die im Code gesetzten Einträge noch nicht wirklich in die Betriebssystemdatei geschrieben oder während der Client AusfĂĽhrung auf Betriebssystemebene veränderte Inhalte in z.B. LotusScript verfĂĽgbar sein (==>Caching zur Laufzeitoptimierung).

Dieses fĂĽhrt somit zu einem jĂĽngst aufgetretenen Problem, bei dem ich im Rahmen eines Datenbankscriptes einen Semaphor setze und diesen z.B. im Rahmen eines PostOpen-Scriptes einer Ansicht (somit neue Session) auslesen wollte:

Datenbankscript:

 
Sub
Postopen(Source As Notesuidatabase)

      Dim s         As New NotesSession
      Dim db        As NotesDatabase
      Dim view      As NotesView
     
      Call s.Setenvironmentvar("Semaphor1", "1")        
     
      Set db         = s.Currentdatabase
      Call Source.OpenView("MyView")
       
End
Sub


Ansicht "MyView":

 
Sub Postopen(Source AsNotesuiview)
        Dim s         As New NotesSession
       
        Messagebox "INI-Var:" & s.GetEnvironmentString ("Semaphor1")
       
End Sub


Leider kommt der Wert im Ansichtsereignis nicht an. Vergleichbarer Code in zwei separaten Agent funktioniert einwandfrei. Somit bleibt mir auch im vorliegenden Fall nur die Umstellung auf Profildokumente mit dem Risiko von Dubletten, wenn Benutzer Repliken auf verschiedenen Servern verwenden.....

Zugriff auf Notes.ini Variablen erfolgt gecachet

17. Januar 2013 Posted by Manfred Meise

Gelegentlich speichere ich innerhalb von Domino Anwendungen Werte in der Notes.ini (ja, ich weiß dass Profildokumente in vielen Fällen flexibler sind...).  Seit einigen Produktversion (mir ist nicht ganz klar, ab welcher Major-/Mino-Release) werden die im Code gesetzten Einträge noch nicht wirklich in die Betriebssystemdatei geschrieben oder während der Client Ausführung auf Betriebssystemebene veränderte Inhalte in z.B. LotusScript verfügbar sein (==>Caching zur Laufzeitoptimierung).

Dieses führt somit zu einem jüngst aufgetretenen Problem, bei dem ich im Rahmen eines Datenbankscriptes einen Semaphor setze und diesen z.B. im Rahmen eines PostOpen-Scriptes einer Ansicht (somit neue Session) auslesen wollte:

Datenbankscript:

 
Sub
Postopen(Source As Notesuidatabase)

      Dim s         As New NotesSession
      Dim db        As NotesDatabase
      Dim view      As NotesView
     
      Call s.Setenvironmentvar("Semaphor1", "1")        
     
      Set db         = s.Currentdatabase
      Call Source.OpenView("MyView")
       
End
Sub


Ansicht "MyView":

 
Sub Postopen(Source AsNotesuiview)
        Dim s         As New NotesSession
       
        Messagebox "INI-Var:" & s.GetEnvironmentString ("Semaphor1")
       
End Sub


Leider kommt der Wert im Ansichtsereignis nicht an. Vergleichbarer Code in zwei separaten Agent funktioniert einwandfrei. Somit bleibt mir auch im vorliegenden Fall nur die Umstellung auf Profildokumente mit dem Risiko von Dubletten, wenn Benutzer Repliken auf verschiedenen Servern verwenden.....

Zugriff auf Notes.ini Variablen erfolgt gecachet

17. Januar 2013 Posted by Manfred Meise

Gelegentlich speichere ich innerhalb von Domino Anwendungen Werte in der Notes.ini (ja, ich weiß dass Profildokumente in vielen Fällen flexibler sind...).  Seit einigen Produktversion (mir ist nicht ganz klar, ab welcher Major-/Mino-Release) werden die im Code gesetzten Einträge noch nicht wirklich in die Betriebssystemdatei geschrieben oder während der Client Ausführung auf Betriebssystemebene veränderte Inhalte in z.B. LotusScript verfügbar sein (==>Caching zur Laufzeitoptimierung).

Dieses führt somit zu einem jüngst aufgetretenen Problem, bei dem ich im Rahmen eines Datenbankscriptes einen Semaphor setze und diesen z.B. im Rahmen eines PostOpen-Scriptes einer Ansicht (somit neue Session) auslesen wollte:

Datenbankscript:

 
Sub
Postopen(Source As Notesuidatabase)

      Dim s         As New NotesSession
      Dim db        As NotesDatabase
      Dim view      As NotesView
     
      Call s.Setenvironmentvar("Semaphor1", "1")        
     
      Set db         = s.Currentdatabase
      Call Source.OpenView("MyView")
       
End
Sub


Ansicht "MyView":

 
Sub Postopen(Source AsNotesuiview)
        Dim s         As New NotesSession
       
        Messagebox "INI-Var:" & s.GetEnvironmentString ("Semaphor1")
       
End Sub


Leider kommt der Wert im Ansichtsereignis nicht an. Vergleichbarer Code in zwei separaten Agent funktioniert einwandfrei. Somit bleibt mir auch im vorliegenden Fall nur die Umstellung auf Profildokumente mit dem Risiko von Dubletten, wenn Benutzer Repliken auf verschiedenen Servern verwenden.....

Zugriff auf Notes.ini Variablen erfolgt gecachet

17. Januar 2013 Posted by Manfred Meise

Gelegentlich speichere ich innerhalb von Domino Anwendungen Werte in der Notes.ini (ja, ich weiß dass Profildokumente in vielen Fällen flexibler sind...).  Seit einigen Produktversion (mir ist nicht ganz klar, ab welcher Major-/Mino-Release) werden die im Code gesetzten Einträge noch nicht wirklich in die Betriebssystemdatei geschrieben oder während der Client Ausführung auf Betriebssystemebene veränderte Inhalte in z.B. LotusScript verfügbar sein (==>Caching zur Laufzeitoptimierung).

Dieses führt somit zu einem jüngst aufgetretenen Problem, bei dem ich im Rahmen eines Datenbankscriptes einen Semaphor setze und diesen z.B. im Rahmen eines PostOpen-Scriptes einer Ansicht (somit neue Session) auslesen wollte:

Datenbankscript:

 
Sub
Postopen(Source As Notesuidatabase)

      Dim s         As New NotesSession
      Dim db        As NotesDatabase
      Dim view      As NotesView
     
      Call s.Setenvironmentvar("Semaphor1", "1")        
     
      Set db         = s.Currentdatabase
      Call Source.OpenView("MyView")
       
End
Sub


Ansicht "MyView":

 
Sub Postopen(Source AsNotesuiview)
        Dim s         As New NotesSession
       
        Messagebox "INI-Var:" & s.GetEnvironmentString ("Semaphor1")
       
End Sub


Leider kommt der Wert im Ansichtsereignis nicht an. Vergleichbarer Code in zwei separaten Agent funktioniert einwandfrei. Somit bleibt mir auch im vorliegenden Fall nur die Umstellung auf Profildokumente mit dem Risiko von Dubletten, wenn Benutzer Repliken auf verschiedenen Servern verwenden.....

Gestaltungsaktualisierung privater Ansichten und Ordner stellt eine echte Herausforderung dar

9. Januar 2013 Posted by Manfred Meise

Als Domino Entwickler weiß man um die Vor- und Nachteile von z.B. von Ansichten und Ordnern "Gemeinsam, privat bei Erstbenutzung" und setzt diese nur sehr selektiv ein. Trotzdem habe ich mich bei einer unserer zentralen Domino Anwendungen entschieden, hiervon Gebrauch zu machen. Da die Anwendung ständig Funktionserweiterungen erfährt, kommt es immer wieder vor, dass auch die Ansichten und Ordner überarbeitet oder erweitert werden müssen. Somit stellt sich bei unseren Kunden, welche diese Anwendung einsetzen die Frage, wie die neue Gestaltung einer Folgeversion in die bereits vorhandenen Installationen kommt, nachdem wir eine neue Schablonenversion der Anwendung bereit stellen!

Hierzu haben wir im Verlauf der Zeit zahlreiche (vorwiegend negative) Erfahrungen sammeln dürfen, welche ich in der nachfolgenden Artikelreihe zusammengetragen habe.

Warum setzen Entwickler private Gestaltungselemente ein?
Leistungsmerkmale privater Ansichten und Ordner sind gelegentlich fachlich gefordert.


Alternativen zum Einsatz privater Gestaltungselemente
Zur Vermeidung der Nachteile privater Gestaltungselemente (u.A. mangelnde Aktualisierungsfähigkeit) bieten sich durchaus Alternativen an.


Speicherort der privaten Gestaltungselemente
Zunächst muss man sich klar werden, wo die Informationen der persönlichen Gestaltungselemente gespeichert werden: In der Datenbank oder im persönlichen Desktop. Man könnte denken "Egal" - doch weit gefehlt! Nicht nur das Roaming sondern auch das Client-Verhalten ist zu beobachten.


Erkennung/unterscheidung von neuen Versionen
Um die Gestaltung neuer Versionen der gemeinsamen Vorlage für Ansichten und Ordner von bereits vorhandenen privaten Kopien unterscheiden zu können, eignen sich leider nicht die üblichen Verfahren (neue Versionen mit neuem Zeitstempel).


Aktualisierung der Gestaltung
Anwendungslogik, welche im Kontext des Benutzers abläuft, entscheidet über die Notwendigkeit und führt die Aktualisierung der privaten Gestaltungselemente durch.


... um das Ergebnis vorwegzunehmen: Zahlreiche leidvolle Erfahrungen mit Happy End.

Gestaltungsaktualisierung privater Ansichten und Ordner stellt eine echte Herausforderung dar

9. Januar 2013 Posted by Manfred Meise

Als Domino Entwickler weiß man um die Vor- und Nachteile von z.B. von Ansichten und Ordnern "Gemeinsam, privat bei Erstbenutzung" und setzt diese nur sehr selektiv ein. Trotzdem habe ich mich bei einer unserer zentralen Domino Anwendungen entschieden, hiervon Gebrauch zu machen. Da die Anwendung ständig Funktionserweiterungen erfährt, kommt es immer wieder vor, dass auch die Ansichten und Ordner überarbeitet oder erweitert werden müssen. Somit stellt sich bei unseren Kunden, welche diese Anwendung einsetzen die Frage, wie die neue Gestaltung einer Folgeversion in die bereits vorhandenen Installationen kommt, nachdem wir eine neue Schablonenversion der Anwendung bereit stellen!

Hierzu haben wir im Verlauf der Zeit zahlreiche (vorwiegend negative) Erfahrungen sammeln dürfen, welche ich in der nachfolgenden Artikelreihe zusammengetragen habe.

Warum setzen Entwickler private Gestaltungselemente ein?
Leistungsmerkmale privater Ansichten und Ordner sind gelegentlich fachlich gefordert.


Alternativen zum Einsatz privater Gestaltungselemente
Zur Vermeidung der Nachteile privater Gestaltungselemente (u.A. mangelnde Aktualisierungsfähigkeit) bieten sich durchaus Alternativen an.


Speicherort der privaten Gestaltungselemente
Zunächst muss man sich klar werden, wo die Informationen der persönlichen Gestaltungselemente gespeichert werden: In der Datenbank oder im persönlichen Desktop. Man könnte denken "Egal" - doch weit gefehlt! Nicht nur das Roaming sondern auch das Client-Verhalten ist zu beobachten.


Erkennung/unterscheidung von neuen Versionen
Um die Gestaltung neuer Versionen der gemeinsamen Vorlage für Ansichten und Ordner von bereits vorhandenen privaten Kopien unterscheiden zu können, eignen sich leider nicht die üblichen Verfahren (neue Versionen mit neuem Zeitstempel).


Aktualisierung der Gestaltung
Anwendungslogik, welche im Kontext des Benutzers abläuft, entscheidet über die Notwendigkeit und führt die Aktualisierung der privaten Gestaltungselemente durch.


... um das Ergebnis vorwegzunehmen: Zahlreiche leidvolle Erfahrungen mit Happy End.

Gestaltungsaktualisierung privater Ansichten und Ordner stellt eine echte Herausforderung dar

9. Januar 2013 Posted by Manfred Meise

Als Domino Entwickler weiß man um die Vor- und Nachteile von z.B. von Ansichten und Ordnern "Gemeinsam, privat bei Erstbenutzung" und setzt diese nur sehr selektiv ein. Trotzdem habe ich mich bei einer unserer zentralen Domino Anwendungen entschieden, hiervon Gebrauch zu machen. Da die Anwendung ständig Funktionserweiterungen erfährt, kommt es immer wieder vor, dass auch die Ansichten und Ordner überarbeitet oder erweitert werden müssen. Somit stellt sich bei unseren Kunden, welche diese Anwendung einsetzen die Frage, wie die neue Gestaltung einer Folgeversion in die bereits vorhandenen Installationen kommt, nachdem wir eine neue Schablonenversion der Anwendung bereit stellen!

Hierzu haben wir im Verlauf der Zeit zahlreiche (vorwiegend negative) Erfahrungen sammeln dĂĽrfen, welche ich in der nachfolgenden Artikelreihe zusammengetragen habe.

Warum setzen Entwickler private Gestaltungselemente ein?
Leistungsmerkmale privater Ansichten und Ordner sind gelegentlich fachlich gefordert.


Alternativen zum Einsatz privater Gestaltungselemente
Zur Vermeidung der Nachteile privater Gestaltungselemente (u.A. mangelnde Aktualisierungsfähigkeit) bieten sich durchaus Alternativen an.


Speicherort der privaten Gestaltungselemente
Zunächst muss man sich klar werden, wo die Informationen der persönlichen Gestaltungselemente gespeichert werden: In der Datenbank oder im persönlichen Desktop. Man könnte denken "Egal" - doch weit gefehlt! Nicht nur das Roaming sondern auch das Client-Verhalten ist zu beobachten.


Erkennung/unterscheidung von neuen Versionen
Um die Gestaltung neuer Versionen der gemeinsamen Vorlage für Ansichten und Ordner von bereits vorhandenen privaten Kopien unterscheiden zu können, eignen sich leider nicht die üblichen Verfahren (neue Versionen mit neuem Zeitstempel).


Aktualisierung der Gestaltung
Anwendungslogik, welche im Kontext des Benutzers abläuft, entscheidet über die Notwendigkeit und führt die Aktualisierung der privaten Gestaltungselemente durch.


... um das Ergebnis vorwegzunehmen: Zahlreiche leidvolle Erfahrungen mit Happy End.

Gestaltungsaktualisierung privater Ansichten und Ordner stellt eine echte Herausforderung dar

9. Januar 2013 Posted by Manfred Meise

Als Domino Entwickler weiß man um die Vor- und Nachteile von z.B. von Ansichten und Ordnern "Gemeinsam, privat bei Erstbenutzung" und setzt diese nur sehr selektiv ein. Trotzdem habe ich mich bei einer unserer zentralen Domino Anwendungen entschieden, hiervon Gebrauch zu machen. Da die Anwendung ständig Funktionserweiterungen erfährt, kommt es immer wieder vor, dass auch die Ansichten und Ordner überarbeitet oder erweitert werden müssen. Somit stellt sich bei unseren Kunden, welche diese Anwendung einsetzen die Frage, wie die neue Gestaltung einer Folgeversion in die bereits vorhandenen Installationen kommt, nachdem wir eine neue Schablonenversion der Anwendung bereit stellen!

Hierzu haben wir im Verlauf der Zeit zahlreiche (vorwiegend negative) Erfahrungen sammeln dürfen, welche ich in der nachfolgenden Artikelreihe zusammengetragen habe.

Warum setzen Entwickler private Gestaltungselemente ein?
Leistungsmerkmale privater Ansichten und Ordner sind gelegentlich fachlich gefordert.


Alternativen zum Einsatz privater Gestaltungselemente
Zur Vermeidung der Nachteile privater Gestaltungselemente (u.A. mangelnde Aktualisierungsfähigkeit) bieten sich durchaus Alternativen an.


Speicherort der privaten Gestaltungselemente
Zunächst muss man sich klar werden, wo die Informationen der persönlichen Gestaltungselemente gespeichert werden: In der Datenbank oder im persönlichen Desktop. Man könnte denken "Egal" - doch weit gefehlt! Nicht nur das Roaming sondern auch das Client-Verhalten ist zu beobachten.


Erkennung/unterscheidung von neuen Versionen
Um die Gestaltung neuer Versionen der gemeinsamen Vorlage für Ansichten und Ordner von bereits vorhandenen privaten Kopien unterscheiden zu können, eignen sich leider nicht die üblichen Verfahren (neue Versionen mit neuem Zeitstempel).


Aktualisierung der Gestaltung
Anwendungslogik, welche im Kontext des Benutzers abläuft, entscheidet über die Notwendigkeit und führt die Aktualisierung der privaten Gestaltungselemente durch.


... um das Ergebnis vorwegzunehmen: Zahlreiche leidvolle Erfahrungen mit Happy End.

Programmatische Aktualisierung von privaten Gestaltungselementen

4. Januar 2013 Posted by Manfred Meise

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

Programmatische Aktualisierung von privaten Gestaltungselementen

4. Januar 2013 Posted by Manfred Meise

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

Programmatische Aktualisierung von privaten Gestaltungselementen

4. Januar 2013 Posted by Manfred Meise

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

Programmatische Aktualisierung von privaten Gestaltungselementen

4. Januar 2013 Posted by Manfred Meise

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

Wie kann ich programmatisch private Gestaltungselemente auf Aktualität prüfen?

28. Dezember 2012 Posted by Manfred Meise

Wir setzen eine Anwendung mit privaten Ansichten und Ordnern ein, die regelmäßig weiterentwickelt wird und produktive Datenbanken durch Schalonenaktualisierung anpasst. Hierbei werden die privaten Kopien der Ansichten und Ordner nicht automatisch aktualisiert. Bei der Konzeption einer "selbstgestrikten" Aktualisierungslogik stößt man schnell auf die Frage: "Wie kann ich erkennen, ob die private Kopie des Gestaltungselementes aktuell ist?"

Vergleich von Zeitstempeln


a) Einsatz von NotesView

Die Idee:
Man öffnet die Ansicht und hat Zeitstempel (Erstelldatum; letzte Änderung) des jeweiligen gemeinsamen Gestaltungselementes und der privaten Kopie.. Klingt gut, ist es aber nicht!

So erhält man mit
 
Dim view as NotesView
set view = db.getView ("Meine Ansicht")


jeweils die gemeinsame Ansichtsvorlage, wenn die private Kopie nicht existiert, jedoch die private Kopie des Ansicht, wenn diese exisiert. Somit kann man im Regelfall (wenn die private Kopie NICHT existiert) nicht auf die gemeinsame Vorlage zu Vergleichszwecken zugreifen.

Ergebnis:
Nicht prakttikabel !

b) Einsatz von NotesDatabase.Views

Die Idee:
Man arbeitet alle Ansichten (gemeinsame Vorlagen und private Kopien) einer Datenbank ab und muss die jeweiligen Exemplare (Vorlage  / Kopie) einander zuordnen, um sie zu vergleichen.. Das muß doch gehen!

So durchsucht folgendes Skript die Datenbank nach Ordnern mit dem AliasNamen "F2-DE" und listet jeweils die Universal-ID der Gestaltungselemente auf:
 
Sub
Initialize
 
 Dim s                         As New NotesSession
 Dim db                         As NotesDatabase
 Dim view                 As NotesView
 Dim vViewNames        As Variant
 
 Set db = s.Currentdatabase
 
 ForAll v In db.Views
         Set view = v
         vViewNames = view.Aliases
         If Not IsEmpty (vViewNames) then
                 If vViewNames(0) = "F2-DE" Then    
                         If Not IsEmpty (view.Readers) Then
                                 MessageBox |Private Kopie des Ordners "F2" gefunden: | & view.Universalid
                         Else
                                 MessageBox |Gemeinsame Vorlage des Ordner "F2" gefunden: | & view.Universalid
                         End If
                 End If
         End If
 End ForAll
End
Sub


Interessant und noch nicht vollständig erforscht: Dieses Skript findet sogar private Kopien von Ordnern (in Datenbank gespeichert), welche der Domino Designer nicht anzeigt! Nach anfänglicher Begeisterung über diesen Lösungsansatz, habe ich dieses Skript gegen eine große produktive Datenbank laufen lassen und musste feststellen, dass jeweils beim Zugriff auf ein Ansichtsobjekt die Ansichtsindizes aktualisiert werden, um nur auf unwesentliche Merkmale der Ansicht zuzugreifen. Ein echter Performance-Killer, wollte ich diese Logik in einem Datenbank-Script beim Öffnen der Datenbank einsetzen. In meinen Testfällen habe ich teilweise 15 Sekunden warten müssen, bevor ich mein Ergebnis hatte.

Ergebnis:
Zu langsam für den Produktionsbetrieb!

b) Einsatz von NotesNoteCollection>

Die Idee:
Man kann doch die Gestaltungselemente sammeln und auf diese als NotesDocument zugreifen!. So erhalte ich Informationen zum Gestaltungselement, ohne den Indexer zu triggern!

Schon häufig habe ich mit der NotesNoteCollection Klasse auf Gestaltungslemente (Ansichten, Felder, Agenten, Teilmasken) zugegriffen und hierfür u.A. auch eine Selektionsformel einsetzen können, nach Elementen mit speziellen Attributen zu suchen. So würde ich mit den Werten des "$Flags" Items auf bestimmte Ansichts-/Ordner-Typen zugreifen und mit Auswertung des "$Readers" Felders den Eigentümer einer privaten Kopie identifizieren können.

siehe dieses Codebeispiel ...

Beim Einsatz dieses Skriptes gegen eine große produktive Datenbank ist dieses schneller als das zuvor, jedoch immer noch zu langsam, da eine Datenbanksuche angestoßen wird.. Ein echter Performance-Killer, wollte ich diese Logik in einem Datenbank-Script beim Öffnen der Datenbank einsetzen.

Ergebnis:
Besser, doch noch zu langsam für den Produktionsbetrieb! Vorteil: Ich kann die Namen der Ansichten/Ordner ermitteln, die ich behandeln möchte.


Einsatz eines Namensschemas


Nach intensiven Tests habe ich alle oben beschriebenen Lösungsansätze verworfen und mich für die Variante entschieden (welche in diesem Beitrag nicht näher beschrieben ist):
  • Ich führe ein Namensschema (speziell für Ansichten, die lokal statt in der Datenbank gespeichert werden) ein und ändere die Namen der Gestaltungselemente, wenn ich diese aktualisiere
  • Ich akzeptiere, durch Einführung eines Versionskennzeichens für die gesamte Anwendung, dass ich ggf. Elementen aktualisiere, deren Gestaltung sich zur Vorversion nicht geändert haben

Ergebnis:
Sehr performant, da keinerlei Prüfungen

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