Domino 9 und frühere Versionen > ND8: Entwicklung
Optimierung einer Suchfunktion
Valron:
Hallo Dirk,
wie Mitch bereits erwähnt hat, ist es nicht notwendig alle Dokumente zu durchlaufen.
Es ist wesentlich performanter, explizit danach in einer sortierten Ansicht zu suchen.
So wie ich das verstanden habe, darf eine Nummer pro Jahr nur einmal vergeben werden,
d.h. die Nummer "00023" darf jeweils einmal für 2012, 2013 und 2014 existieren. Ist das so korrekt?
Ich habe auf die schnelle deinen Code etwas angepasst (Nicht getestet -> Dient nur als Ansatz)
--- Code: ---Function NummerSuchen(jahr As String, nummer As String, refdoc As NotesDocument) As Variant
Dim s As New NotesSession
Dim db As NotesDatabase
Dim v As NotesView
Dim doc As NotesDocument
Dim asKeys(0 To 1)
Set db = s.CurrentDatabase
Set v = db.GetView("(LUNummern)") '// Eine View, dessen 1. Spalte Ablagenummer_1 und 2. Spalte Ablagenummer_2 ist (Beide sortiert)
asKeys(0) = jahr
asKeys(1) = nummer
Set doc = v.GetDocumentByKey(asKeys, True)
If doc Is Nothing Then
'//Es wurde nichts gefunden, die mitgegebene Nummer existiert also nicht für das mitgegebene Jahr
Else
If Not refdoc Is Nothing Then
If StrCompare(doc.Universalid, refdoc.Universalid, 5) <> 0 Then '// StrCompare ist meines Wissens nach performanter, als Strings direkt miteinander zu vergleich
MsgBox "Die Nummer wurde schon vergeben.",16,"Hinweis"
NummerSuchen = True
End If
Else
MsgBox "Die Nummer wurde schon vergeben.",16,"Hinweis"
NummerSuchen = True
End If
End If
End Function
--- Ende Code ---
Wenn in der Ansicht mit den angegebenen Keys nichts gefunden wird, so ist die Nummer noch
nicht vergeben.
Falls jedoch was gefunden wird, wird noch geprüft, ob es sich beim gefundenen Dokument um
das mitgegebene Dokument handelt.
Diese Stelle habe ich mit StrCompare ersetzt, da nach meinem Wissensstand StrCompare
performanter ist. -> Holt zwar nicht viel raus, da es nur noch einmal aufgerufen wird, aber egal :-P
Ich hoffe, ich konnte dir hiermit ein wenig unter die Arme greifen. ;-)
Gruß,
Rich
Keydins:
Ich habe die Funktion auf Basis von Mitchs Tip angepasst und bisher sieht das von der Geschwindigkeit sehr gut aus (Prüfung deutlich unter 10 Sekunden). Die View war schon passend aufgebaut (1. Spalte = Jahr; 2. Spalte = laufende Nr.; beide aufsteigend sortiert)
--- Code: ---Function NummerSuchen(jahr As String, nummer As String, refdoc As NotesDocument, v As NotesView) As Variant
Dim s As New NotesSession
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim keys( 1 To 2 ) As Integer
Dim doc As NotesDocument
Set db = s.CurrentDatabase
keys(1) = Cint(jahr)
keys(2) = Cint(nummer)
Set dc = v.GetAllDocumentsByKey(keys, True)
NummerSuchen = False
If dc.Count = 0 Then
Exit Function
Else
Set doc = dc.GetFirstDocument ()
While Not doc Is Nothing
If Cint(doc.Ablagenummer_2 (0)) = Cint(nummer) Then
If Cint(jahr) = Cint(doc.Ablagenummer_1 (0)) Then
'Wenn das Dokument nicht neu ist
If Not refdoc Is Nothing Then
If Cstr(doc.UniversalID) <> Cstr(refdoc.UniversalID) Then
Msgbox "Die Nummer wurde schon vergeben.",16,"Hinweis"
NummerSuchen = True
Exit Function
End If
Else
Msgbox "Die Nummer wurde schon vergeben.",16,"Hinweis"
NummerSuchen = True
Exit Function
End If
End If
End If
Set doc = dc.GetNextDocument(doc)
Wend
End If
End Function
--- Ende Code ---
@Rich
Den Tip mit dem StrCompare werde ich auch mal testen, mehr Performance kann nicht schaden.
Andrew Harder:
Hast Du schon in der Lookup-Ansicht alle Dokumente ausgeschlossen, die älter als 2 Jahre sind?
Beim Jahreswechsel wird man evtl. auch den Lookup auf das alte Jahr benötigen.
Noch ältere sollten für einen Lookup aber nicht notwendig sein?
Das sollte die Ansicht schneller aufbauen, beim ersten mal wirds etwas länger dauern, aber dann gehts los....
Der Hauptgeschwindigkeitsgewinn wird aber auf jeden Fall vom Lookup kommen ;)
Mitch:
Huhu Dirk,
das sieht doch schon gut aus.
Da du ja die potentiellen Dublikate mit einem exakten Schlüssel ziehst, kannst du dir im weiteren Verlauf die Prüfung auf die Items "Jahr" und "Ablagennummer_2" noch sparen.
Eigentlich reicht die Prüfung auf "Nichts gefunden -> Nummer frei", "Mehr als 1 gefunden -> Ohoh, schnell dem Anwendungsverantwortlichen mailen", "Genau eins gefunden -> Prüfen ob ich es selbst bin".
Eine entsprechende Anpassung hier wird zwar vermutlich keinen fühlbaren Performance-Unterschied machen, aber du hast ein paar Zeilen weniger in denen Fehler auftreten können. Apropos Fehler: Ein Errorhandling ist immer eine gute Idee. ;) In den Best Practices gibt es Anregungen dazu: http://atnotes.de/index.php/topic,11980.0.html
Gruß,
Mitch
Valron:
Hallo Dirk,
die Abfragerei unten...
--- Code: --- If CInt(doc.Ablagenummer_2 (0)) = CInt(nummer) Then
If CInt(jahr) = CInt(doc.Ablagenummer_1 (0)) Then
'...
End If
End If
--- Ende Code ---
... ist nicht mehr notwendig, da diese nur zur identifizierung des Dokuments diente.
Diese Abfragen werden nun IMMER True liefern, da die Dokumente mit denen du prüfst,
anhand dieser Kriterien gefunden worden sind.
Dann zu deinen Keys,...
--- Code: --- Dim keys( 1 To 2 ) As Integer
keys(1) = CInt(jahr)
keys(2) = CInt(nummer)
--- Ende Code ---
Aufgrund folgender Aussage von dir...
--- Zitat ---Die Nummern sind immer 5-stellig mit führenden Nullen und werden aus diesem Grund als Text im Dokument gespeichert.
--- Ende Zitat ---
... gehe ich davon aus, dass deine NotesDocumentCollection immer leer bleibt. ;)
Du musst in diesem Fall dein Array als String deklarieren und dementsprechend mit den Strings füllen.
Edit: Mitch war schneller... :(
Gruß,
Rich
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln