Autor Thema: Collection sortieren?  (Gelesen 2481 mal)

Offline Spalter

  • Aktives Mitglied
  • ***
  • Beiträge: 109
  • Mit der Lizenz zum Löschen!!!
Collection sortieren?
« am: 21.06.05 - 10:30:59 »
Hallo zusammen,

hatte gestern eine Thread zum Thema Dynamische Search Formel.

Nun das nächste Problem. Die Collection, die ich mit dem Search erhalte, ist natürlich unsortiert - wie auch anders nicht zu erwarten.

Jetzt meine Frage:

Gibt es einen Würg-Around, die Docs der Collection nun doch nach bestimmten Kriterien (Feldwert) zu sortieren und anschließend in der Reihenfolge zu verarbeiten?

Gruß
Spalter  :-:

Offline diali

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.023
  • Geschlecht: Männlich
Re: Collection sortieren?
« Antwort #1 am: 21.06.05 - 10:36:39 »
ja.

baue ein 2-dimensionales Array, fülle es mit dem Sortierschlüssel und der UniquID. Danach sortierst Du das Array nach dem Sortierschlüssel (z.B. mit Q-Sort) und dann gehst Du das Array durch und holst die Dokumente mit NotesDatabase.GetDocumentByUNID(...).

Gruß
Dirk
Gruß
Dirk

Offline m3

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 8.102
  • Geschlecht: Männlich
  • Non ex transverso sed deorsum!
    • leyrers online pamphlet
Re: Collection sortieren?
« Antwort #2 am: 21.06.05 - 10:39:51 »
Bist Du Dir sicher, dass es nicht sortiert ist (nach irgendeiner obskuren Sortierregel)? Weil die Notes-Hilfe meint, dass Ergebnisse einer Suche sehr wohl sortiert sind.

Zitat
IsSorted property 
Read-only. Indicates whether the documents in a collection are sorted. A collection is sorted only when it results from a full-text search of a database.

HTH
m³ aka. Martin -- leyrers online pamphlet | LEYON - All things Lotus (IBM Collaborations Solutions)

All programs evolve until they can send email.
Except Microsoft Exchange.
    - Memorable Quotes from Alt.Sysadmin.Recovery

"Lotus Notes ist wie ein Badezimmer, geht ohne Kacheln, aber nicht so gut." -- Peter Klett

"If there isn't at least a handful of solutions for any given problem, it isn't IBM"™ - @notessensai

Offline Axel

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 8.658
  • Geschlecht: Männlich
  • It's not a bug, it's Notes
Re: Collection sortieren?
« Antwort #3 am: 21.06.05 - 10:43:43 »
Hi,

ich habe mir mal in grauer Vorzeit was aus dem Web gefischt.

Zitat
Since getting having an unsorted DocumentCollection is generally a pain, I've
written some code that's pretty quick in sorting these documents on the fly.
This uses a QuickSort algorithm, instead of the much slower bubble sorts that
seem to be floating out here...

I actually borrowed the CollectionToArray code from this board a while back,
but it also used a bubble sort routine that was way too slow.

This code should be able to be used as is. I've used this method in several
DB's with no changes since the initial write. The only thing you should have
to change is the variable which tells it which field to sort on (explained
below)...

Sub CollectionToArray ( dc As NotesDocumentCollection)

Dim doc As NotesDocument
Dim k As Long
k = dc.Count
If k<>0 Then
Redim da( 1 To k+1) As NotesDocument
Set doc = dc.GetFirstDocument
For i=1 To k
Set da(i) = doc
Set doc = dc.GetNextDocument(doc)
Next
End If

'Need to add a value at the end that will always be greater than all
other values
Set da(k+1) = dirDB.CreateDocument
da(k+1).Lastname = "ZZZZZZZZ"

End Sub

Function swap(i As Integer,j As Integer) As Variant
Dim temp As NotesDocument

Set temp = da(i)
Set da(i) = da(j)
Set da(j) = temp

End Function

Sub QuickSort (leftpos As Integer, rightpos As Integer)
Dim i As Integer
Dim j As Integer
Dim pivot As String
If (leftpos < rightpos) Then
i=leftpos
j=rightpos + 1
pivot =
da(leftpos).GetFirstItem(key).Text
Do
Do
i=i+1
Loop While da(i).GetFirstItem(key).Text<pivot And
i<=rightpos
Do
j=j-1
Loop While da(j).GetFirstItem(key).Text > pivot And
j>=leftpos
If (i<j) Then
Call swap(i, j)
End If
Loop While (i<j)
Call swap(leftpos,j)
Call QuickSort(leftpos,j-1)
Call QuickSort(j+1,rightpos)
End If

End Sub

These need to be public variables, so place them in your "Declarations":

Dim s As NotesSession
Dim db As NotesDatabase 'The current database
Dim da As Variant
Const key = "LastName" 'This the name of the FIELD you want to sort on

Now, how to use this stuff...

In your Initialize, or wherever you're calling this from:
1) Get your DocumentCollection (here: dc)
2) Call CollectionToArray(dc) 'just creates an array of your documents so that
we can re-order them
3) Call QuickSort(Lbound(da), Ubound(da)-1) 'actually sorts your documents
4) Redim Preserve da( 1 To Ubound(da)-1) As NotesDocument 'just chops off the
'ZZZZZ' value we needed as a 'high' value (see CollectionToArray routine)
5) Forall doc In da ... End ForAll 'Use this to loop through your sorted
documents

Remember, the DocumentArray (da) is just an array of documents, so you can
reference the 'doc' in your ForAll and any of it's properties, fields, etc.
just like any other document.

Let me know if you have any problems, or just to let me know you found this
useful...


Das habe ich in ein paar DBs schon verwendet. Läuft bisher ohne Probleme.

Axel
Ohne Computer wären wir noch lange nicht hinterm Mond!

Offline diali

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.023
  • Geschlecht: Männlich
Re: Collection sortieren?
« Antwort #4 am: 21.06.05 - 10:43:58 »
Set notesDocumentCollection = notesDatabase.Search( formula$, notesDateTime, maxDocs% ), da kannst Du nix sortieren (ist aber glaube ich nach dem Erstelldatum sortiert).

Sortieren kannst Du auch nur einen FTSearch in NotesDatabase.

Gruß
Dirk
Gruß
Dirk

Offline Axel

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 8.658
  • Geschlecht: Männlich
  • It's not a bug, it's Notes
Re: Collection sortieren?
« Antwort #5 am: 21.06.05 - 10:47:19 »
Bist Du Dir sicher, dass es nicht sortiert ist (nach irgendeiner obskuren Sortierregel)? Weil die Notes-Hilfe meint, dass Ergebnisse einer Suche sehr wohl sortiert sind.

Zitat
IsSorted property 
Read-only. Indicates whether the documents in a collection are sorted. A collection is sorted only when it results from a full-text search of a database.

Das sind die Sortieroptionen einer Volltextsuche.

Zitat
FT_DATE_ASC (64) sorts by document date in ascending order.
FT_DATE_DES (32) sorts by document date in descending order.
FT_DATECREATED_ASC (1543) sorts by document creation date in ascending order.
FT_DATECREATED_DES (1542) sorts by document creation date in descending order.
FT_SCORES (8) sorts by relevance score (default).

In der Regel sind die aber nicht zu gebrauchen.

Axel
Ohne Computer wären wir noch lange nicht hinterm Mond!

Offline Spalter

  • Aktives Mitglied
  • ***
  • Beiträge: 109
  • Mit der Lizenz zum Löschen!!!
Re: Collection sortieren?
« Antwort #6 am: 21.06.05 - 10:54:35 »
Hi,

ich habe mir mal in grauer Vorzeit was aus dem Web gefischt.

Zitat
Since getting having an unsorted DocumentCollection is generally a pain, I've
written some code that's pretty quick in sorting these documents on the fly.
This uses a QuickSort algorithm, instead of the much slower bubble sorts that
seem to be floating out here...

I actually borrowed the CollectionToArray code from this board a while back,
but it also used a bubble sort routine that was way too slow.

This code should be able to be used as is. I've used this method in several
DB's with no changes since the initial write. The only thing you should have
to change is the variable which tells it which field to sort on (explained
below)...

Sub CollectionToArray ( dc As NotesDocumentCollection)

Dim doc As NotesDocument
Dim k As Long
k = dc.Count
If k<>0 Then
Redim da( 1 To k+1) As NotesDocument
Set doc = dc.GetFirstDocument
For i=1 To k
Set da(i) = doc
Set doc = dc.GetNextDocument(doc)
Next
End If

'Need to add a value at the end that will always be greater than all
other values
Set da(k+1) = dirDB.CreateDocument
da(k+1).Lastname = "ZZZZZZZZ"

End Sub

Function swap(i As Integer,j As Integer) As Variant
Dim temp As NotesDocument

Set temp = da(i)
Set da(i) = da(j)
Set da(j) = temp

End Function

Sub QuickSort (leftpos As Integer, rightpos As Integer)
Dim i As Integer
Dim j As Integer
Dim pivot As String
If (leftpos < rightpos) Then
i=leftpos
j=rightpos + 1
pivot =
da(leftpos).GetFirstItem(key).Text
Do
Do
i=i+1
Loop While da(i).GetFirstItem(key).Text<pivot And
i<=rightpos
Do
j=j-1
Loop While da(j).GetFirstItem(key).Text > pivot And
j>=leftpos
If (i<j) Then
Call swap(i, j)
End If
Loop While (i<j)
Call swap(leftpos,j)
Call QuickSort(leftpos,j-1)
Call QuickSort(j+1,rightpos)
End If

End Sub

These need to be public variables, so place them in your "Declarations":

Dim s As NotesSession
Dim db As NotesDatabase 'The current database
Dim da As Variant
Const key = "LastName" 'This the name of the FIELD you want to sort on

Now, how to use this stuff...

In your Initialize, or wherever you're calling this from:
1) Get your DocumentCollection (here: dc)
2) Call CollectionToArray(dc) 'just creates an array of your documents so that
we can re-order them
3) Call QuickSort(Lbound(da), Ubound(da)-1) 'actually sorts your documents
4) Redim Preserve da( 1 To Ubound(da)-1) As NotesDocument 'just chops off the
'ZZZZZ' value we needed as a 'high' value (see CollectionToArray routine)
5) Forall doc In da ... End ForAll 'Use this to loop through your sorted
documents

Remember, the DocumentArray (da) is just an array of documents, so you can
reference the 'doc' in your ForAll and any of it's properties, fields, etc.
just like any other document.

Let me know if you have any problems, or just to let me know you found this
useful...


Das habe ich in ein paar DBs schon verwendet. Läuft bisher ohne Probleme.

Axel

Hallo Axel,
Danke für die schnelle Antwort. Werde ich testen.

Gruß
Spalter  :)

Offline m3

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 8.102
  • Geschlecht: Männlich
  • Non ex transverso sed deorsum!
    • leyrers online pamphlet
Re: Collection sortieren?
« Antwort #7 am: 21.06.05 - 10:57:31 »
Bist Du Dir sicher, dass es nicht sortiert ist (nach irgendeiner obskuren Sortierregel)? Weil die Notes-Hilfe meint, dass Ergebnisse einer Suche sehr wohl sortiert sind.

Zitat
IsSorted property 
Read-only. Indicates whether the documents in a collection are sorted. A collection is sorted only when it results from a full-text search of a database.

Das sind die Sortieroptionen einer Volltextsuche.

Zitat
FT_DATE_ASC (64) sorts by document date in ascending order.
FT_DATE_DES (32) sorts by document date in descending order.
FT_DATECREATED_ASC (1543) sorts by document creation date in ascending order.
FT_DATECREATED_DES (1542) sorts by document creation date in descending order.
FT_SCORES (8) sorts by relevance score (default).

In der Regel sind die aber nicht zu gebrauchen.

Axel

OK, soweit hab ich nicht mehr weitergelesen. Sind absolut unbrauchbar. Danke für die Info.
HTH
m³ aka. Martin -- leyrers online pamphlet | LEYON - All things Lotus (IBM Collaborations Solutions)

All programs evolve until they can send email.
Except Microsoft Exchange.
    - Memorable Quotes from Alt.Sysadmin.Recovery

"Lotus Notes ist wie ein Badezimmer, geht ohne Kacheln, aber nicht so gut." -- Peter Klett

"If there isn't at least a handful of solutions for any given problem, it isn't IBM"™ - @notessensai

Offline Spalter

  • Aktives Mitglied
  • ***
  • Beiträge: 109
  • Mit der Lizenz zum Löschen!!!
Re: Collection sortieren?
« Antwort #8 am: 21.06.05 - 10:59:28 »
Hallo,

Danke für die schnellen Antworten, auch an Dirk für den Tip mit dem Array.

Gruß
Spalter  :D

Offline Spalter

  • Aktives Mitglied
  • ***
  • Beiträge: 109
  • Mit der Lizenz zum Löschen!!!
Re: Collection sortieren?
« Antwort #9 am: 21.06.05 - 11:59:32 »
Hi,

ich habe mir mal in grauer Vorzeit was aus dem Web gefischt.

Zitat
Since getting having an unsorted DocumentCollection is generally a pain, I've
written some code that's pretty quick in sorting these documents on the fly.
This uses a QuickSort algorithm, instead of the much slower bubble sorts that
seem to be floating out here...

I actually borrowed the CollectionToArray code from this board a while back,
but it also used a bubble sort routine that was way too slow.

This code should be able to be used as is. I've used this method in several
DB's with no changes since the initial write. The only thing you should have
to change is the variable which tells it which field to sort on (explained
below)...

Sub CollectionToArray ( dc As NotesDocumentCollection)

Dim doc As NotesDocument
Dim k As Long
k = dc.Count
If k<>0 Then
Redim da( 1 To k+1) As NotesDocument
Set doc = dc.GetFirstDocument
For i=1 To k
Set da(i) = doc
Set doc = dc.GetNextDocument(doc)
Next
End If

'Need to add a value at the end that will always be greater than all
other values
Set da(k+1) = dirDB.CreateDocument
da(k+1).Lastname = "ZZZZZZZZ"

End Sub

Function swap(i As Integer,j As Integer) As Variant
Dim temp As NotesDocument

Set temp = da(i)
Set da(i) = da(j)
Set da(j) = temp

End Function

Sub QuickSort (leftpos As Integer, rightpos As Integer)
Dim i As Integer
Dim j As Integer
Dim pivot As String
If (leftpos < rightpos) Then
i=leftpos
j=rightpos + 1
pivot =
da(leftpos).GetFirstItem(key).Text
Do
Do
i=i+1
Loop While da(i).GetFirstItem(key).Text<pivot And
i<=rightpos
Do
j=j-1
Loop While da(j).GetFirstItem(key).Text > pivot And
j>=leftpos
If (i<j) Then
Call swap(i, j)
End If
Loop While (i<j)
Call swap(leftpos,j)
Call QuickSort(leftpos,j-1)
Call QuickSort(j+1,rightpos)
End If

End Sub

These need to be public variables, so place them in your "Declarations":

Dim s As NotesSession
Dim db As NotesDatabase 'The current database
Dim da As Variant
Const key = "LastName" 'This the name of the FIELD you want to sort on

Now, how to use this stuff...

In your Initialize, or wherever you're calling this from:
1) Get your DocumentCollection (here: dc)
2) Call CollectionToArray(dc) 'just creates an array of your documents so that
we can re-order them
3) Call QuickSort(Lbound(da), Ubound(da)-1) 'actually sorts your documents
4) Redim Preserve da( 1 To Ubound(da)-1) As NotesDocument 'just chops off the
'ZZZZZ' value we needed as a 'high' value (see CollectionToArray routine)
5) Forall doc In da ... End ForAll 'Use this to loop through your sorted
documents

Remember, the DocumentArray (da) is just an array of documents, so you can
reference the 'doc' in your ForAll and any of it's properties, fields, etc.
just like any other document.

Let me know if you have any problems, or just to let me know you found this
useful...


Das habe ich in ein paar DBs schon verwendet. Läuft bisher ohne Probleme.

Axel

Hallo Axel,

eine Frage noch. Habe die Subs schon mal in den Agenten kopiert. Bei dem Quicksort kommt bei

pivot = da(i).GetFirstItem(key).Text

die Fehlermeldung

Illegal parenthesized reference: DA

Kanns Du mir noch einen Tip geben.

PS: Habe einfach die Sub reinkopiert und noch nicht eingebunden.

Gruß
Spalter   :-[


Offline Axel

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 8.658
  • Geschlecht: Männlich
  • It's not a bug, it's Notes
Re: Collection sortieren?
« Antwort #10 am: 21.06.05 - 13:07:57 »
Hi,

die globalen Variablen hast du in den Declarations-Abschnitt übernommen, oder?

Wo soll den in QuickSort diese Zeile sein? Die finde ich nicht. Da gibt's nur diese:

Code
pivot = da(leftpos).GetFirstItem(key).Text 


Axel
Ohne Computer wären wir noch lange nicht hinterm Mond!

Offline Spalter

  • Aktives Mitglied
  • ***
  • Beiträge: 109
  • Mit der Lizenz zum Löschen!!!
Re: Collection sortieren?
« Antwort #11 am: 21.06.05 - 14:27:32 »
Sorry Axel,

in der Hektitk habe ich wohl was falsch gemacht. Du hast recht. habe jetzt auch die Declarations eingebaut.

Versuche das jetzt noch auf ein numerisches Feld umzubauen.

Gruß
Spalter :-\

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz