Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Treeview - Popolamento e tempistica

Salve a tutti
Ho una tabella che contiene gli indirizzo di utenti ed io vorrei preparare
una struttura ad albero contenente l'indirizzo ed il numero di utenti per
indirizzo, nel nodo figlio raggruppare il civico per quell'indirizzo ed il
numero di utenti per civico.
Di seguito è riportato il codice per fare questo, ma considerando che l'ho
verificato su circa 30.000 utenti, il mio pentium II 233 ci impiega circa 45
ss per caricarlo. Mi sembra un pochino troppo.
Esiste un modo diverso che velocizzi il popolamento della Treeview?
Questo avviene nell'evento load della form:
Dim rscarico As New ADODB.Recordset
Dim cat As New ADOX.Catalog
Dim tbl As New ADOX.Table
Dim tvcarico As Node
Dim tvindi As Node
Dim rsletturista As New ADODB.Recordset
Dim rscivico As New ADODB.Recordset
cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &
App.Path & "\struttura.mdb;Mode=ReadWrite;Persist Security Info=False"
cn.Open
cat.ActiveConnection = cn.ConnectionString
rsletturista.Open "select id_letturista,nominativo from letturisti", cn,
adOpenStatic, adLockReadOnly, adCmdText
cboletturista.AddItem ""
Do Until rsletturista.EOF
    cboletturista.AddItem Format(rsletturista.Fields(0), "00") & " - " &
rsletturista.Fields(1)
    rsletturista.MoveNext
Loop
For Each tbl In cat.Tables
    If UCase(Mid(tbl.Name, 1, 2)) = "CB" Then
        Set tvcarico = tv.Nodes.Add(, , tbl.Name, tbl.Name & " - " &
tbl.DateCreated)
        tvcarico.Bold = True
        rscarico.Open "select indirizzo,count(utenza),assegnata from " &
tbl.Name & " where isnull(lettura) group by indirizzo,assegnata", cn,
adOpenStatic, adLockReadOnly, adCmdText
        Do Until rscarico.EOF
            Set tvindi = tv.Nodes.Add(tvcarico.Key, tvwChild,
rscarico.Fields(0) & tvcarico.Key, rscarico.Fields(0) & " - " &
rscarico.Fields(1))
            rscivico.Open "select civico,count(utenza) as utenze from " &
tbl.Name & " where indirizzo=""" & rscarico.Fields(0) & """ group by civico
order by civico", cn, adOpenStatic, adLockReadOnly, adCmdText
            If rscarico.Fields(2) = -1 Then
                tvindi.Bold = True
            End If
            Do Until rscivico.EOF
                tv.Nodes.Add tvindi.Key, tvwChild, tvindi.Key &
rscivico.Fields(0), rscivico.Fields(0) & " - " & rscivico.Fields(1)
                rscivico.MoveNext
            Loop
            rscarico.MoveNext
            rscivico.Close
        Loop
        rscarico.Close
        tvcarico.Expanded = True
    End If
Next tbl
Ciao
Fabio

 ss per caricarlo. Mi sembra un pochino troppo.
Non ho letto attentissimamente il codice da te proposto, ma mi sembra che
carichi in memoria tutti gli elementi all'inizio.
Una soluzione per velocizzare il tutto, in questo caso, sarebbe quella di
raccogliere solo i gruppi, e poi raccogliere i singoli utenti del gruppo
quando l'utilizzatore apre il ramo associato
Salutoni
Sergio

 carichi in memoria tutti gli elementi all'inizio.
[SNIP]
Infatti... oltretutto da quello che si vede hai parecchi loop innestati con
relative select interne, da cui deriva una classica "scartavetrata" di
accessi al DB che, treeview a parte, gia' di suo non e' il massimo
dell'efficienza.
Una grande possibilita' che ti offre il TreeView e' proprio quella suggerita
da Sergio, cioe' di poter separare in varie fasi il caricamento dei dati,
sfruttando in particolare l'evento Expand.
E' sufficiente solo un piccolo accorgimento, un flag a tua scelta, per
evitare di ricaricare un nodo gia' visitato e per il resto il meccanismo e'
molto semplice e efficace.
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

 ha scritto nel messaggio
news:amp7ib$7rl11$1...@ID-138791.news.dfncis.de...

Non ci avevo pensato, attuo e verifico.
Grazie per l'immancabile aiuto.
Ciao
Fabio

 Esiste un modo diverso che velocizzi il popolamento della Treeview?
Se TV č, come penso, della stessa "pasta" di ListView, (a parte i tempi
"tecnici" per leggere i dati da inserire) prova a rendere invisibile il
controllo prima del suo popolamento e a visualizzarlo solo alla fine.

 ha scritto nel messaggio
news:amp7ib$7rl11$1...@ID-138791.news.dfncis.de...

Tuttavia se nella treeview faccio comparire solo l'indirizzo, come faccio a
far visualizzare il + per espandere il ramo e iniziare l'evento?
Ciao
fabio

 ha scritto nel messaggio
news:sPVj9.3483$e31....@twister2.libero.it...

Mi spieghi dove potrebbe essere la diffeenza?
Ciao
Fabio

 Mi spieghi dove potrebbe essere la diffeenza?
No, non riesco a spiegartelo (se non pensando agli adeguamenti grafici
connessi al popolamentoI, ma prova a popolare una ListView visibile con un
tot di dati.
Fai la stessa prova (identica) con la ListView invisibile (insolla, la rendi
visibile solo alla fine)

 far visualizzare il + per espandere il ramo e iniziare l'evento?
Ogni volta che carichi un nodo di primo livello aggiungi subito anche un
nodo figlio "finto" che puoi contrassegnare con una costante nella property
tag (intendo quella del singolo Node, non del Tree)
A questo punto hai il tuo '+' e nell'evento Expand puoi verificare che, se
Node.Children > 0 e il primo nonche' unico Node.Child.Tag e' uguale alla tua
costante, allora questo nodo non e' ancora stato visitato; puoi quindi
rimuovere il nodo fasullo (nei prossimi Expand non verra' fatto quindi piu'
nulla) e passare a caricare e inserire gli elementi figli reali; qui puoi
anche ripetere la procedura suddetta per i livelli successivi
Ciao
P.S.
qualcun altro te lo fara' notare sicuramente... dovresti stare un po' piu'
attento a come "quoti" i messaggi, cioe' a riportare possibilmente non tutto
il testo nelle risposte ma solo le parti salienti



Ci avevo pensato, ma credevo ci fosse un'altra soluzione forse più elegante.
Comunque grazie di nuovo.
Ciao
Fabio


Ti ringrazio.
Con la mole di dati che ho č facile evidenziare le differenze.
Ciao
Fabio

Elucubravo in letizia, quando udii Fabio sostenere...

Potresti provare con:
1) Mettere la treeview invisibile;
2) Aprire il recordset in modalita' adForwardOnly;
3) Al posto di rscarico.Fields(...), definisci delle variabili di tipo 
ADODB.Fields, ed usa quelle;
4) Al posto dei cicli DO UNTIL rs.EOF ... rs.MOVENEXT LOOP, prova a 
calcolarti il numero di record, e fdare un ciclo FOR...NEXT
5) (stupida) metti tvcarico.Key in una variabile...
6) (stupida) idem per tbl.name...
-- 
Bye by SixaM 8-]
---------------------
Sito comune: 
www.it-lang-vb.com