Domino 9 und frühere Versionen > ND7: Entwicklung

per runonserver gestartetem Agenten mitteilen, von wo er gestartet wurde

(1/2) > >>

Demian:
Moin,moin,

ich habe diverse Konstellationen, bei denen Änderungen von einer DB an die nächste übertragen werden sollen. Ich arbeite hier im Prinzip mit 2  vorsichtig ausgedrückt "Replizierungs"Agenten. Einem in der DB in der geändert wird und einer in der DB wo die Änderungen hin müssen. Ich starte aus der QuellDB den Agenten in der Ziel-DB per runonserver und übergebe die Note-ID meines temporär erstellten Docs mit den Änderungen und verarbeite diese in der Ziel-DB.

Eigentlich klappt das wunderbar. Aber auf diese Weise bräuchte ich für jede Art Änderung einen eigenen Agenten in jeder Ziel-DB. Das würde ich gerne auf einen Agenten beschränken. Allerdings bin ich mir jetzt nicht so schlüssig, wie ich dem Agenten mitteile in welcher DB er mir ParameterDocID suchen soll?

Hat da jemand nen Denkanstoß?

Demian:
PS: ich hatte schon überlegt das temporäre Dokument mit den Änderungen direkt in der Ziel-DB zu erstellen (wird in einer ScriptLib erstellt), nur hat der User der ändert, ggf. ja nicht das Recht dazu Dokumente in der Ziel-DB zu erstellen.  :-:

Außerdem müsste ich dann bei mehreren Ziel-DB's auch für jede DB ein Änderungsdokument erstellen.

koehlerbv:
Hallo Demian,

das ist eine Architekturfrage - hierzu müsste man viel mehr über die Details der Datenbanken wissen.
Was mich aber jetzt schon stört: Das temporäre Dokumente angelegt werden (die dann sicherlich wieder gelöscht werden?).
Vorschläge hätte ich eine Menge (u.a. könnte man in Betracht ziehen, dass DB 1 die erforderlichen Änderungen in DB 2 per Mail an diese schickt). Ich hätte auch Vorschläge, wie man das Erstellen von Dokumenten, die man dann eh nur wieder löschen muss, verhindern könnte. Aber dazu erfordert es einfach mehr Details zu Deiner Konstellation.

Bernhard

Demian:
Moin,moin,

also im Prinzip ist es ganz einfach. Nehmen wir als Beispiel mal Mitgliederverwaltung, eine Kundenverwaltung sowie eine Werkzeugverwaltung in der Werkzeuge an Mitglieder oder Kunden ausgegeben werden.

Beim Verleih eines Werkzeugs wird ein Mitglied oder Kunde ausgewählt und der Name wird im Werkzeug gespeichert, bis dieses zum Beispiel über eine Aktion freigegeben wird. Wenn das Mitglied oder Kunde aber beispielsweise heiratet und sich der Name ändert, muss diese Änderung an die Werkzeugverwaltung weitergegeben werden, damit der Name bei verliehenen Werkzeugen geändert wird.

Die Person die den Namen des Mitglieds ändert hat aber unter Umständen gar keinen Zugriff auf die Werkzeugverwaltung. Also läuft das über 2 Serverbasierte Agenten.

In der Maske Mitglied überprüfe ich Änderungen indem ich mir im Postopen die Feldwerte wegspeicher und im Querysave ebenfalls. Im Postsave vergleiche ich dann meine Variablen mit den alten und neuen Werten. Wenn dann Änderungen aufgetreten sind, speichere ich die alten und die neuen Feldwerte in einem neuen Dokument, starte den Agenten in der Mitgliederverwaltung und übergebe die Note-ID. Dieser Agent ruft wiederum in der Datenbank Werkzeugverwaltung einen Agenten auf und übergibt diesem ebenfalls die Note-ID.

In diesem Agent wird das tempDoc in der Mitgliederverwaltung über die ID geholt alle relevanten Dokumente (verliehene Werkzeuge) auf die alten Werte überprüft und bei Übereinstimmung mit den neuen Wertden aus dem tempDoc überschrieben. Danach wird das tempDoc in der Mitgliederverwaltung gelöscht.

Zu allem Übel kommt vielleicht noch hinzu, dass die Werkzeuge vielleicht noch verschiedenen Abteilungen zugeordnet sind, die aber auch in einer separaten DB gepflegt werden. So dass Abteilungsänderungen ebenfalls an die Werkzeuge weitergegeben werden müssen. Der Agent in der Werkzeugverwaltung muss ja wissen, ob er jetzt das tempDoc in der Mitgliederverwaltung, in der Kundenverwaltung oder in der Abteilungsverwaltung suchen soll.


Hier mal Teile des ursprünglichen Agenten in der DB in der eine Änderung erfolgt (der Code bezieht sich jetzt auf andere DB's hoffe das verwirrt nicht zu sehr):


--- Code: ---Sub Initialize
'*********************************************************************************************************************************
'This agent will allocate changes on any document which data are used in other databases.
'*********************************************************************************************************************************
On Error Goto ErrHandle
'*********************************************************************************************************************************
Dim strMod_Form As String 'to get form of changed doc
'*********************************************************************************************************************************
Set s = New NotesSession
Set db = s.CurrentDatabase
Set AgentThis = s.CurrentAgent

'get tmp doc to continue logging with real user name
If General_GetModificationDoc = False Then
Call CreateLogEntry(db.title,s.CommonUserName,"Agent: AllocateChanges","Initialize",_
"General_GetModificationDoc = false - beende Agenten")
Exit Sub
End If

'get form of changed doc
strMod_Form = Cstr(docMod.ChangedForm(0))

Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","Initialize",_
"Starte Verteilung für Maske: " & strMod_Form)

'start allocating for the changed doc
If strMod_Form = "Zone" Then
Call Zone_Allocate
Elseif strMod_Form = "City" Then
Call City_Allocate()
Elseif strMod_Form = "TransportSystem" Then
Call TransportSystem_Allocate()
Elseif strMod_Form = "CostObject" Then
Call CostObject_Allocate()
Else
Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","Initialize",_
"Verteilung kann nicht gestartet werden, da für Maske: " & strMod_Form & " keine Verteilung festgelegt wurde")
Exit Sub
End If

Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","Initialize",_
"Verteilung für Maske: " & strMod_Form & " beendet")

Leave:
Exit Sub

ErrHandle:
Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","Initialize",_
"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
Resume Leave
End Sub


Function General_GetModificationDoc As Boolean
'*********************************************************************************************************************************
'get the temporary doc. Save the form of changed doc global and continue logging with the name of the user, which have
'edited created the tmp doc. invoked from Initialize of this agent.
'*********************************************************************************************************************************
'used libraries: logging
'used functions: CreateLogEntry(DBName As String, User As String, DesignElement As String, InvokingEvent As String, _
' Text As String)as Boolean
'*********************************************************************************************************************************
On Error Goto ErrHandle
'*********************************************************************************************************************************

Set docMod = db.GetDocumentByID(AgentThis.ParameterDocID)

If docMod Is Nothing Then
'log with the name of the server on which this agent run
Call CreateLogEntry(db.title,s.CommonUserName,"Agent: AllocateChanges","General_GetModificationDoc",_
"Das temporäre Änderungsdokument konnte nicht gefunden werden")
'RETURN
General_GetModificationDoc = False
Else
'get username for logging
strMod_User = Cstr(docMod.EditingUser(0))

'log with the name of the user, which have edited the zone
Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","General_GetModificationDoc",_
"Agent: " & AgentThis.Name & " wurde gestartet")
End If

'RETURN
General_GetModificationDoc = True

Leave:
Exit Function

ErrHandle:
Call CreateLogEntry(db.title,s.CommonUserName,"Agent: AllocateChanges","General_GetModificationDoc",_
"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
'RETURN
General_GetModificationDoc = False
Resume Leave
End Function



Sub City_Allocate
'*********************************************************************************************************************************
'allocate changes on a city to any database which use city datain this database.
'*********************************************************************************************************************************
On Error Goto ErrHandle
Dim SourceDocDB As NotesDatabase
Dim strMod_CityOLD As String 'old City value of the changed City
'*********************************************************************************************************************************
Set SourceDocDB = s.CurrentDatabase
strMod_CityOLD = Cstr(docMod.CityOLD(0))

Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","City_Allocate",_
"City_Allocate wird für Ort: " & strMod_CityOLD & " durchgeführt")

'refresh in all db's where zone data is used
Call City_RefreshThisDB(SourceDocDB, strMod_CityOLD)
Call City_RefreshCarDB()

Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","City_Allocate",_
"City_Allocate wird für Ort: " & strMod_CityOLD & " beendet")

Leave:
Exit Sub

ErrHandle:
Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","City_Allocate",_
"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
Resume Leave
End Sub



Sub City_RefreshCarDB()
'*********************************************************************************************************************************
'allocate changes on a CostObject to any database which work with the CostObject values
'*********************************************************************************************************************************
On Error Goto ErrHandle
'*********************************************************************************************************************************
Dim agent As NotesAgent 'agent in CarDB to edit reservations
'*********************************************************************************************************************************
Set RefreshDB = s.GetDatabase("Baghira","Abteilungen\public\Firmenfahrzeugverwaltung.nsf")

Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","CostObject_RefreshCarDB",_
"starte Agent ReservationsEdit in db: " & RefreshDB.Title)

Set agent = RefreshDB.GetAgent("ReservationsEdit")
Call agent.RunOnServer(docMod.NoteID)

Leave:
Exit Sub

ErrHandle:
Call CreateLogEntry(db.title,strMod_User,"Agent: AllocateChanges","CostObject_RefreshCarDB",_
"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
Resume Leave
End Sub


--- Ende Code ---



und hier Teile des Agents in der DB in der Änderungen erfolgen müssen




--- Code: ---Sub Initialize
'*********************************************************************************************************************************
'This agent edit the reservations if an cost object or a city  in db "Kostenträgerverwaltung" was changed.
'*********************************************************************************************************************************
On Error Goto ErrHandle
'*********************************************************************************************************************************
Set s = New NotesSession
Set db = s.CurrentDatabase

'get tmp doc to continue logging with real user name
If General_GetModificationDoc = False Then
Call CreateLogEntry(db.title,s.CommonUserName,"Agent: AllocateChanges","Initialize",_
"General_GetModificationDoc = false - beende Agenten")
Exit Sub
End If

'verify form of changed doc
strForm = Cstr(docMod.ChangedForm(0))
'get ID
strCostObject = Cstr(docMod.ID(0))

'start allocating for the changed doc
If strForm = "CostObject" Then
Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","Initialize",_
"geänderte Maske: " & strForm)

Call CostObject_EditAll

Elseif strForm = "City" Then
Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","Initialize",_
"geänderte Maske: " & strForm)

Call City_EditAll()

Else
Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","Initialize",_
"geänderte Maske nicht gültig - Maske: " & strForm)
End If

Leave:
Exit Sub

ErrHandle:
Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","Initialize",_
"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
Resume Leave
End Sub



Function General_GetModificationDoc As Boolean
'*********************************************************************************************************************************
'get the temporary doc in  db . Save the form of changed doc global and continue logging with the name of the user, which have
'created the tmp doc.
'*********************************************************************************************************************************
On Error Goto ErrHandle
'*********************************************************************************************************************************
'get tmpModification doc
Set agent = s.CurrentAgent
Set SourceDocDB = s.GetDatabase("Baghira","Zeiterfassung\Kostenträgerverwaltung.nsf")
Set docMod = SourceDocDB.GetDocumentByID(agent.ParameterDocID)

If docMod Is Nothing Then
'log with the name of the server on which this agent run
Call CreateLogEntry(db.title,s.CommonUserName,"Agent: ReservationsEdit","General_GetModificationDoc",_
"Das temporäre Änderungsdokument konnte nicht gefunden werden")
'RETURN
General_GetModificationDoc = False
Else
'get username for logging
strUser = Cstr(docMod.EditingUser(0))

'log with the name of the user, which have edited the doc
Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","General_GetModificationDoc",_
"Agent: " & agent.Name & " wurde gestartet")
End If

'RETURN
General_GetModificationDoc = True

Leave:
Exit Function

ErrHandle:
Call CreateLogEntry(db.title,s.CommonUserName,"Agent: ReservationsEdit","General_GetModificationDoc",_
"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
'RETURN
General_GetModificationDoc = False
Resume Leave
End Function





Function City_EditAll()
'**********************************************************************************************************************************************
'This function gets the changed city in the DB Stammdatenverwaltung, search for all reservations with this city
'edit them an send an info mail to the author of the reservation.
'**********************************************************************************************************************************************
On Error Goto ErrHandle
'**********************************************************************************************************************************************
Dim doccol As NotesDocumentCollection 'all reservations which must be edited
Dim resdoc As NotesDocument 'Reservation doc
'**********************************************************************************************************************************************
'search for all reservations with the city
If Not (docMod Is Nothing) Then
Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","City_EditAll",_
"geänderter Ort gefunden: - " & docMod.CityOLD(0))

Dim view As NotesView
Set view = db.GetView("lkpCities")

Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","City_EditAll",_
"suche nach Reservierungen mit Ort: " & docMod.CityOLD(0))

Set doccol = view.GetAllDocumentsByKey(docMod.CityOLD(0),True)

If doccol.Count = 0 Then
Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","City_EditAll",_
"Es wurden keine zu ändernden Reservierungen mit Ort: " & docMod.CityOLD(0) & " gefunden")
Exit Function
End If

'get first reservation
Set resdoc = doccol.GetFirstDocument

'run over all reservations
While Not (resdoc Is Nothing)
Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","City_EditAll",_
"es wurden " & doccol.Count & " Reservierungen gefunden")

'read out old data
strCostObject = resdoc.ReservationOrderNumber(0)
strCityOLD = resdoc.ReservationCity(0)
strDistanceOLD = Cstr(resdoc.ReservationKilometer(0))

Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","City_EditAll",_
"Alter Ort: " & strCityOLD)

'change the data
resdoc.ReservationCity = docMod.CityNEW(0)
Call resdoc.Save(True,False)

Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","City_EditAll",_
"Ort bei Reservierung " & resdoc.NoteID & " wurde geändert")

'Informate the author of the reservation
Call Memo_Variables(resdoc)
Call Memo_Initialize(resdoc)

'get next reservation
Set resdoc = doccol.GetNextDocument(resdoc)
Wend

End If

'delete modification doc after allocating
Call General_DeleteModificationDoc

Leave:
Exit Function

ErrHandle:
Call CreateLogEntry(db.title,strUser,"Agent: ReservationsEdit","City_EditAll",_
"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
'delete modification doc after error
Call General_DeleteModificationDoc
Resume Leave
End Function


--- Ende Code ---



Mein Problem ist im 2. Agenten das General_GetModificationDoc weil hier das tempDoc gesucht wird und die DB angegeben wird. So bräuchte ich für jede DB die Änderungen empfängt einen eigenen Agenten. Um das ganze übersichtlich zu halten will ich aber hier nur mit einem Agenten arbeiten, in dem ich für alle DB's die Änderungen verwalte.
Und da stand ich an dem Punkt, dass ich nicht wusste wie ich dem Agenten mitteile wo er das tempDoc herkiegt. Ich habe das aber jetzt mehr oder weniger gelöst, indem ich alle forms der aktuellen db abfrage und wenn zum Beispiel die Form "Werkzeug" vorhanden ist (natürlich der  Alias), dann soll er in der Mitgliederverwaltung suchen, wenn das fehlschlägt in der Kundenverwaltung. Das ist zwar nicht ganz so dolle/sauber, aber es löst das Problem vorerst. Bin grad noch dabei das für alle DB's umzusetzen, Code dann später.




 

WildVirus:
Moin Moin,

muss die Änderung sofort erfolgen ?

Wenn nein, dann speicher in der "Ausleih-DB" die Kunden- oder Mitgliedernummer als Schlüsselwort ab und hol stündlich, täglich oder wie oft auch immer aus der QuellDB die aktuellen Daten.

Alternative ist, dass beim Ändern des Namens in Kunden- oder Mitgliederverwaltung eine Mail an die Ausleih-DB geschickt wird, die dort ein Agent verarbeitet.

Das wäre beides einfach, sauber und nachvollziehbar.

CU,
Axel

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln