Domino 9 und frühere Versionen > ND8: Entwicklung

Problem mit db.search

(1/3) > >>

Alfirin:
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.


--- Code: ---...
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 ...
...
--- Ende Code ---

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

ghostmw:
Hallo Alfirin,

ok, hast du schon mal probiert, dir eine Ansicht zu basteln, und die Notesdocument-Objekte aus der Ansicht zu lesen?

Das ist eine gute Alternative, damit hast du die Limitierung und die Blockbildung nicht, die dir aktuell Probleme bereitet.

Die Selektionsformel kannst du mit der Eigenschaft SelectionFormula des NotesView-Objektes manipulieren und setzen, mit den Paramtern aus deinem Search-Aufruf.
Z.B. Select Form="MEINEFORM" & myDate >= [1.1.2014]

Das kannst du ggf. auch in der Hilfe nachlesen.
Ein Refresh der Ansichtsdaten und es kann mit dem Iterieren losgehen über alle Dokumente ( => getFirst/getNextDocument ).

Wäre zu überlegen.

Gruß
Marco

Alfirin:
Hallo Marco,

das wäre sicher auch ein gangbarer Weg. Aber mich interessiert doch zunächst, wieso in der DocCollection die korrekte Anzahl an Dokumenten über 'Count' ausgewiesen wird, wenn ich dann jedoch die Dokumente 'durchblättere' ein aus meiner Sicht völlig unlogisches Verhalten auftritt.

Da die Ursache des Fehlers ja in der Regel vor der Tastatur sitzt würde ich doch gern die Ursache kennen, damit ich zukünftig nicht in die selbe Falle tappe.  ;D

Regards


Alfirin

ghostmw:
Ok, verstehe ...
ich gehe immer den Ansatz, wenn ich länger als x Minuten nach einem Problem und dessen Ursache suche, nehme ich eine andere Variante.

Also du machst in deinen Schleifen db.Search.
Da bekommst du 0-11 Treffern, meiner Meinung nach bekommst du doch aber immer die gleichen x Treffer aus meiner Sicht zurückgeliefert und nicht fortlaufend. Das gibt der Befehl nicht her.


--- Zitat ---  Loop
      
      'nächsten Block holen
      Set docclSearch = dbThis.Search(strSearch, Nothing, 11)
      lCounterBlock = lCounterBlock + 1
      
   Loop
--- Ende Zitat ---

Da liegt der Hase im Pfeffer ...


--- Zitat ---extDoc:  
         Set docBase = docclSearch.Getnextdocument(docBase)
--- Ende Zitat ---

Da könnte auch eine Ursache liegen, du manipulierst und speicherst das docBase, und holst dann anhand dessen das nächste Dokument. Wenn man Views benutzt, und das Dokument durch das Speichern aus der Ansicht verschwindet, knallts hier u.U.
Ich kann aktuell nicht ausschließen, dass es bei dir nicht auch so sein könnte.

Wie dein Script überhaupt fertig werden kann, ist noch ein wenig schleierhaft, das müsste eine Endlosschleife geben für  
--- Code: ---docclSearch.Count > 0
--- Ende Code ---
.

Alfirin:
Hallo Marco,

richtig. Zur Zeit bekomme ich immer dieselben 11 Treffer, da ich das docThis.Save auskommentiert habe. Ich wollte halt ganz bewusst noch keine Veränderung an den Dokumenten durchführen, solange die Schleife nicht korrekt läuft. Darüber hinaus sollen die Blöcke im Echtbetrieb dann auch eine Größe von 30.000 Dokumenten haben.

Wenn das docThis.Save dann ausgeführt wird, müsste ja auch die Treffermenge immer geringer werden, da die Dokumente ja dann mit einem aktuelleren Datum verändert worden sind und somit nicht mehr den Suchkriterien entsprechen. Irgendwann würde dann auch ein Block mit Count=0 zurückgeliefert werden und die Schleife somit beendet.

Zum jetzigen Zeitpunkt ist es allerdings wirklich eine Endlosschleife, welche ich jedoch über den Debugger beende.  8)


--- Zitat ---Da könnte auch eine Ursache liegen, du manipulierst und speicherst das docBase, und holst dann anhand dessen das nächste Dokument. Wenn man Views benutzt, und das Dokument durch das Speichern aus der Ansicht verschwindet, knallts hier u.U.
Ich kann aktuell nicht ausschließen, dass es bei dir nicht auch so sein könnte.
--- Ende Zitat ---

Hm. Das kann ich mir so nicht recht vorstellen. Zum Einen handelt es sich doch hier um eine DocCollection und nicht um einen View und die DocCollection sollte doch eigentlich statisch sein, oder? Zum Anderen hab ich ja die Speicherung auskommentiert. Somit sollte es doch zum jetzigen Zeitpunkt sauber laufen.

Regards



Alfirin

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln