Das Notes Forum
Domino 9 und frühere Versionen => ND6: Entwicklung => Thema gestartet von: tfrenz am 21.08.09 - 08:55:10
-
Hallo,
habe da ein Problem mit dem Verschieben (Archivieren) von Dokumenten.
Ich habe einen Agenten in LS geschrieben, der mir aus einer DB alle Dokumente die vor einem best. Datum Created worden sind in eine sog. Archiv-DB kopieren und dann löschen soll.
Der Agent läuft los, geht ca. 15.000 - 20.000 Dokumente durch, dann beendet er sich ohne Fehlermeldung.
Ich habe nun schon einige Print's eingebaut, damit ich sehe, wann er abbricht.
Der "Print "Set Doc = DocNext"" wird noch ausgeführt, dann nichts mehr. Vermutlich liegt es an dem
"Set Doc = DocNext".
In der Archiv-DB sind dann auch die 15.000 - 20.000 Dokumente vorhanden, und in der Orginal DB gelöscht.
Ich sehe leider keinen Fehler, hoffentlich kann mir da jemand helfen.
Danke
Thomas
Agent
----------------------------------------------------------------------------
Sub CreateArchiv
On Error Goto ErrorMail
Print "Agent CreateArchiv Start"
Dim Session As New NotesSession
Dim DB As NotesDatabase
Dim proDoc As NotesDocument
Dim Col As NotesDocumentCollection
Dim Doc As NotesDocument
Dim DocNext As NotesDocument
Dim DBArchiv As NotesDatabase
Dim DBArchivAgent As NotesAgent
Dim DocMail As NotesDocument
Dim rtitem As NotesRichTextItem
Dim strArchivMonate As String
Dim strArchivPfad As String
Dim strArchivLastDate As String
Dim strMonth As String
Dim strYear As String
Dim cnt As Double
Dim DBReplica As NotesDatabase
Dim strArchivDB As String
Dim strClusterServer As Variant
Dim i As Integer
Dim agentArray( 1 To 30) As String
Dim agent As NotesAgent
Dim agcnt As Integer
Dim x As Integer
agcnt = 0
cnt = 1
Dim AktDatum As New NotesDateTime(Now)
.......
Set Col = DB.AllDocuments
Print "Anz. Dokumente: " & Col.Count
Set Doc = Col.GetFirstDocument
Print "Alle Dokumente bis Erstelldatum " & Aktdatum.DateOnly & " werden archiviert."
While Not (Doc Is Nothing)
Set DocNext = Col.GetNextDocument(Doc)
Dim datDocCreate As New NotesDateTime(Doc.Created)
If AktDatum.TimeDifference(datDocCreate) > 0 Then
' Print "Dokument kopieren"
Call doc.CopyToDatabase( DBArchiv )
' Print "Dokumet löschen"
Call doc.Remove( False )
cnt = cnt + 1
Print Cstr(cnt)
End If
Print "Set Doc = DocNext"
Set Doc = DocNext
Print "nach Set"
Wend
Print "Nach Wend"
ErrorMail:
Call ErrorMailSend("ERROR:" & Err() & ": " & Error() & ", in Line " & Erl())
Print "Error " & Err() & ": " & Error()& ", in Line " & Erl()
End Sub
-
Einen direkten kann ich auf Anhieb auch nicht finden. Unter Umständen ist es auch ein internes Problem mit der Speicherverwaltung.
Um Set doc = Docnext als felherquelle auszu schließen kannst du ja auch mal folgendes probieren.
Kopiere zuerst alle Dokumente der Collection in die andere Datenbank und erst danach löscht du die Dokumente mit
col.RemoveAll(true)
aus der Datenbank.
Axel
-
Danke Axel für die schnelle Antwort.
aber ich will ja nicht alle Dokumente aus der DB löschen.
Aber du hast mich auf die Idee gebracht, zuerst alle Dokumente zu kopieren, dann in einer 2.ten Schleife die Dokumente zu löschen, die z.B. in einer Ansicht "Archivierte Dokumente" mit dem Flag "archiviert=1" angezeigt werden. Dann kann ich ja mit ViewCollection.RemoveAll(True) alle Dokumente löschen.
Thomas
-
Geht mir genauso wie Axel.
Aber ...
Erstens ist es nicht sinnvoll jedes einzelne Dokument zu überprüfen ob es im Zeitfenster für die Archivierung liegt. Nimm um die Collection der zu archivierenden Dokumente zu erstellen nicht alldocuments sondern einen db.Search mit einer entsprechenden Suchformel.
Zweitens, Prints in Agents entschleunigen den Agenten erheblich. Egal ob der dann auf dem Client oder auf dem Server läuft. Wobei es auf dem Server noch schlimmer ist, denn jeder Print bedeutet er muss was in die Logdokumente schreiben.
Drittens les die Hilfe zu RemoveAll für DocCollection. Die tut genau das was sie soll und nicht das was du denkst das sie tut.
Viertens wenn du erst alle Dokumente kopierst und dann löscht musst du im fehlerfall ein anderes Handling aufbauen.
Also
db.search mit entsprechendem Parameter um eine resultierende Collection zu bekommen
Leere Collection mit einem Pseudosearch bauen.
resultierende Collection mit Schleife durchlaufen damit du die Dokumente einzeln in die andere Datenbank kopieren kannst.
jedes kopierte Dokument in der Leeren Collection ablegen.
nach Ende der Schleife resultierende Collection mit col.removeall(true) behandeln.
Im Fehlerfall Resultierende Collection mit col.removeall(true) behandeln.
-
Wenn das ein serverbasierter periodischer Agent ist, dann wird ggf. die maximal zulässige Laufzeit von Agenten, die im Serverdokument definiert ist, überschritten. Das führt dann zum Abbruch des Agenten.
Andreas
-
Danke Thomas für die Informationen.
Die Prints habe ich ja nur zum Debuggen eingebaut, im Normalfall sind keine drin.
Werde den Agenten auf DB.Search umbauen, darauf bin ich nicht gekommen.
Werde es testen und dann berichten. Komme aber vermutlich erst am Montag dazu.
Thomas