Posts Tagged: ‘Datenbankentwicklung’

Kein debugging von LotusScript Agent möglich

19. April 2015 Posted by Manfred Meise

Gelegentlich lässt sich z.B. ein LotusScript Agent nicht debuggen, da der debugger zwar startet, sich jedoch nicht bedienen lässt. Die Schaltfächen der Aktionen im Debugger sowie die Tastaturkürzel funktionieren einfach nicht. Hier ein Screenshot, welcher das Problem mit den Aktionen anschaulich darstellt.



Dieses kann mit einfach an folgendem Code nachempfunden werden.

Die Ursache liegt im Laufzeitfehler eines Initialize-Events einer Bibliothek:
 
'Test-Agent:

Option Public
Option Declare

Use "IncludeLib"

Sub Initialize
Call MySub
End Sub

'IncludeLib:

Option Public
Option Declare

Sub Initialize
Dim intCounter As Integer
intCounter = Cint ("")
End Sub

Sub MySub

End Sub



Wird dieser Code korrigiert (Konstante "1" statt ""),
 
intCounter = Cint ("1")

so lässt sich der Debugger wie gewohnt nutzen:

Kein debugging von LotusScript Agent möglich

19. April 2015 Posted by Manfred Meise

Gelegentlich lässt sich z.B. ein LotusScript Agent nicht debuggen, da der debugger zwar startet, sich jedoch nicht bedienen lässt. Die Schaltfächen der Aktionen im Debugger sowie die Tastaturkürzel funktionieren einfach nicht. Hier ein Screenshot, welcher das Problem mit den Aktionen anschaulich darstellt.



Dieses kann mit einfach an folgendem Code nachempfunden werden.

Die Ursache liegt im Laufzeitfehler eines Initialize-Events einer Bibliothek:
 
'Test-Agent:

Option Public
Option Declare

Use "IncludeLib"

Sub Initialize
Call MySub
End Sub

'IncludeLib:

Option Public
Option Declare

Sub Initialize
Dim intCounter As Integer
intCounter = Cint ("")
End Sub

Sub MySub

End Sub



Wird dieser Code korrigiert (Konstante "1" statt ""),
 
intCounter = Cint ("1")

so lässt sich der Debugger wie gewohnt nutzen:

Kein debugging von LotusScript Agent möglich

19. April 2015 Posted by Manfred Meise

Gelegentlich lässt sich z.B. ein LotusScript Agent nicht debuggen, da der debugger zwar startet, sich jedoch nicht bedienen lässt:



Dieses kann mit einfach an folgendem Code nachempfunden werden.

Die Ursache liegt im Laufzeitfehler eines Initialize-Events einer Bibliothek:
 
'Test-Agent:

Option Public
Option Declare

Use "IncludeLib"

Sub Initialize
Call MySub
End Sub

'IncludeLib:

Option Public
Option Declare

Sub Initialize
Dim intCounter As Integer
intCounter = Cint ("")
End Sub

Sub MySub

End Sub



Wird dieser Code korrigiert (Konstante "1" statt ""),
 
intCounter = Cint ("1")

so lässt sich der Debugger wie gewohnt nutzen:

Kein debugging von LotusScript Agent möglich

19. April 2015 Posted by Manfred Meise

Gelegentlich lässt sich z.B. ein LotusScript Agent nicht debuggen, da der debugger zwar startet, sich jedoch nicht bedienen lässt. Die Schaltfächen der Aktionen im Debugger sowie die Tastaturkürzel funktionieren einfach nicht. Hier ein Screenshot, welcher das Problem mit den Aktionen anschaulich darstellt.



Dieses kann mit einfach an folgendem Code nachempfunden werden.

Die Ursache liegt im Laufzeitfehler eines Initialize-Events einer Bibliothek:
 
'Test-Agent:

Option Public
Option Declare

Use "IncludeLib"

Sub Initialize
Call MySub
End Sub

'IncludeLib:

Option Public
Option Declare

Sub Initialize
Dim intCounter As Integer
intCounter = Cint ("")
End Sub

Sub MySub

End Sub



Wird dieser Code korrigiert (Konstante "1" statt ""),
 
intCounter = Cint ("1")

so lässt sich der Debugger wie gewohnt nutzen:

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

Datenbankrollen stets aktuell zum Code halten

2. April 2012 Posted by Manfred Meise

Datenbankentwickler können in Domino Datenbanken Rollen einsetzen, um bestimmte anwendungsspezifische Funktionen zu steuern. Leider kann es z.B. beim Kopieren von Schablonen oder Datenbanken geschehen, dass die ACL nicht mit kopiert wird und die Rollendefinitionen verloren gehen, Eine nachträgliche (erneute) Einrichtung der Rollen durch den Domino Administrator ist zwar möglich, setzt jedoch eine saubere Dokumentation der verwendeten Rollen voraus (unter Berücksichtigung der Groß-/Kleinschreibung der Rollennamen) damit die gewünschte Funktion gewährleistet ist.

Um diesem Problem aus dem Weg zu gehen, setze ich in Datenbanken mit Rollen stets das nachfolgende Datenbankskript ein (in etwas abgewandelter / detaillierter Form) ein, um durch Code des Anwendungsentwicklers (der wohl seine Rollennamen kennen sollte) die ACL in der Laufzeitumgebung zu analysieren und ggf. zu pflegen. Fehlen Rollendefinitionen (und sind gar überflüssige enthalten) und Ist der aktuelle Benutzer mit Manager Berechtigung ausgestattet, so pflegt dieses Skript direkt die ACL, ansonsten wird mindesten ein Hinweis ausgegeben.

Hat sich in der Praxis einfach bewährt !!!

 
'
' This Database Script insures up-to-date database Roles as required/assumed by the developer
'
' Note: Update constant in PostOpen to match your application
'
' Author: Manfred.Meise@mmi-consult.de (http://www.mmi-consult.de/faq)
'

Sub Postopen(Source As Notesuidatabase)
       
        Const strRequiredRoles = "[Configuration]:[EditAllDocs]:[TestRolle]"                'Required Roles in application
       
        Call VerifyRoles (Source.Database, Split(strRequiredRoles, ":"))
       
End Sub

Sub VerifyRoles (db As NotesDatabase, strRequireRoles As Variant)
       
        Dim vRolesCurrent        As Variant
        Dim vRolesMissing        As Variant
        Dim vRolesObsolete        As Variant
       
        Dim strErrorMsg         As String
       
        Const MB_ICONEXCLAMATION = 48
       
        '---------------------------------------------
        ' Specify and Verify Roles in ACL
        '---------------------------------------------
        If Ubound(strRequireRoles) >= 0 Then
                ' Get list of missing or obsolete roles
                vRolesCurrent        db.acl.Roles
                vRolesMissing         = Fulltrim(Arrayreplace (strRequireRoles, vRolesCurrent, ""))
                vRolesObsolete        Fulltrim(Arrayreplace (vRolesCurrent, strRequireRoles, ""))
               
                If (vRolesMissing(0) <> "") Or (vRolesObsolete(0) <> "") Then
                        'Prepare resulting message
                        If vRolesMissing(0) <> "" Then
                                strErrorMsg = "Fehlende ACL-Rollen in Datenbank:" & _
                                Chr(10) & Join (vRolesMissing, Chr(10)) & Chr(10)
                        End If                                        
                       
                        If (vRolesObsolete(0) <> "") Then
                                If strErrorMsg <> "" Then strErrorMsg = strErrorMsg & Chr(10)
                                strErrorMsg = "Überflüssige ACL-Rollen in Datenbank:" & _
                                Chr(10) & Join (vRolesObsolete, Chr(10))  & Chr(10)
                        End If
                       
                        'Roles are missing in ACL of this database
                        If db.CurrentAccessLevel = ACLLEVEL_MANAGER Then
                                'We can add missing roles
                                Call setRoles (db, Arrayunique(strRequireRoles))
                                Messagebox strErrorMsg & "ACL wurden automatisch angepasst", MB_ICONEXCLAMATION,""
                               
                        Else
                                'Notify administrator to add missing roles
                                Messagebox strErrorMsg & "Bitte den Systemadministrator benachrichtigen", MB_ICONEXCLAMATION,""
                               
                        End If
                End If
        End If                
       
End Sub


Sub SetRoles (db As NotesDatabase, roles As Variant)
       
        Dim acl                 As NotesACL
        Dim bNeedToSave         As Boolean
        Dim vCurrentRoles         As Variant
        Dim vTargetRoles         As Variant
       
        bNeedToSave         = False
       
        vTargetRoles         = Roles
        vCurrentRoles         = db.ACL.Roles
        If Not Isarray (vCurrentRoles) Then Redim vCurrentRoles(0)
       
        Set acl = db.ACL
       
                'Add missing roles
        Forall r In vTargetRoles
               
                If Isnull (Arraygetindex(vCurrentRoles, r)) Then
                        Call acl.AddRole (r)                                
                        bNeedToSave = True
                End If
               
        End Forall
       
                'Remove obsolete Roles
        Forall r In vCurrentRoles
                If Not r = "" Then                                        
                        If Isnull (Arraygetindex(vTargetRoles, r)) Then
                                Call acl.DeleteRole (r)                                
                                bNeedToSave = True
                        End If
                End If
        End Forall
       
        If bNeedToSave Then Call acl.Save
       
SingleExit:
        Exit Sub
       
End Sub

Datenbankrollen stets aktuell zum Code halten

2. April 2012 Posted by Manfred Meise

Datenbankentwickler können in Domino Datenbanken Rollen einsetzen, um bestimmte anwendungsspezifische Funktionen zu steuern. Leider kann es z.B. beim Kopieren von Schablonen oder Datenbanken geschehen, dass die ACL nicht mit kopiert wird und die Rollendefinitionen verloren gehen, Eine nachträgliche (erneute) Einrichtung der Rollen durch den Domino Administrator ist zwar möglich, setzt jedoch eine saubere Dokumentation der verwendeten Rollen voraus (unter Berücksichtigung der Groß-/Kleinschreibung der Rollennamen) damit die gewünschte Funktion gewährleistet ist.

Um diesem Problem aus dem Weg zu gehen, setze ich in Datenbanken mit Rollen stets das nachfolgende Datenbankskript ein (in etwas abgewandelter / detaillierter Form) ein, um durch Code des Anwendungsentwicklers (der wohl seine Rollennamen kennen sollte) die ACL in der Laufzeitumgebung zu analysieren und ggf. zu pflegen. Fehlen Rollendefinitionen (und sind gar überflüssige enthalten) und Ist der aktuelle Benutzer mit Manager Berechtigung ausgestattet, so pflegt dieses Skript direkt die ACL, ansonsten wird mindesten ein Hinweis ausgegeben.

Hat sich in der Praxis einfach bewährt !!!

 
'
' This Database Script insures up-to-date database Roles as required/assumed by the developer
'
' Note: Update constant in PostOpen to match your application
'
' Author: Manfred.Meise@mmi-consult.de (http://www.mmi-consult.de/faq)
'

Sub Postopen(Source As Notesuidatabase)
       
        Const strRequiredRoles = "[Configuration]:[EditAllDocs]:[TestRolle]"                'Required Roles in application
       
        Call VerifyRoles (Source.Database, Split(strRequiredRoles, ":"))
       
End Sub

Sub VerifyRoles (db As NotesDatabase, strRequireRoles As Variant)
       
        Dim vRolesCurrent        As Variant
        Dim vRolesMissing        As Variant
        Dim vRolesObsolete        As Variant
       
        Dim strErrorMsg         As String
       
        Const MB_ICONEXCLAMATION = 48
       
        '---------------------------------------------
        ' Specify and Verify Roles in ACL
        '---------------------------------------------
        If Ubound(strRequireRoles) >= 0 Then
                ' Get list of missing or obsolete roles
                vRolesCurrent        db.acl.Roles
                vRolesMissing         = Fulltrim(Arrayreplace (strRequireRoles, vRolesCurrent, ""))
                vRolesObsolete        Fulltrim(Arrayreplace (vRolesCurrent, strRequireRoles, ""))
               
                If (vRolesMissing(0) <> "") Or (vRolesObsolete(0) <> "") Then
                        'Prepare resulting message
                        If vRolesMissing(0) <> "" Then
                                strErrorMsg = "Fehlende ACL-Rollen in Datenbank:" & _
                                Chr(10) & Join (vRolesMissing, Chr(10)) & Chr(10)
                        End If                                        
                       
                        If (vRolesObsolete(0) <> "") Then
                                If strErrorMsg <> "" Then strErrorMsg = strErrorMsg & Chr(10)
                                strErrorMsg = "Überflüssige ACL-Rollen in Datenbank:" & _
                                Chr(10) & Join (vRolesObsolete, Chr(10))  & Chr(10)
                        End If
                       
                        'Roles are missing in ACL of this database
                        If db.CurrentAccessLevel = ACLLEVEL_MANAGER Then
                                'We can add missing roles
                                Call setRoles (db, Arrayunique(strRequireRoles))
                                Messagebox strErrorMsg & "ACL wurden automatisch angepasst", MB_ICONEXCLAMATION,""
                               
                        Else
                                'Notify administrator to add missing roles
                                Messagebox strErrorMsg & "Bitte den Systemadministrator benachrichtigen", MB_ICONEXCLAMATION,""
                               
                        End If
                End If
        End If                
       
End Sub


Sub SetRoles (db As NotesDatabase, roles As Variant)
       
        Dim acl                 As NotesACL
        Dim bNeedToSave         As Boolean
        Dim vCurrentRoles         As Variant
        Dim vTargetRoles         As Variant
       
        bNeedToSave         = False
       
        vTargetRoles         = Roles
        vCurrentRoles         = db.ACL.Roles
        If Not Isarray (vCurrentRoles) Then Redim vCurrentRoles(0)
       
        Set acl = db.ACL
       
                'Add missing roles
        Forall r In vTargetRoles
               
                If Isnull (Arraygetindex(vCurrentRoles, r)) Then
                        Call acl.AddRole (r)                                
                        bNeedToSave = True
                End If
               
        End Forall
       
                'Remove obsolete Roles
        Forall r In vCurrentRoles
                If Not r = "" Then                                        
                        If Isnull (Arraygetindex(vTargetRoles, r)) Then
                                Call acl.DeleteRole (r)                                
                                bNeedToSave = True
                        End If
                End If
        End Forall
       
        If bNeedToSave Then Call acl.Save
       
SingleExit:
        Exit Sub
       
End Sub

Datenbankrollen stets aktuell zum Code halten

2. April 2012 Posted by Manfred Meise

Datenbankentwickler knnen in Domino Datenbanken Rollen einsetzen, um bestimmte anwendungsspezifische Funktionen zu steuern. Leider kann es z.B. beim Kopieren von Schablonen oder Datenbanken geschehen, dass die ACL nicht mit kopiert wird und die Rollendefinitionen verloren gehen, Eine nachtrgliche (erneute) Einrichtung der Rollen durch den Domino Administrator ist zwar mglich, setzt jedoch eine saubere Dokumentation der verwendeten Rollen voraus (unter Bercksichtigung der Gro-/Kleinschreibung der Rollennamen) damit die gewnschte Funktion gewhrleistet ist.

Um diesem Problem aus dem Weg zu gehen, setze ich in Datenbanken mit Rollen stets das nachfolgende Datenbankskript ein (in etwas abgewandelter / detaillierter Form) ein, um durch Code des Anwendungsentwicklers (der wohl seine Rollennamen kennen sollte) die ACL in der Laufzeitumgebung zu analysieren und ggf. zu pflegen. Fehlen Rollendefinitionen (und sind gar berflssige enthalten) und Ist der aktuelle Benutzer mit Manager Berechtigung ausgestattet, so pflegt dieses Skript direkt die ACL, ansonsten wird mindesten ein Hinweis ausgegeben.

Hat sich in der Praxis einfach bewhrt !!!

 
'
' This Database Script insures up-to-date database Roles as required/assumed by the developer
'
' Note: Update constant in PostOpen to match your application
'
' Author: Manfred.Meise@mmi-consult.de (http://www.mmi-consult.de/faq)
'

Sub Postopen(Source As Notesuidatabase)
       
        Const strRequiredRoles = "[Configuration]:[EditAllDocs]:[TestRolle]"                'Required Roles in application
       
        Call VerifyRoles (Source.Database, Split(strRequiredRoles, ":"))
       
End Sub

Sub VerifyRoles (db As NotesDatabase, strRequireRoles As Variant)
       
        Dim vRolesCurrent        As Variant
        Dim vRolesMissing        As Variant
        Dim vRolesObsolete        As Variant
       
        Dim strErrorMsg         As String
       
        Const MB_ICONEXCLAMATION = 48
       
        '---------------------------------------------
        ' Specify and Verify Roles in ACL
        '---------------------------------------------
        If Ubound(strRequireRoles) >= 0 Then
                ' Get list of missing or obsolete roles
                vRolesCurrent        db.acl.Roles
                vRolesMissing         = Fulltrim(Arrayreplace (strRequireRoles, vRolesCurrent, ""))
                vRolesObsolete        Fulltrim(Arrayreplace (vRolesCurrent, strRequireRoles, ""))
               
                If (vRolesMissing(0) <> "") Or (vRolesObsolete(0) <> "") Then
                        'Prepare resulting message
                        If vRolesMissing(0) <> "" Then
                                strErrorMsg = "Fehlende ACL-Rollen in Datenbank:" & _
                                Chr(10) & Join (vRolesMissing, Chr(10)) & Chr(10)
                        End If                                        
                       
                        If (vRolesObsolete(0) <> "") Then
                                If strErrorMsg <> "" Then strErrorMsg = strErrorMsg & Chr(10)
                                strErrorMsg = "berflssige ACL-Rollen in Datenbank:" & _
                                Chr(10) & Join (vRolesObsolete, Chr(10))  & Chr(10)
                        End If
                       
                        'Roles are missing in ACL of this database
                        If db.CurrentAccessLevel = ACLLEVEL_MANAGER Then
                                'We can add missing roles
                                Call setRoles (db, Arrayunique(strRequireRoles))
                                Messagebox strErrorMsg & "ACL wurden automatisch angepasst", MB_ICONEXCLAMATION,""
                               
                        Else
                                'Notify administrator to add missing roles
                                Messagebox strErrorMsg & "Bitte den Systemadministrator benachrichtigen", MB_ICONEXCLAMATION,""
                               
                        End If
                End If
        End If                
       
End Sub


Sub SetRoles (db As NotesDatabase, roles As Variant)
       
        Dim acl                 As NotesACL
        Dim bNeedToSave         As Boolean
        Dim vCurrentRoles         As Variant
        Dim vTargetRoles         As Variant
       
        bNeedToSave         = False
       
        vTargetRoles         = Roles
        vCurrentRoles         = db.ACL.Roles
        If Not Isarray (vCurrentRoles) Then Redim vCurrentRoles(0)
       
        Set acl = db.ACL
       
                'Add missing roles
        Forall r In vTargetRoles
               
                If Isnull (Arraygetindex(vCurrentRoles, r)) Then
                        Call acl.AddRole (r)                                
                        bNeedToSave = True
                End If
               
        End Forall
       
                'Remove obsolete Roles
        Forall r In vCurrentRoles
                If Not r = "" Then                                        
                        If Isnull (Arraygetindex(vTargetRoles, r)) Then
                                Call acl.DeleteRole (r)                                
                                bNeedToSave = True
                        End If
                End If
        End Forall
       
        If bNeedToSave Then Call acl.Save
       
SingleExit:
        Exit Sub
       
End Sub

Datenbankrollen stets aktuell zum Code halten

2. April 2012 Posted by Manfred Meise

Datenbankentwickler können in Domino Datenbanken Rollen einsetzen, um bestimmte anwendungsspezifische Funktionen zu steuern. Leider kann es z.B. beim Kopieren von Schablonen oder Datenbanken geschehen, dass die ACL nicht mit kopiert wird und die Rollendefinitionen verloren gehen, Eine nachträgliche (erneute) Einrichtung der Rollen durch den Domino Administrator ist zwar möglich, setzt jedoch eine saubere Dokumentation der verwendeten Rollen voraus (unter Berücksichtigung der Groß-/Kleinschreibung der Rollennamen) damit die gewünschte Funktion gewährleistet ist.

Um diesem Problem aus dem Weg zu gehen, setze ich in Datenbanken mit Rollen stets das nachfolgende Datenbankskript ein (in etwas abgewandelter / detaillierter Form) ein, um durch Code des Anwendungsentwicklers (der wohl seine Rollennamen kennen sollte) die ACL in der Laufzeitumgebung zu analysieren und ggf. zu pflegen. Fehlen Rollendefinitionen (und sind gar ĂĽberflĂĽssige enthalten) und Ist der aktuelle Benutzer mit Manager Berechtigung ausgestattet, so pflegt dieses Skript direkt die ACL, ansonsten wird mindesten ein Hinweis ausgegeben.

Hat sich in der Praxis einfach bewährt !!!

 
'
' This Database Script insures up-to-date database Roles as required/assumed by the developer
'
' Note: Update constant in PostOpen to match your application
'
' Author: Manfred.Meise@mmi-consult.de (http://www.mmi-consult.de/faq)
'

Sub Postopen(Source As Notesuidatabase)
       
        Const strRequiredRoles = "[Configuration]:[EditAllDocs]:[TestRolle]"                'Required Roles in application
       
        Call VerifyRoles (Source.Database, Split(strRequiredRoles, ":"))
       
End Sub

Sub VerifyRoles (db As NotesDatabase, strRequireRoles As Variant)
       
        Dim vRolesCurrent        As Variant
        Dim vRolesMissing        As Variant
        Dim vRolesObsolete        As Variant
       
        Dim strErrorMsg         As String
       
        Const MB_ICONEXCLAMATION = 48
       
        '---------------------------------------------
        ' Specify and Verify Roles in ACL
        '---------------------------------------------
        If Ubound(strRequireRoles) >= 0 Then
                ' Get list of missing or obsolete roles
                vRolesCurrent        db.acl.Roles
                vRolesMissing         = Fulltrim(Arrayreplace (strRequireRoles, vRolesCurrent, ""))
                vRolesObsolete        Fulltrim(Arrayreplace (vRolesCurrent, strRequireRoles, ""))
               
                If (vRolesMissing(0) <> "") Or (vRolesObsolete(0) <> "") Then
                        'Prepare resulting message
                        If vRolesMissing(0) <> "" Then
                                strErrorMsg = "Fehlende ACL-Rollen in Datenbank:" & _
                                Chr(10) & Join (vRolesMissing, Chr(10)) & Chr(10)
                        End If                                        
                       
                        If (vRolesObsolete(0) <> "") Then
                                If strErrorMsg <> "" Then strErrorMsg = strErrorMsg & Chr(10)
                                strErrorMsg = "ĂśberflĂĽssige ACL-Rollen in Datenbank:" & _
                                Chr(10) & Join (vRolesObsolete, Chr(10))  & Chr(10)
                        End If
                       
                        'Roles are missing in ACL of this database
                        If db.CurrentAccessLevel = ACLLEVEL_MANAGER Then
                                'We can add missing roles
                                Call setRoles (db, Arrayunique(strRequireRoles))
                                Messagebox strErrorMsg & "ACL wurden automatisch angepasst", MB_ICONEXCLAMATION,""
                               
                        Else
                                'Notify administrator to add missing roles
                                Messagebox strErrorMsg & "Bitte den Systemadministrator benachrichtigen", MB_ICONEXCLAMATION,""
                               
                        End If
                End If
        End If                
       
End Sub


Sub SetRoles (db As NotesDatabase, roles As Variant)
       
        Dim acl                 As NotesACL
        Dim bNeedToSave         As Boolean
        Dim vCurrentRoles         As Variant
        Dim vTargetRoles         As Variant
       
        bNeedToSave         = False
       
        vTargetRoles         = Roles
        vCurrentRoles         = db.ACL.Roles
        If Not Isarray (vCurrentRoles) Then Redim vCurrentRoles(0)
       
        Set acl = db.ACL
       
                'Add missing roles
        Forall r In vTargetRoles
               
                If Isnull (Arraygetindex(vCurrentRoles, r)) Then
                        Call acl.AddRole (r)                                
                        bNeedToSave = True
                End If
               
        End Forall
       
                'Remove obsolete Roles
        Forall r In vCurrentRoles
                If Not r = "" Then                                        
                        If Isnull (Arraygetindex(vTargetRoles, r)) Then
                                Call acl.DeleteRole (r)                                
                                bNeedToSave = True
                        End If
                End If
        End Forall
       
        If bNeedToSave Then Call acl.Save
       
SingleExit:
        Exit Sub
       
End Sub

Beliebige Applikationen adressbuchkompatibel machen

11. Mai 2007 Posted by Michael Siegrist

IBM Lotus Notes bietet die Mglichkeit, jede beliebige Datenbank als Verzeichniss im Adressdialog z.B. im Mailfile mittels "names=" Eintrag in der notes.ini bzw. Directory Assistance, oder programmiertechnisch mit der Formel @Command([MailAddress]),  zu verwenden.  

Damit die zu verwendete Datenbank auch im Dialog @Command([MailAddress])  Daten zur Verfgung stellen kann, mssen die Ansichten
  • ($PeopleGroupsFlat)
  • ($PeopleGroupsHier)

in die Applikation kopiert werden.
Danch mssen einfach noch die SELECT und Spaltenformeln angepasst werden.

ACHTUNG:
ausserhalb des dargestellten Bildschirms haben die Ansichten entsprechend anzupassenden Spalten !!

Design Synopsis via DXL als HTML ausgeben

26. Januar 2007 Posted by Manfred Meise

Seit Domino Designer 6 werden zustzliche DXL Werkzeuge angeboten, mit denen man z.B. XML exportieren, ansehen und auch transformieren kann. Hierzu werden u.a. entsprechende XSL mit installiert, um die Gestaltungselemente einer Datenbank als HTML auszugeben (wie ich finde, bersichtlicher als mit der Standard Gestaltungsbersicht).

Diese Werkzeuge knnen ber die Menfolge "Werkzeuge" --> "DXL-Hilfprogramme" --> "Transformer" gestartet werden.

Doch was, wenn dieser Menpunkt (oder auch "Werkzeuge" --> "DXL-Hilfprogramme" --> "Betrachter") fehlt???

Die Werkzeuge werden nur angeboten, wenn die aktuelle Arbeitsumgebung des Clients auf dem Reiter "Internet-Browser" auf "Internet Explorer" oder "Notes mit Internet Explorer" gesetzt worden ist.