Das Notes Forum

Domino 9 und frühere Versionen => ND8: Entwicklung => Thema gestartet von: schroederk am 11.01.11 - 13:03:44

Titel: Wie zähle ich am besten Dokumente einer View?
Beitrag von: schroederk am 11.01.11 - 13:03:44
Hallo,

ich würde gerne mittels Lotusscript Dokumente in einer View zählen, alle vom heutigen Datum und alle vom diesem Monat.
Bisher würde ich in einer Schleife alle Dokumente einzeln durchgehen.  Das wird bei vielen (alten) Dokumenten schnell zeitintensiv.
Die Datenbank besitzt einen Volltextindex, aber kann ich die View vor der Schleife nach einem Feld sortieren und den Zeiger setzen?
Oder gibt es noch bessere Techniken?

Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: atbits am 11.01.11 - 13:07:19
Code
Dim session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim vc As NotesViewEntryCollection
Set db = session.CurrentDatabase
Set view = db.GetView("By Category")
view.AutoUpdate = False
Set vc = view.AllEntries
Messagebox vc.Count

ungetestet aus der noteshilfe

grüße David
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: schroederk am 11.01.11 - 13:12:00
Danke, aber ich möchte nicht wissen, wieviele Dokumente insgesamt in einer View sind, sondern nur die, die dem aktuellen Datum bzw. dem aktuellen Monat betreffen.
Kann ich vielleicht vorher einen Filter setzen, der nur die Dokumente die einem bestimmten Kriterium entsprechen, selektiert und dann mit Count zählen?
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: atbits am 11.01.11 - 13:16:57
Kannst Du die View denn kategorisieren oder die erste Spalte auf das Datum ändern?
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: Peter Klett am 11.01.11 - 13:25:11
Wenn Du das ohne separate Ansicht machen willst, geht es auch mit NotesDatabase.Search:

z.B. Set col = db.Search ({Form = "meineForm" & Datum = @Today}, Nothing, 0)

Der blaue Text ist eine Selektionsformel, wie Du sie auch in einer Ansicht nutzen würdest, wobei Du in einer Ansicht möglichst kein @Today verwenden solltest, bei Search ist das kein Problem.

col.Count ist dann die Anzahl der Dokumente
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: schroederk am 11.01.11 - 13:27:19
Die View ist kategorisiert und die erste Spalte danach ist das Datum.
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: atbits am 11.01.11 - 13:31:00
Na dann nimm passe ich meinen Code doch wie folgt an:
Code
Dim session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim vc As NotesViewEntryCollection
Set db = session.CurrentDatabase
Set view = db.GetView("By Category")
view.AutoUpdate = False
view.GetAllEntriesByKey(DATUMSSTRING)
Messagebox vc.Count

Jetzt braucht Du nur noch den DATUMSSTRING zu setzen
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: Peter Klett am 11.01.11 - 13:31:14
Set col = view.GetAllDocumentsByKey (datum, True)

Dann ist wieder col.Count die Anzahl der Dokumente (musst Du aber ausprobieren, da ich meine, dass die erste Spalte sortiert und Text sein muss, kann mich aber irren)

Edit: Oder so, wie David geschrieben hat, kommt aufs gleiche
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: schroederk am 11.01.11 - 13:59:24
Code
	Dim todaysdate As New NotesDateTime("Today") 
	Dim dateTime As New NotesDateTime(todaysdate.DateOnly)
	Dim keyarray(0) As Variant 
	Set keyarray(0) = dateTime
	
	view.AutoUpdate = False
	Set vc = view.GetAllEntriesByKey(keyarray, true)
	Print vc.Count

gibt leider 0 zurück, obwohl da allein von heute Dokumente im dreistelligen Bereich existieren.
Zudem die Frage, wie ich auch nach nur dem Monat suchen kann.

Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: atbits am 11.01.11 - 14:09:40
Na Du mußt erst noch todaysdate in einen passenden String konvertieren.
Für Monate mußt Du auf Peters Lösung mit der Search zurückgreifen, die kostet allerdings mehr Performance.
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: schroederk am 11.01.11 - 14:12:47
Für Monate mußt Du auf Peters Lösung mit der Search zurückgreifen, die kostet allerdings mehr Performance.
Ist denn diese Methode wenigstens weniger Performance-lastig wie eine selbstgebaute Schleife durch alle Dokumente?
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: Peter Klett am 11.01.11 - 14:34:11
Ist denn diese Methode wenigstens weniger Performance-lastig wie eine selbstgebaute Schleife durch alle Dokumente?
Ja, auf jeden Fall. Ich nutze sowas recht gerne, denn wenn ich eine Ansicht habe und die zur Sicherheit vorher einmal refreshe, ist das auch nicht schneller.
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: atbits am 11.01.11 - 14:37:00
Ich denke Peter hat Recht - für größere Views mit mehr als eine Handvoll Dokumente würde ich das auch so sehen.
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: Peter Klett am 11.01.11 - 14:41:32
Wenn Dir die Ansicht lieber ist, kannst Du natürlich auch für die Monate eine eigene Ansicht bauen, die die Dokumente nach Monat kategorisiert.

Ich nutze db.Search deshalb lieber, weil bei einer Ansicht auch mal ein Index zerschossen sein kann. Dann habe ich ein schnelles falsches Ergebnis, ein etwas langsameres und richtiges ziehe ich aber vor (ist aber eine reine Bauchentscheidung und nicht wissenschaftlich bewiesen).

Das hängt natürlich auch von dem Umfeld, in das die Funktion integriert werden soll, ab.
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: schroederk am 11.01.11 - 16:52:07
Ich werd mal rumtesten, wie stark sich speziell bei meiner Datenbank die Performance-Unterschiede bemerkbar machen.
Im Moment hab ich das mal in einer einfachen Schleife gelöst, aber diese kommt noch nichtmal auf die korrekten Werte  :o
Es werden im Moment knapp unter der Hälfte der eigentlich zu zählenden Dokumente gezählt.
Mal sehen, ob ich mit dem db.Search mehr Glück habe  ;)
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: koehlerbv am 11.01.11 - 17:09:34
Wenn Dein Code nicht die korrekte Anzahl liefert (die Du sicherlich an Hand der View überprüfst), dann liegt der Fehler natürlich bei Dir.

Zu NotesDatabase.Search: Ein Performance-Test lohnt sich wirklich. Da NotesDatabase.Search keine "dumpfe Suche" durchführt, sondern interne Tables auswertet, ist es in der Regel viel flotter, als man zunächst erwarten würde.
Wenn Du aber ein paar hunderttausend Dokumente in der DB herumlungern hast, aber nur eine geringeren dreistelligen Bereich an Dokumenten im fraglichen Zeitraum darunter, dann kann das Search auch nach hinten losgehen.
In diesem Falle solltest Du dann aber die View (NotesViewEntryCollection) auswerten (und nicht jedem einzelnen Dokument erst die Hand schütteln!) - Deine Ansicht ist ja laut Schirmschuss eh schon nach Datum absteigend sortiert, so dass Du beim ersten Treffer ausserhalb des Datumsbereichs sagen kannst: "Okay, das war's - lass uns was anderes spielen!".

Bernhard
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: eknori am 12.01.11 - 06:53:22
Wenn du die Ansicht intelligent aufbaust, kommst du evtl. hiermit http://www.eknori.de/2008-12-29/get-view-column-sums-with-lotusscript/ zum Ziel. Es muss ja nicht die Ansicht sein, die der User sieht.
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: Peter Klett am 12.01.11 - 08:36:35
... Es muss ja nicht die Ansicht sein, die der User sieht.
Ich würde Funktionen niemals von sichtbaren Ansichten abhängig machen. Wenn von den Usern ein berechtigter Änderungswunsch zu einer sichtbaren Ansicht kommt, wird die Ansicht geändert und die Funktion ist kaputt, oder Du musst den Wunsch ablehnen. Beides ist nicht gut.

Wir haben das bei uns so organisiert:

Sichtbare Ansichten haben grundsätzlich keinen Alias (Ausnahme webDefaultView oder andere Notesvorgaben)
Versteckte Ansichten haben immer einen Alias
Wird eine versteckte Ansicht von einer Routine außerhalb der Datenbank verwendet, beginnt der Name mit einem $ (natürlich nach der Klammer, sonst ist die Ansicht nicht mehr verborgen, also z.B. "($NameDerAnsicht)")
Programmatischer Zugriff auf Ansichten erfolgt immer über den Alias, niemals über den Ansichtsnamen

So kann es eigentlich nicht passieren, dass jemand eine Routine baut, die von einer sichtbaren Ansicht abhängig ist (da wäre dann ein doppelter Verstoß notwendig, 1. Zugriff auf sichtbare Ansicht, 2. Zugriff nicht über den Alias)
Änderungen von versteckten Ansichten ohne $ müssen nur in der Datenbank selbst getestet werden
Änderungen von versteckten Ansichten mit $ lässt man am besten sein
Eine Ansicht, die bisher nur intern verwendet wurde, kann problemlos in eine extern genutzte umbenannt werden, da das $ nur vor den Namen, aber nicht vor den Alias gestellt wird

Um die Datenbanken nicht mit zu vielen Ansichten unnötig zu belasten, werden versteckte Ansichten nur gebaut, wenn sie wirklich einen Vorteil bringen, und in der Regel möglichst allgemeingültig gehalten, um sie für mehrere Funktionen nutzen zu können.

Die letzten 10 Jahre sind wir gut damit gefahren.
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: schroederk am 12.01.11 - 16:23:20
Vielen Dank für den Tipp Peter, das ist sicher eine gute Regel.
In meinem Fall kann ich momentan noch wild bauen, da es innerhalb der Firma keinen Notes-Entwickler gibt (ich schließe mich dabei noch ein).
Die Datenbank ist sher simpel und ich möchte in jetzigen Fall einfach ermitteln, wieviele ein- und ausgehende Faxe wir erhalten haben. Heute und im aktuellen Monat. Da wird die vorhandene Ansicht sicherlich nicht mehr geändert und sollte es mal eine neue Version der Fax-Software geben, muss sicherlich sowieso hand angelegt werden.

Der Link über die get-view-columns-sums sieht sehr interessant aus. Vielen Dank eknori, das muss ich mir unbedingt genauer anschauen.

Im Moment versuche ich noch Troubleshooting, was mein momentanes Script betrifft. Zu einem Performance-Vergleich habe ich mal folgende Scripte zeitlich verglichen:
Code
	Set doc = view.GetFirstDocument
	While Not(doc Is Nothing)
		str_datum = Left(doc.GetItemValue( "StartTime" )(0),10)
		If str_datum = str_aktdatum Then
			ges_heute = ges_heute + 1		
		End If
		If Mid(str_datum,4,2) = Mid(str_aktdatum,4,2) Then
			ges_monat = ges_monat + 1
		End If
		Set doc = view.GetNextDocument(doc)
	Wend
und
Code
Set col = db.Search ({Form = "FaxForm" & StartTime = @Today}, Nothing, 0)
ges_heute = col.Count

Zudem das bestehende PHP-Script über die COM-Schnittstelle:
Code

$entry = $view->GetFirstDocument();
while (is_object($entry)) {
	$field = $entry->GetFirstItem( "StartTime" ); 
	$starttime = $field->text; 
	if (substr($starttime,2,4) == ".$monat.") {
		$efaxmon ++;
		$field = $entry->GetFirstItem( "PAGES" ); 
		$seiten = $field->text; 
		$eseitenmon += $seiten;
		if (substr($starttime,0,3) == "$tag.") {
			$efaxtag ++;
			$eseitentag += $seiten;
		}
	}
	$entry = $view->getNextDocument($entry);
}

Merkwürdigerweise stimmt nur das PHP-Script mit dem Wert aus der DB überein.
Die beiden Lotusscripte Code-Fragmente liefern beide einen deutlich geringeren Wert (z.b. 60 anstatt 110)

In jedem Fall lässt sich schonmal sagen, dass die Variante db.Search mindestens Faktor 10 schneller ist.
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: koehlerbv am 12.01.11 - 16:31:41
Du hast Da aber noch merkwürdigen Code: Im Fall 1 erwartest Du als StartTime einenString, im zweiten einen Datums-/Zeitwert. Das wären schon mal Äpfel und Birnen.
Weiters: Wie ist StartTime überhaupt abgelegt? Als reiner Datums- / oder als Datums-/Zeitwert oder gar gemischt? Denn 12.01.2011 16:31 ist nicht gleich Today (12.01.2011)!

Ist der Code korrekt, dann stimmt auch mit LS das Ergebnis exakt.

Zum ersten LS-Code: Du gehst hier ganz dumpf per Schleife durch alle Dokumente in der Ansicht - das ist natürlich sehr langsam (in Bezug auf NotesDatabase.Search sind das also wieder Äpfel und Birnen, die Du da vergleichst). Siehe hierzu mein letztes Posting!

Bernhard
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: Peter Klett am 12.01.11 - 16:33:37
Kann es sein, dass in den Dokumenten eine Seitenanzahl steht und Dein PHP-Script die Seiten addiert? Bei den LotusScript-Routinen zählst Du nur die Log-Dokumente.

Wenn das so ist, würde ich mit db.Search alle relevanten Dokumente suchen und denn mit NotesDocumentCollection.GetFirstDocument und .GetNextDocument alle Dokumente durchgehen und die Seitenzahlen addieren.
Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: Peter Klett am 13.01.11 - 06:49:23
Probier mal

Set col = db.Search ({Form = "FaxForm" & @Date (StartTime) = @Today}, Nothing, 0)

falls StartTime in jedem Dokument vom Typ Datum ist, oder

Set col = db.Search ({Form = "FaxForm" & @Date (@TextToTime (StartTime)) = @Today}, Nothing, 0)

falls StartTime in einigen/allen Dokumenten vom Typ Text ist.

Eventuell wird auch der Maskenname nicht immer korrekt geschrieben, was Groß-Kleinschreibung angeht. Ich verwende gerne @LowerCase (Form) = "faxform", da bin ich auf der sicheren Seite.

Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: schroederk am 13.01.11 - 08:15:39
Im Fall 1 erwartest Du als StartTime einenString, im zweiten einen Datums-/Zeitwert.
Meinem (wohl fehlerhaftem Verständnis nach) lese ich mit GetItemValue( "StartTime" )(0) den Wert als String aus.
Den Wert mit Print ausgegeben zeigte mir zumindest einen korrekten Eintrag an.

Weiters: Wie ist StartTime überhaupt abgelegt? Als reiner Datums- / oder als Datums-/Zeitwert oder gar gemischt? Denn 12.01.2011 16:31 ist nicht gleich Today (12.01.2011)!
Starttime ist Datum/Zeitwert. Dadurch hätten doch Starttime und Today eigentlich nie eine Übereinstimmung finden dürfen. Dennoch kam die Funktion auf die selbe Anzahl wie oben mit dem fehlerhaften String (und zwar 60 und nicht 0)

Zum ersten LS-Code: Du gehst hier ganz dumpf per Schleife durch alle Dokumente in der Ansicht - das ist natürlich sehr langsam (in Bezug auf NotesDatabase.Search sind das also wieder Äpfel und Birnen, die Du da vergleichst). Siehe hierzu mein letztes Posting!
Inwiefern das Äpfel mit Birnen vergleichen ist, verstehe ich nicht. Beide Script-Teile sollen die selben Dokumente zählen. Beide brauchen dafür Zeit. Und diese Zeit vergleiche ich.


Probier mal
Set col = db.Search ({Form = "FaxForm" & @Date (StartTime) = @Today}, Nothing, 0)
Diese Suche funktioniert jetzt einwandfrei :D


Ich werd aber in jedem Fall auch noch das Beispiel von eknori versuchen. Das scheint mir im Moment am performantesten.  ;)

Titel: Re: Wie zähle ich am besten Dokumente einer View?
Beitrag von: schroederk am 13.01.11 - 13:41:19
Ich habe letzlich die Lösungsidee von eknori verwendet.
Funktioniert tadellos und ist auch die schnellste Lösung.

Vielen Dank für die Hinweise, Anmerkungen und Unterstützung