Ich habe hier eine (doch schon etwas betagte) Datenbank, in der ca. 700.000 Dokumente gespeichert sind. Die Dokumente enthalten ein Feld mit einer Kundennummer, welches anhand eine Referenzdatenbank mit einer neuen Kundennummer überschrieben werden soll.
Da die Anzahl der Dokumente sehr groß ist, möchte ich immer nur jeweils einen Block an Dokumenten auslesen und diese dann ändern. Anschließend den nächsten Block etc.
Sub ChangeKUndNr
On Error GoTo errorhandler
Dim sThis As New NotesSession
Dim dbThis As NotesDatabase
Dim dbKNUD As NotesDatabase
Dim viewKAOSUCH As NotesView
Dim docclSearch As NotesDocumentCollection
Dim docProfil As NotesDocument
Dim docBase As NotesDocument
Dim DocKNUD As NotesDocument
Dim iAnswer As Integer
Dim lCounterDoc As Long
Dim lCounterBlock As Long
Dim strSearch As String
Dim strKN As String
Dim strKNOSP As String
Dim strForm As String
'### initialize ###
Set dbThis = sThis.CurrentDatabase
strSearch = "@Modified < @Date(" + Str$(Year(Now())) + ";" + _
Str$(Month(Now())) + ";" + _
Str$(Day(Now())) + ";" + _
Str$(Hour(Now())) + ";" + _
Str$(Minute(Now())) + ";" + _
Str$(Second(Now())) + ")"
iAnswer = MessageBox("Sind Sie sicher, dass Sie in der Datenbank " & dbThis.Title & " alle Kundennummern überarbeiten möchten?", MB_YESNO + MB_ICONQUESTION, dbThis.Title)
If iAnswer = IDNO Then GoTo terminate
'Zugang zur KNUD-Datenbank ermitteln und DB öffnen
Set docProfil = dbThis.Getprofiledocument("Profil")
Set dbKNUD = sThis.Getdatabase(docProfil.KNUDServer(0), docProfil.KNUDPfad(0))
Set viewKAOSUCH = dbKnud.Getview("kaosuch")
'den ersten Block zur Bearbeitung holen
Set docclSearch = dbThis.Search(strSearch, Nothing, 11)
lCounterBlock = 1
Do While docclSearch.Count > 0
'Alle Dokumente der DB 'Kreditaktenarchiv' durchlaufen
Set docBase = docclSearch.Getfirstdocument()
lCounterDoc = docclSearch.Count
Do While Not docBase Is Nothing
strKN = ""
strKNOSP = ""
Print lCounterBlock & ". Block - Es sind noch " & lCounterDoc & " von " & docclSearch.Count & " zu bereinigen ..."
strForm = docBase.Form(0)
Select Case strForm
Case "Akte","Eingabe":
strKN = Format$(docBase.Kundennummer(0),"0000000000")
Case "Historie":
strKN = Format$(docBase.HKundennummer(0),"0000000000")
Case Else:
GoTo nextDoc
End Select
'Set docKNUD = viewKAOSUCH.Getdocumentbykey(strKN, True) --> für Test auskommentiert
If Not docKNUD Is Nothing Then
strKNOSP = docKNUD.KundenummerOSP(0)
Select Case strForm
Case "Akte","Eingabe":
docBase.KundennummerAlt = Format(strKN,"#########0")
docBase.Kundennummer = Format(strKNOSP,"#########0")
Case "Historie":
docBase.HKundennummerAlt = Format(strKN,"#########0")
docBase.HKundennummer = Format(strKNOSP,"#########0")
End Select
'Call docBase.Save(False, False, True) -> für test auskommentiert
End if
nextDoc:
Set docBase = docclSearch.Getnextdocument(docBase)
lCounterDoc = lCounterDoc - 1
Loop
'nächsten Block holen
Set docclSearch = dbThis.Search(strSearch, Nothing, 11)
lCounterBlock = lCounterBlock + 1
Loop
Print "Die Bereinigung der Kundennummern in der Datenbank " & dbThis.Title & " ist abgeschlossen."
'### terminate ###
terminate:
Set sThis = Nothing
Set dbThis = Nothing
Set dbKNUD = Nothing
Set viewKAOSUCH = Nothing
Set docclSearch = Nothing
Set docProfil = Nothing
Set docBase = Nothing
Set docKNUD = Nothing
Exit sub
'### errorhandling ###
errorhandler:
MessageBox "Module: " & "ScriptSPK (Script)" & Chr(10) &_
"Procedure: " & "OpenExtDoc" & Chr(10) &_
"Error: " & Error() & Chr(10) &_
"Code: " & Err() & Chr(10) &_
"Line: " & Erl() & Chr(10) ,_
MB_OK + MB_ICONSTOP ,_
dbThis.Title
Stop
Resume terminate
End Sub
Das Script liefert mir dann jedoch etwas seltsame Werte.
...
1. Block - Es sind noch -43900 von 11 zu bereinigen ...
1. Block - Es sind noch -43901 von 11 zu bereinigen ...
1. Block - Es sind noch -43902 von 11 zu bereinigen ...
2. Block - Es sind noch 11 von 11 zu bereinigen ...
2. Block - Es sind noch 10 von 11 zu bereinigen ...
2. Block - Es sind noch 9 von 11 zu bereinigen ...
2. Block - Es sind noch 8 von 11 zu bereinigen ...
2. Block - Es sind noch 7 von 11 zu bereinigen ...
2. Block - Es sind noch 6 von 11 zu bereinigen ...
2. Block - Es sind noch 5 von 11 zu bereinigen ...
2. Block - Es sind noch 4 von 11 zu bereinigen ...
2. Block - Es sind noch 3 von 11 zu bereinigen ...
2. Block - Es sind noch 2 von 11 zu bereinigen ...
2. Block - Es sind noch 1 von 11 zu bereinigen ...
2. Block - Es sind noch 0 von 11 zu bereinigen ...
2. Block - Es sind noch -1 von 11 zu bereinigen ...
2. Block - Es sind noch -2 von 11 zu bereinigen ...
2. Block - Es sind noch -3 von 11 zu bereinigen ...
2. Block - Es sind noch -4 von 11 zu bereinigen ...
2. Block - Es sind noch -5 von 11 zu bereinigen ...
...
Offentsichtlich sind in der DocCollection ja die angeforderten 11 Dokumente enthalten. In der inneren Schleife werden dann jedoch alle Dokumente meiner TestDB durchlaufen.
Ich hab jetzt schon alles Mögliche probiert, aber irgenwie sehe ich den Wald vor lauter Bäumen nicht mehr. Hat irgendjemand ne Idee???
Regards
Alfirin
Set docclSearch = dbThis.Search(strSearch, Nothing, 11)
lCounterBlock = 1
Do While docclSearch.Count > 0
'Alle Dokumente der DB 'Kreditaktenarchiv' durchlaufen
Set docBase = docclSearch.Getfirstdocument()
lCounterDoc = docclSearch.Count
Warum sollte sich der Count auch ändern? Du kickst ja nirgendwo ein Dokument aus der Collection. Der bleibt also immer größer als Null. Endlossschleife. Oder übersehe ich da etwa etwas?
Laufe Collections doch lieber so in der Art durch:
coll = db.Search({foo}, Nothing, 0)
Set doc = coll.GetFirstDocument
While Not doc Is Nothing
'Code
Set doc = coll.GetNextDocument(doc)
Wend
Gruß,
Mitch
Ok, mit einer "statischen" DocCollection sollte es passen.
Das mit dbSearch ist aber alles andere als performant mit den vielen Aufrufen, das aber nur nebenbei.
Do While Not docBase Is Nothing
strKN = ""
strKNOSP = ""
Print lCounterBlock & ". Block - Es sind noch " & lCounterDoc & " von " & docclSearch.Count & " zu bereinigen ..."
...
nextDoc:
[i][b] Set docBase = docclSearch.Getnextdocument(docBase)[/b][/i]
lCounterDoc = lCounterDoc - 1
Loop
das aber wundert mich, die Schleife wird bei dir erst nach zig tausend (ca. 40000) Durchläufen beendet.
Ich vermute mal, er navigiert dich trotzdem auf das nächste Dokument in der Gesamtmenge und beschränkt sich nicht auf die 11 Treffer ?
Lass dir mal in einer Schleife die UNID ausgeben und bei deinem bestehenden Print auch, vielleicht erkennt man da was uns hilft.