Utilizzo proprietà groups in listview

lunedì 15 febbraio 2010 - 10.23

save2004 Profilo | Newbie

Buongiorno a tutti, ho questo problema:
ho un albero di 4 livelli che rappresenta il WBS del mio lavoro (centri di costo); per ciascun centro di costo di quest'albero io voglio elencare in un listview tutti i contratti emessi; quindi ad esempio per il centro di costo relativo alle opere strutturali/fornitura di cls vorrei che si vedessero i contratti stipulati con i nostri subappaltatori (ragione sociale, numero ordine, descrizione, quantità, prezzo e importo).
Quello che mi piacerebbe fare sarebbe utilizzare la proprietà groups per raggruppare i contratti di uno stesso centro di costo; quindi vorrei la classica linea orizzontale, il gruppo lo chiamo proprio con i codici del WBS (04.16.04 STRU-CA-002) e sotto i relativi contratti... il tutto per tutti i centri di costo.
Questo è il codice che ho scritto relativo al click del pulsante "ordinato":

Listordinato.Clear()
Listordinato.Groups.Clear()
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim y As Integer
Dim x As Integer = 0
Dim indice As Integer = 0
Dim capitolato As String
Dim importo As Double
Dim importo1 As Double
importo1 = 0
Dim dal As String
Dim al As String

Dim zero As Integer
zero = 0

dal = Mid(dtdal.Text, 7, 4) & Mid(dtdal.Text, 4, 2) & Mid(dtdal.Text, 1, 2)
al = Mid(dtal.Text, 7, 4) & Mid(dtal.Text, 4, 2) & Mid(dtal.Text, 1, 2)

If CInt(dal) >= CInt(al) Then
MsgBox("Il range di date scelto non è valido!", MsgBoxStyle.Exclamation, "Attenzione!")
Exit Sub
End If

cn = New ADODB.Connection
rs = New ADODB.Recordset

cn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=nuovo.mdb; Persist Security Info=False")

'scorro il primo livello
For i = 0 To TreeView1.Nodes.Count - 1
ToolStripProgressBar1.Minimum = 0
ToolStripProgressBar1.Maximum = TreeView1.Nodes.Count - 1
ToolStripProgressBar1.Value = i

'scorro il secondo livello
For j = 0 To TreeView1.Nodes(i).Nodes.Count - 1
'scorro il terzo livello
For k = 0 To TreeView1.Nodes(i).Nodes(j).Nodes.Count - 1
If TreeView1.Nodes(i).Nodes(j).Nodes(k).Nodes.Count <> 0 Then
'scorro il quarto livello
For y = 0 To TreeView1.Nodes(i).Nodes(j).Nodes(k).Nodes.Count - 1
importo = 0
s1 = Split(TreeView1.Nodes(i).Text, " ")
s2 = Split(TreeView1.Nodes(i).Nodes(j).Text, " ")
s3 = Split(TreeView1.Nodes(i).Nodes(j).Nodes(k).Text, " ")
capitolato = TreeView1.Nodes(i).Nodes(j).Nodes(k).Nodes(y).Text

rs.Open("SELECT fornitori.ragionesociale, GSD70COL_GOFRI00F.ORNUM, " _
& "GSD70COL_GOFRI00F.ORANN, GSD70COL_GOFRI00F.ORDES, GSD70COL_GOFRI00F.ORDE2, " _
& "GSD70COL_GOFRI00F.ORQTA, GSD70COL_GOFRI00F.ORCOS" _
& " FROM fornitori INNER JOIN GSD70COL_GOFRI00F" _
& " ON (fornitori.codice = GSD70COL_GOFRI00F.ORFOR) WHERE" _
& " ORAZI LIKE '" & filtro & "' AND" _
& " ORCOM LIKE '%" & cmbcommessa.Text & "%' AND" _
& " ORCAN LIKE '%" & cmbcant.Text & "%' AND" _
& " ORLI2 LIKE '%" & s1(0) & "%' AND" _
& " ORLI3 LIKE '%" & s2(0) & "%' AND" _
& " ORLI4 LIKE '%" & s3(0) & "%' AND" _
& " ORCAP LIKE '%" & capitolato & "%' AND" _
& " ORDTX >= " & dal & " AND" _
& " ORDTX <= " & al & " ", cn, 1)


'ListView2.Groups.Add(New ListViewGroup("" & s1(0) & "." & s2(0) & "." _
' & s3(0) & " " & capitolato & " ", HorizontalAlignment.Left))


While rs.EOF = False
If rs.Fields("ORQTA").Value = zero Then
importo = importo + rs.Fields("ORCOS").Value
Else
importo = importo + (rs.Fields("ORQTA").Value * rs.Fields("ORCOS").Value)
End If


With Listordinato.Items.Add(rs.Fields("ragionesociale").Value)
.SubItems.add((Mid(rs.Fields("ORANN").Value, 3, 2) & "/" & rs.Fields("ORNUM").Value))
.SubItems.add(Trim(rs.Fields("ORDES").Value) & Trim(rs.Fields("ORDE2").Value))
.subitems.add(FormatNumber(rs.Fields("ORQTA").Value))
.subitems.add(FormatNumber(rs.Fields("ORCOS").Value))
If rs.Fields("ORQTA").Value = zero Then
.subitems.add(FormatNumber(rs.Fields("ORCOS").Value))
Else
.subitems.add(FormatNumber(rs.Fields("ORQTA").Value * rs.Fields("ORCOS").Value))
End If
End With
'ListView2.Items.Item(rs.AbsolutePosition) = ListView2.Groups(y)

rs.MoveNext()
End While

'ListView2.Groups.Add(New ListViewGroup("" & s1(0) & "." & s2(0) & "." _
' & s3(0) & " " & capitolato & " (" & FormatNumber(importo) & ")", HorizontalAlignment.Left))
'indice = ListView2.Groups

'For x = 0 To rs.RecordCount
'ListView2.Items.Item(x).Group = ListView2.Groups(0)
'Next

rs.Close()

Next
End If
Next
Next
Next

cn.Close()
ToolStripProgressBar1.Value = 0

Come faccio a creare il gruppo e ad assegnargli i record trovati? Come potete vedere ho provato a scrivere qualcosa in merito (l'ho lasciato commentato...)
Allego un'immagine del Form che ho creato per maggiore chiarezza...

923x583 154Kb


Ringrazio chiunque voglia gentilmente rispondermi e aiutarmi!!!!

Saverio

AntCiar Profilo | Expert

Ciao.

DAi una occhiata all'allegato. E' fatto in VB con versione VS 2005

Ciao
Cristian Barca

save2004 Profilo | Newbie

Grazie mille per la risposta!!!!
Più o meno è la stessa strada che sto seguendo questa mattina.... dopo aver scritto qui, ho continuato a fare delle prove; ecco il nuovo codice che ho scritto:

'scorro il primo livello
For i = 0 To TreeView1.Nodes.Count - 1
ToolStripProgressBar1.Minimum = 0
ToolStripProgressBar1.Maximum = TreeView1.Nodes.Count - 1
ToolStripProgressBar1.Value = i

'scorro il secondo livello
For j = 0 To TreeView1.Nodes(i).Nodes.Count - 1
'scorro il terzo livello
For k = 0 To TreeView1.Nodes(i).Nodes(j).Nodes.Count - 1
If TreeView1.Nodes(i).Nodes(j).Nodes(k).Nodes.Count <> 0 Then
'scorro il quarto livello
For y = 0 To TreeView1.Nodes(i).Nodes(j).Nodes(k).Nodes.Count - 1
importo = 0
s1 = Split(TreeView1.Nodes(i).Text, " ")
s2 = Split(TreeView1.Nodes(i).Nodes(j).Text, " ")
s3 = Split(TreeView1.Nodes(i).Nodes(j).Nodes(k).Text, " ")
capitolato = TreeView1.Nodes(i).Nodes(j).Nodes(k).Nodes(y).Text

rs.Open("SELECT fornitori.ragionesociale, GSD70COL_GOFRI00F.ORNUM, " _
& "GSD70COL_GOFRI00F.ORANN, GSD70COL_GOFRI00F.ORDES, GSD70COL_GOFRI00F.ORDE2, " _
& "GSD70COL_GOFRI00F.ORQTA, GSD70COL_GOFRI00F.ORCOS" _
& " FROM fornitori INNER JOIN (GSD70COL_GOFRI00F INNER JOIN GSD70COL_GOFTE00F " _
& " ON (GSD70COL_GOFRI00F.ORANN = GSD70COL_GOFTE00F.OTANN AND " _
& " GSD70COL_GOFRI00F.ORNUM = GSD70COL_GOFTE00F.OTNUM)) " _
& " ON (fornitori.codice = GSD70COL_GOFRI00F.ORFOR) WHERE" _
& " ORAZI LIKE '" & filtro & "' AND" _
& " ORCOM LIKE '%" & cmbcommessa.Text & "%' AND" _
& " ORCAN LIKE '%" & cmbcant.Text & "%' AND" _
& " ORLI2 LIKE '%" & s1(0) & "%' AND" _
& " ORLI3 LIKE '%" & s2(0) & "%' AND" _
& " ORLI4 LIKE '%" & s3(0) & "%' AND" _
& " ORCAP LIKE '%" & capitolato & "%' AND" _
& " OTDAT >= " & dal & " AND" _
& " OTDAT <= " & al & " ", cn, 1)

If rs.RecordCount <> 0 Then

MsgBox("numero di record trovati " & rs.RecordCount & " WBS " & s1(0) & "." & s2(0) & "." & s3(0) & " " & capitolato)
While rs.EOF = False
If rs.Fields("ORQTA").Value = zero Then
importo = importo + rs.Fields("ORCOS").Value
Else
importo = importo + (rs.Fields("ORQTA").Value * rs.Fields("ORCOS").Value)
End If
With Listordinato.Items.Add(rs.Fields("ragionesociale").Value)
.SubItems.add((Mid(rs.Fields("ORANN").Value, 3, 2) & "/" & rs.Fields("ORNUM").Value))
.SubItems.add(Trim(rs.Fields("ORDES").Value) & Trim(rs.Fields("ORDE2").Value))
.subitems.add(FormatNumber(rs.Fields("ORQTA").Value))
.subitems.add(FormatNumber(rs.Fields("ORCOS").Value))
If rs.Fields("ORQTA").Value = zero Then
.subitems.add(FormatNumber(rs.Fields("ORCOS").Value))
Else
.subitems.add(FormatNumber(rs.Fields("ORQTA").Value * rs.Fields("ORCOS").Value))
End If
End With

rs.MoveNext()
End While

Listordinato.Groups.Add(New ListViewGroup("" & s1(0) & "." & s2(0) & "." _
& s3(0) & " " & capitolato & " " & "(" & importo & ")", HorizontalAlignment.Left))

indice = Listordinato.Groups.Count - 1

'assegno gli elementi trovati al gruppo di pertinenza
valore = CInt(Listordinato.Items(Listordinato.Items.Count - 1).Index) - 1
MsgBox("valore = " & valore)
MsgBox("raggruppo dal record " & valore & " al record " & valore + rs.RecordCount - 1)
For x = valore To (valore + rs.RecordCount - 1)
Listordinato.Items.Item(x).Group = Listordinato.Groups(indice)
Next

End If
rs.Close()
Next
End If
Next
Next
Next

cn.Close()
ToolStripProgressBar1.Value = 0

In questo modo riesco a creare dinamicamente i gruppi con le giuste intestazioni e ad assegnare i relativi elementi (allego immagine durante l'esecuzione).
Non capisco perché l'ultimo ciclo FOR (di assegnazione delle righe al gruppo di pertinenza) funzioni solo fino ad un certo punto, poi mi dà errore sull'indice x......
e inoltre, come si vede dall'immagine allegata, mi spariscono le intestazioni di colonna del listview e non si leggono le righe assegnate ai gruppi (eppure dai vari controlli che ho inserito - msgbox - i record trovati e da assegnare ai gruppi sono giusti!!!)

Grazie mille per qualsiasi aiuto vogliate darmi!!!

Saverio

923x584 49Kb

AntCiar Profilo | Expert

Ciao.

Dal codice che hai scritto presumo vieni dal VBA di ACCESS. Se posso darti un consiglio, scordati il modo di programmare in Access altrimenti bestemmierai in turco!!!

Venendo al codice che hai scritto, in sostanza tu crei prima gli elementi senza gruppo, poi il gruppo e poi scorri gli elementi creati per associarli al gruppo. Io farei in un altro modo:

creo il gruppo dandogli come testo la stringa vuota (perchè importo in questo caso non è ancora calcolato) e lo associo ad una variabile di tipo ListViewGroup.

Poi creo ogni singolo elemento e gli associo come gruppo la variabile. Al termine del ciclo di creazione degli elementi, dopo che importo è stato valorizzato, aggiorno il text del Gruppo tramite la variabile.

In questo modo è un ragionamento più lineare e manutenibile. Poi vorrei darti un altro consiglio. Non so in che modo crei il tuo TreeView ma ho notato che per ogni nodo accedi alla proprietà "text" per ricavarti i dati che a te servono. Io farei diversamente. Nella proprietà "Tag" di ogni nodo, in fase di costruzione dell'albero, assocerei un oggetto (stringa, dataRow o altro) contenente tutto quello che mi serve. Questo perchè se un domani ti viene chiesto di cambiare il testo visualizzato nel nodo, non dovrai mettere mano a tutto il resto.

Ciao
Cristian Barca

save2004 Profilo | Newbie

Grazie mille Cristian per le risposte che mi dai!!! Sei GENTILISSSIMO!!
Quindi:
1) dichiaro una variabile "gruppo" (Dim gruppo as ListviewGroup)
2) Aggiungo un nuovo gruppo prima ancora di caricare nel listview i dati prelevati dalla query (Listordinato.Groups.Add(New ListViewGroup("", HorizontalAlignment.Left))) senza nominarla in alcun modo
3) ora devo associare questo nuovo gruppo alla mia variabile "gruppo" (come si traduce in codice?)
4) il recordset determinato dalla query lo associo direttamente a "gruppo"? (come si traduce in codice? tenendo conto anche del fatto che ho dei subitems....)

Resta un mistero come mai non visualizzi i record nel listview ma mi rimanga tutto in bianco....

Ti prego di perdonarmi se approfitto della tua gentilezza!!

Saverio

AntCiar Profilo | Expert

Ciao.

Metto un po mani al tuo codice:

''Dichiaro il gruppo
Dim grp As ListViewGroup
''Dichiaro un Items
Dim elem As ListViewItem

For i = 0 To TreeView1.Nodes.Count - 1
ToolStripProgressBar1.Minimum = 0
ToolStripProgressBar1.Maximum = TreeView1.Nodes.Count - 1
ToolStripProgressBar1.Value = i

'scorro il secondo livello
For j = 0 To TreeView1.Nodes(i).Nodes.Count - 1
'scorro il terzo livello
For k = 0 To TreeView1.Nodes(i).Nodes(j).Nodes.Count - 1
If TreeView1.Nodes(i).Nodes(j).Nodes(k).Nodes.Count <> 0 Then
'scorro il quarto livello
For y = 0 To TreeView1.Nodes(i).Nodes(j).Nodes(k).Nodes.Count - 1
importo = 0
s1 = Split(TreeView1.Nodes(i).Text, " ")
s2 = Split(TreeView1.Nodes(i).Nodes(j).Text, " ")
s3 = Split(TreeView1.Nodes(i).Nodes(j).Nodes(k).Text, " ")
capitolato = TreeView1.Nodes(i).Nodes(j).Nodes(k).Nodes(y).Text

''Inizializzo il gruppo e lo aggiungo alla ListView
grp = new ListViewGroup("") me.ListView1.Groups.Add(grp)

rs.Open("SELECT fornitori.ragionesociale, GSD70COL_GOFRI00F.ORNUM, " _
& "GSD70COL_GOFRI00F.ORANN, GSD70COL_GOFRI00F.ORDES, GSD70COL_GOFRI00F.ORDE2, " _
& "GSD70COL_GOFRI00F.ORQTA, GSD70COL_GOFRI00F.ORCOS" _
& " FROM fornitori INNER JOIN (GSD70COL_GOFRI00F INNER JOIN GSD70COL_GOFTE00F " _
& " ON (GSD70COL_GOFRI00F.ORANN = GSD70COL_GOFTE00F.OTANN AND " _
& " GSD70COL_GOFRI00F.ORNUM = GSD70COL_GOFTE00F.OTNUM)) " _
& " ON (fornitori.codice = GSD70COL_GOFRI00F.ORFOR) WHERE" _
& " ORAZI LIKE '" & filtro & "' AND" _
& " ORCOM LIKE '%" & cmbcommessa.Text & "%' AND" _
& " ORCAN LIKE '%" & cmbcant.Text & "%' AND" _
& " ORLI2 LIKE '%" & s1(0) & "%' AND" _
& " ORLI3 LIKE '%" & s2(0) & "%' AND" _
& " ORLI4 LIKE '%" & s3(0) & "%' AND" _
& " ORCAP LIKE '%" & capitolato & "%' AND" _
& " OTDAT >= " & dal & " AND" _
& " OTDAT <= " & al & " ", cn, 1)

If rs.RecordCount <> 0 Then

MsgBox("numero di record trovati " & rs.RecordCount & " WBS " & s1(0) & "." & s2(0) & "." & s3(0) & " " & capitolato)
While rs.EOF = False

If rs.Fields("ORQTA").Value = zero Then
importo = importo + rs.Fields("ORCOS").Value
Else
importo = importo + (rs.Fields("ORQTA").Value * rs.Fields("ORCOS").Value)
End If

elem = new Listvewiitem() elem.text = rs.Fields("ragionesociale").Value elem.subitems.add((Mid(rs.Fields("ORANN").Value, 3, 2) & "/" & rs.Fields("ORNUM").Value)) elem.subitems.add(Trim(rs.Fields("ORDES").Value) & Trim(rs.Fields("ORDE2").Value)) elem.subitems.add(FormatNumber(rs.Fields("ORQTA").Value)) elem.subitems.add(FormatNumber(rs.Fields("ORCOS").Value)) If rs.Fields("ORQTA").Value = zero Then elem.subitems.add(FormatNumber(rs.Fields("ORCOS").Value)) else elem.subitems.add(FormatNumber(rs.Fields("ORQTA").Value * rs.Fields("ORCOS").Value)) end if elem.Group = grp me.ListView1.Items.Add(Elem)

rs.MoveNext()
End While

grp.Text( oppure 'Caption' non ricordo bene) = "" & s1(0) & "." & s2(0) & "." _ & s3(0) & " " & capitolato & " " & "(" & importo & ")"

End If
rs.Close()
Next
End If
Next
Next
Next

cn.Close()
ToolStripProgressBar1.Value = 0
Cristian Barca

save2004 Profilo | Newbie

Fantastico!!! Funziona benissimo ed è anche più rapido!!
Cristian sei un mito!!!!
(per grp ho usato la proprietà Header)
Purtroppo mi resta sempre tutto in bianco... sembra quasi che il listview perda la proprietà details come visualizzazione (infatti scompaiono le intestazioni di colonna e non si vede il contenuto delle righe).
Ho provato al termine del ciclo a scrivere

Listordinato.View = View.Details

ma non ho alcun effetto.... allego l'immagine di come mi compare il form al termine dell'operazione... (so per certo che i record associati ai vari gruppi sono quelli giusti - vedi i msgbox che ho usato come controlli)


923x582 87Kb

AntCiar Profilo | Expert

Ciao.

-Controlla che la proprietà OwerDraw della listview sia = false
-Controlla anche di non aver generato l'evento DrawItem sulla ListView
-Controlla nel caso in cui invochi il metodo me.listView1.BeginUpdate() di richiamare alla fine il metodo Me.ListView1.EndUpdate()


Cristian Barca

save2004 Profilo | Newbie

RISOLTO!!!!!!
Come si può vedere dal primo post che ho scritto, ho inizializzato il tutto con un brutalissimo

listordinato.clear()

Mi è bastato correggere in

lisordinato.items.clear()

Scusatemi tanto!!
Cristian il risultato è bellissimo!! Proprio come volevo!!! Grazie mille per l'aiuto!!! Sei stato fondamentale!!

Saverio

AntCiar Profilo | Expert

Di Niente.

Ricordati di chiudere il post accettando una delle risposte.
Cristian Barca
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5