Newsgroup: it.comp.lang.visual-basic
Titolo: Migliorare ricerca collection VB6

Ciao a tutti,
ho una collection che pu� arrivare a contenere circa 10/15mila elementi,
ordinati.
Ogni elemento � una classe del tipo
-IDArticolo
-CodLotto
-Quantit�
Devo scorrere la collection e vedere se per quell'articolo e per quel lotto
ho una quantit� disponibile.
Ora gli articoli magari vanno da 1 a 85mila.
Nella bozza sto facendo cos�:
Private sub Ricerca (IDArticolo as Long, Lotto as String)
    For Each oLotto In mCol
        If oLotto.IDArticolo = IDArticolo Then
            If oLotto.Lotto = Lotto Then
		'varie operazioni
            End If
        Else
            ' vuol dire che ho scorso tutto l'elenco di quell'articolo
            If oLotto.IDArticolo > IDArticolo Then Exit For
        End If
    Next
End Sub
Se ricerco un articolo ID=80mila (vicino al MaxID), � inutile che scorra
dal primo elemento, � facile che si trovi verso la fine.
Tutto si risolverebbe se impongo che IDArticolo+Lotto sia "primary key",
cos� facendo aggiungerei gli elementi con una key tipo
Cstr(IDArticolo|Lotto), e recupererei l'elemento senza scansioni.
In questo caso potrei anche farlo, forse, ma altrimenti?
Avevo pensato ad un array che memorizzasse le posizioni in migliaia
Array(1)= Indice del primo elemento IDArticol>=1000
array(2)= Indice del primo elemento IDArticol>=2000
Cos� facendo, dato un IDArticolo so che lo devo ricercare fra un minimo e
massimo ristretto. In questo caso non potrei per� usare il pi� performante
For Each ma un ciclo for normale.
Se cerco ID=3523 devo fare
For i=array(3) to array(4)
   'scansioni elementi con ID da 3000 a 4000
Next
Grazie a tutti

"Andrea [Work]" <andrea.isw...@gmail.invalid> ha scritto nel 
messaggio news:10goi046gv7mo.1ekvvqct1nr4$.dlg@40tude.net...

Se per collection ordinata intendi che gli elementi sono in ordine 
progressivo di IDArticolo e, a parit� di IDArticolo, in ordine progressivo 
di CodLotto, allora dovrebbe essere pi� veloce la ricerca fatta dimezzando 
progressivamente gli intervalli di ricerca.
Private sub Ricerca (IDArticolo as Long, Lotto as String)
    Dim L1 as Long,L2 as long, n as Long
    L1 = 1
    L2 = mCol.count
    Do
        n = (L2 - L1 + 1) \ 2
        If mCol(n).IDArticolo = IDArticolo and mCol(n).Lotto = Lotto Then
            'fai quello che ti pare
        ElseIf mCol(n).IDArticolo = IDArticolo < IDArticolo) or _
            (mCol(n).IDArticolo = IDArticolo and mCol(n).Lotto < Lotto) Then
            L1 = n
        Else
            L2 = n
        End If
        If L1 > L2 Then
            'L'elemento non � presente nella collection
            Exit Do
        End If
    Loop
End Sub
Con 15000 elementi nella collection, dovrai testare al massimo 15 elementi.
Ho scritto direttamente qui senza testare la routine (e non sono sicuro 
neppure della sintassi) ma, come metodo, penso sia quello pi� veloce.
Ciao.
E.

 E.
Un paio di rettifiche... :-(

 Un paio di rettifiche... :-(
Tnx, ora vedo se funziona bene anche in caso di duplicati, perch� per
assurdo potrei avere due righe
Art=10
Lotto=AAA1
In quel caso potrebbe essere il precedente o il successivo.
Oppure per stavolta sommo i lotti+art uguali e indicizzo l'elemento della
collection, cos� lo recupero subito.

 collection, cos� lo recupero subito.
Ho fatto come sopra. Old � la routine che cicla, New � quella che prende
l'item, espressi in seconds. Ricercavo gli articoli da 1 a MAX variabile:
1.000 iteration
 - New:-9,6875E-04
 - Old:1,503125E-02
5.000 iteration
 - New:1,490625E-02
 - Old:0,1242812
10.000 iteration
 - New:0,0466875
 - Old:0,2498125
50.000 iteration
 - New:0,2324062
 - Old:126,2829
100.000 iteration
 - New:0,4865625
1.000.000 iteration
 - New:4,720562