Das Notes Forum
Domino 9 und frühere Versionen => ND7: Entwicklung => Thema gestartet von: Schorschi353 am 29.07.10 - 12:03:09
-
Hallo liebe Notes-Gemeinde,
ich habe in einer Datenbank einen Agent, der Berechtigungen einträgt.
In der Datenbank gibt es Berichtsdokumente und Zugriffsdokumente. In den Zugriffsdokumenten ist geregelt, welche Person auf welche Berichtsdokumente Zugriff hat, z.B. aufgrund einer bestimmten Kategorie. D.h. pro Person gibt es ein Zugriffsdokument, dort steht drin, auf welche Kategorie der Benutzer Zugriff hat.
Der Agent löscht zunächst die Autorenfelder (damit keine Personen Zugriff haben, von denen kein Zugriffsdokument mehr existiert), holt sich dann jedes Zugriffsdokument, prüft in welchen Berichtsdokumenten die im Zugriffsdokument eingetragenen Kategorien sind und trägt in die Berichtsdokumente, wo dies der Fall ist, den Namen der Person ein.
Der Agent läuft, nachdem Dokumente erstellt oder geändert wurden.
Momentan sind in der Datenbank ca 840 Berichtsdokumente und 90 Zugriffsdokumente.
Jede Person hat auf ihr Zugriffsdokument Leseberechtigung.
Das Problem ist, dass der Agent 20 Minuten braucht, um zu laufen. Auf dem Server ist allerdings eingestellt, dass Agents tagsüber nur 5, nachts 10 Minuten laufen dürfen, der Agent läuft also seit einiger zeit auf einen Fehler.
Gibt es eine Möglichkeit, die Laufzeit des Agents zu verkürzen? Hat jemand eine Idee?
Wenn ein Berichtsdokument erstellt, oder geändert wird, müsste der Agent ja nur die Autorenfelder dieses Dokuments anpassen. Nur wenn ein neues Zugriffsdokument erstellt/geändert wird, bzw. wenn ein Zugriffsdokument gelöscht wird, würde dies mehrere Berichtsdokumente betreffen.
Danke schonmal für Eure Anregungen/Ideen!!
Gruß, Marius
-
Hallo,
Ohne den Aufbau des Agenten zu kennen, wird es sehr schwer werden, irgendwelche Punkte zu finden, wie man die Laufzeit verbssern kann.
Noch eine Frage am Rande.
Traegst Du die Zugriffe nicht gleich beim Erstellen/Aendern des Dokumentes (Berichtsdokument) ein?
Andreas
-
Hallo Andreas,
anbei der Agent.
Die Berechtigungen gleich beim Erstellen/Ändern des Dokumentes einzutragen wird wohl insofern nicht gehen, weil die Personen jeweils nur auf ihre Zugriffsdokumente Lesezugriff haben (dürfen).
Agent:
Sub Initialize
Set session = New notessession
Set db = session.CurrentDatabase
Dim docChanged As Boolean
Set berichtsview = db.GetView("Lookup\alleBerichteNoteID")
Set accessview = db.GetView("Lookup\useraccess_Autoren")
If Not (berichtsview Is Nothing) Then
Set berichtdoc = berichtsview.GetFirstDocument
Call berichtdoc.ReplaceItemValue("Autoren", "")
Call berichtdoc.save(True,False,True)
Set berichtdoc = berichtsview.GetNextDocument(berichtdoc)
End If
If Not (berichtsview Is Nothing) Then
Set berichtdoc = berichtsview.GetFirstDocument
While Not (berichtdoc Is Nothing)
Set accessdoc = accessview.GetFirstDocument
While Not accessdoc Is Nothing
docChanged = False
Set holding = accessdoc.GetFirstItem( "MBSHolding_Jahr" )
Set auswahl = accessdoc.GetFirstItem( "auswahl" )
Set gesellschaft = accessdoc.GetFirstItem( "gesellschaft" )
Set bu = accessdoc.GetFirstItem( "bu" )
Set projekte = accessdoc.GetFirstItem( "projekte" )
Set ebene_gesellschaft = accessdoc.GetFirstItem( "ebene_gesellschaft" )
Set ebene_bu = accessdoc.GetFirstItem( "ebene_bu" )
Set ebene_materials = accessdoc.GetFirstItem( "ebene_materials" )
Set username = accessdoc.GetFirstItem( "User" )
Forall v In berichtdoc.Autoren
If username.contains(v) Then
'Msgbox "User bereits im Bericht vorhanden!"
If gesellschaft.contains(berichtdoc.ebene_2(0)) And ebene_gesellschaft.contains(berichtdoc.ebene_3(0) + "\" + berichtdoc.ebene_4(0)) Then
'Msgbox "User im Bericht enthalten und Bedingung 1 erfüllt!"
Exit Forall
Elseif bu.contains(berichtdoc.ebene_2(0)) And ebene_bu.contains(berichtdoc.ebene_3(0) + "\" + berichtdoc.ebene_4(0)) Then
'Msgbox "User im Bericht enthalten und Bedingung 2 erfüllt!"
Exit Forall
Elseif projekte.contains(berichtdoc.ebene_2(0)) And projekte.contains(berichtdoc.ebene_4(0)) Then
'Msgbox "User im Bericht enthalten und Bedingung 3 erfüllt!"
Exit Forall
Elseif auswahl.contains(berichtdoc.ebene_2(0)) And auswahl.contains(berichtdoc.ebene_4(0)) Then
'Msgbox "User im Bericht enthalten und Bedingung 4 erfüllt!"
Exit Forall
Elseif holding.contains(berichtdoc.ebene_2(0)) And holding.contains(berichtdoc.ebene_4(0)) Then
'Msgbox "User im Bericht enthalten und Bedingung 5 erfüllt!"
Exit Forall
Elseif auswahl.contains(berichtdoc.ebene_1(0)) And ebene_materials.contains(berichtdoc.ebene_4(0)) Then
'Msgbox "User im Bericht enthalten und Bedingung 6 erfüllt!"
Exit Forall
Else
var1 = berichtdoc.Autoren(0)
var2 = accessdoc.User(0)
var3 = ""
var4 = Replace(var1, var2, var3)
Set itm = berichtdoc.ReplaceItemValue("Autoren", var2)
Call berichtdoc.ComputeWithForm(False, False)
docChanged = True
Exit Forall
End If
Elseif Not username.contains(v) Then
If gesellschaft.contains(berichtdoc.ebene_2(0)) And ebene_gesellschaft.contains(berichtdoc.ebene_3(0) + "\" + berichtdoc.ebene_4(0)) Then
Set itm = berichtdoc.GetFirstItem( "Autoren")
Call itm.appendtotextlist(accessdoc.User(0))
Call berichtdoc.ComputeWithForm(False, False)
docChanged = True
Exit Forall
Elseif bu.contains(berichtdoc.ebene_2(0)) And ebene_bu.contains(berichtdoc.ebene_3(0) + "\" + berichtdoc.ebene_4(0)) Then
Set itm = berichtdoc.GetFirstItem( "Autoren")
Call itm.appendtotextlist(accessdoc.User(0))
Call berichtdoc.ComputeWithForm(False, False)
docChanged = True
Exit Forall
Elseif projekte.contains(berichtdoc.ebene_2(0)) And projekte.contains(berichtdoc.ebene_4(0)) Then
Set itm = berichtdoc.GetFirstItem( "Autoren")
Call itm.appendtotextlist(accessdoc.User(0))
Call berichtdoc.ComputeWithForm(False, False)
docChanged = True
Exit Forall
Elseif auswahl.contains(berichtdoc.ebene_2(0)) And auswahl.contains(berichtdoc.ebene_4(0)) Then
Set itm = berichtdoc.GetFirstItem( "Autoren")
Call itm.appendtotextlist(accessdoc.User(0))
Call berichtdoc.ComputeWithForm(False, False)
docChanged = True
Exit Forall
Elseif auswahl.contains(berichtdoc.ebene_1(0)) And ebene_materials.contains(berichtdoc.ebene_4(0)) Then
Set itm = berichtdoc.GetFirstItem( "Autoren")
Call itm.appendtotextlist(accessdoc.User(0))
Call berichtdoc.ComputeWithForm(False, False)
docChanged = True
Exit Forall
Elseif holding.contains(berichtdoc.ebene_2(0)) And holding.contains(berichtdoc.ebene_4(0)) Then
Set itm = berichtdoc.GetFirstItem( "Autoren")
Call itm.appendtotextlist(accessdoc.User(0))
Call berichtdoc.ComputeWithForm(False, False)
docChanged = True
Exit Forall
End If
End If
End Forall
If docChanged Then Call berichtdoc.save(True,False,True)
Set accessdoc = accessview.GetNextDocument(accessdoc)
Wend
Set berichtdoc = berichtsview.GetNextDocument(berichtdoc)
Wend
End If
End Sub
Gruß, Marius
-
Wenn ein Berichtsdokument erstellt, oder geändert wird, müsste der Agent ja nur die Autorenfelder dieses Dokuments anpassen. Nur wenn ein neues Zugriffsdokument erstellt/geändert wird, bzw. wenn ein Zugriffsdokument gelöscht wird, würde dies mehrere Berichtsdokumente betreffen.
Du hast die Lösung doch schon selber benannt.
Wobei ich das nach deiner Beschreibung so machen würde, daß beim Erstellen des Dokumentes die Berechtigungen gesetzt werden und anschließend nur verändert werden, wenn im Zugriffsdokument etwas passiert.
Damit sparst Du dir den Aufwand, bei jeder Dokumentenänderung die Rechte zu prüfen und ggf. nachzuziehen.
Und der Agent, der über die Zugriffsdokumente läuft, kann ja ggf. auch nachts laufen und dann nur die Zugriffsdokumente holen, die seit dem letzten Lauf verändert wurden.
-
Wobei ich das nach deiner Beschreibung so machen würde, daß beim Erstellen des Dokumentes die Berechtigungen gesetzt werden und anschließend nur verändert werden, wenn im Zugriffsdokument etwas passiert.
Hallo Ingo,
danke das hört sich gut an, nur hat ja jeder nur Zugriff auf sein eigenes Zugriffsdokument und nicht auf die anderen Zugriffsdokumente. Also kann ich doch die Berechtigungen nicht beim Speichern des Dokuments eintragen, weil der jeweilige User nur sein Zugriffsdokument sieht, oder?!
-
Das habe ich jetzt nicht ganz verstanden. Die Zugriffsdokumente sind auch per Leserfeld "gesperrt" ? Und der User kann theoretisch ein Berichtsdokument erzeugen und eine Kategorie auswählen, in der er selber dann nicht eingetragen ist, d.h. er sieht das Dokument nach dem Speichern dann auch nicht mehr ?
Wenn das der Fall ist, kannst Du den Agenten immer noch via RunOnBehalfOf (letzter Tab Agenten-Eigenschaften, "Ausführen im Namen von") z.B. mit Server-ID ausführen lassen. Der Agent läuft dann mit den Rechten des angegebenen Benutzers/Servers und käme dann auch an die für den Anwender selber nicht sichtbaren Dokumente heran.
-
Genau, die Zugriffsdokumente sind per Leserfelder 'gesperrt'. Der User kann natürlich nur Berichte in den Kategorien anlegen, die er auch sieht. Das habe ich berücksichtigt. :)
OK, den Agenten im Namen einer anderen Person zum Laufen zu bringen klingt super. Nur wie mache ich das? Wie sage ich dem Agent dass er nur DAS Dokument ändern soll?
Momentan läuft der Agent ja periodisch über alle Dokumente einer Ansicht.
Danke!
-
Wenn der Benutzer nur "seine" Kategorien auswählen kann, dann brauchst Du das an der Stelle doch gar nicht. Oder sehen die User die Zugriffsdokumente generell nicht ?
Schau Dir mal in der Designer-Hilfe RunOnServer und die Eigenschaft ParameterDocID vom Objekt NotesAgent an. Damit kannst Du beim Aufruf eines Agenten die ID des Dokumentes übergeben und diese dann im Agenten ermitteln und das Dokument über die ID "holen".
Der Agent dürfte dann natürlich nicht periodisch laufen, sondern müßte beim Speichern/Schließen des Berichtsdokumentes gestartet werden.
-
Danke für Deine Hilfe, Ingo!
Das klingt ja prima!
Werde das sofort testen, wenn ich in einer Woche aus meinem wohlverdienten Urlaub wiederkomme! ;D
Danke!
-
Oder Lookups in die Autorenfelder (in einem berechneten Feld) und dann muss der Agent immer nur das Dok öffnen und mit ComputeWithForm speichern. Dann werden alle Feldformeln ausgeführt.
Die Lookups sollten dann natürlich auf (versteckte) Ansichten schauen, die die Zugriffsdoks schon entsprechend aufbereitet beinhalten.
Sollte auch funktionieren.
Matthias