Il controllo ListView si carica molto lentamente
-
03-07-2019 - |
Domanda
Qual è il modo più veloce per riempire ListView dalla query quando ha oltre 15000 elenchi con 9 elementi secondari. mi ci vogliono circa 6 minuti per caricare.
Ecco cosa ho scritto per riempire il controllo ListView.
Set rs = db.OpenRecordset(strSQL, dbOpenForwardOnly, dbReadOnly)
With Me.listViewData
.View = lvwReport
.GridLines = True
.FullRowSelect = True
.ListItems.Clear
.ColumnHeaders.Clear
End With
'Set up column headers
With Me.listViewData.ColumnHeaders
.Add , , "Client", 1440, lvwColumnLeft
.Add , , "Contact", 2160, lvwColumnLeft
.Add , , "Quote #", 720, lvwColumnCenter
.Add , , "Date", 1140, lvwColumnLeft
.Add , , "GrandTotal", 1440, lvwColumnRight
.Add , , "Weighted Value", 1440, lvwColumnRight
.Add , , "Chance %", 500, lvwColumnRight
.Add , , "Sales Cycle", 1140, lvwColumnRight
.Add , , "Won Orders", 1000, lvwColumnRight
.Add , , "SalesRep", 1000, lvwColumnRight
End With
While Not rs.EOF
Set lstItem = Me.listViewData.ListItems.Add()
lstItem.Text = Nz(rs!Name, "")
lstItem.SubItems(1) = Nz(rs!Company, "")
lstItem.SubItems(2) = Nz(rs!QuoteNumber, "")
lstItem.SubItems(3) = Nz(rs!OrderDate, "")
lstItem.SubItems(4) = Nz(Format(rs!GrandTotal, "Currency"), "0.00")
lstItem.SubItems(5) = Nz(Format(rs!GrandTotal * rs!Customfield1 / 100, "Currency"), "")
lstItem.SubItems(6) = Nz(rs!Customfield1, "")
lstItem.SubItems(7) = Nz(rs!Date1, "none")
lstItem.SubItems(8) = Nz(rs!Detail, "")
lstItem.SubItems(9) = Nz(rs!CustomT1, Nz(rs!UserID, ""))
For I = 1 To Me.listViewData.ColumnHeaders.Count - 1
Set sb = lstItem.ListSubItems(I)
If rs!Customfield1 = 100 Or Not IsNull(rs!List) Then
sb.ForeColor = vbBlue
lstItem.ForeColor = vbBlue
ElseIf rs!Cancelled = -1 Then
sb.ForeColor = vbRed
lstItem.ForeColor = vbRed
Else
sb.ForeColor = vbBlack
lstItem.ForeColor = vbBlack
End If
DoEvents
Next
rs.MoveNext
Wend
Soluzione 2
Posso pensare a un paio di cose:
While ... Wend è un meccanismo di loop più lento; utilizzare per ... Avanti. Per ... Il prossimo è più veloce - anche se devi eseguire un altro comando per ottenere RecordCount. Questo è quello che uso:
With rs
If .RecordCount > 0 Then
'-- MoveLast...MoveFirst will update the .RecordCount; depending on the type of DAO Recordset, RecordCount might only return "1" when there are more than that.
.MoveLast
.MoveFirst
For lngCounter = 1 To .RecordCount
'-- Code to add ListItems here
.MoveNext
Next lngCounter
End If
.Close
End With
Usa con ... Termina con per aggiungere i tuoi SubItems:
With Me.listViewData.ListItems.Add
.Text = Nz(rs!Name, "")
.SubItems(1) = Nz(rs!Company, "")
.SubItems(2) = Nz(rs!QuoteNumber, "")
.SubItems(3) = Nz(rs!OrderDate, "")
.SubItems(4) = Nz(Format(rs!GrandTotal, "Currency"), "0.00")
.SubItems(5) = Nz(Format(rs!GrandTotal * rs!Customfield1 / 100, "Currency"), "")
.SubItems(6) = Nz(rs!Customfield1, "")
.SubItems(7) = Nz(rs!Date1, "none")
.SubItems(8) = Nz(rs!Detail, "")
.SubItems(9) = Nz(rs!CustomT1, Nz(rs!UserID, ""))
End With
Inserisci il codice populater in:
DoCmd.Echo False
'-- Populate code
DoCmd.Echo True
Spero che ti aiuti!
Altri suggerimenti
La prima cosa da fare è sbarazzarsi del "doevents" È un vero killer delle prestazioni.
Devi caricare la visualizzazione elenco in modo dinamico? Perché non collegarlo direttamente a un'origine dati?
Controlla i metodi del controllo Listview per qualcosa come startupdate / endupdate o imposta refresh su false (se possibile). Ciò significa che l'interfaccia utente non proverà ad aggiornare lo schermo dopo aver aggiunto ogni elemento, rendendo l'aggiunta molto più rapida.
Il controllo Listview è progettato per prendere un gran numero di elementi, quindi dovrebbe essere possibile con un po 'di scavo.