الأحمال تحكم ListView ببطء شديد
-
03-07-2019 - |
سؤال
ما هي اسرع وسيلة لملء ListView من الاستعلام عندما يكون لديه أكثر من 15000 القوائم مع 9 بنود فرعية. فمن أخذ مني حوالي 6 دقائق لتحميل.
وهنا ما كتبته لملء تحكم 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
المحلول 2
وأستطيع أن أفكر في بضعة أشياء:
وعلى الرغم ... وند هو آلية حلقات أبطأ. استخدام ل... التالي. ل... التالي أسرع - حتى إذا كان لديك لتشغيل أمر آخر للحصول على عدد_السجلات. وهذا هو ما يمكنني استخدام:
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
استخدم مع ... نهاية مع لإضافة بنود فرعية الخاص بك:
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
والتفاف رمز populater في:
DoCmd.Echo False
'-- Populate code
DoCmd.Echo True
وعلى أمل أن يساعد!
نصائح أخرى
وأول شيء هو يجب عليك فعله هو التخلص من "تقوم الدالة DoEvents" هذا قاتل الأداء الحقيقي.
هل لديك لتحميل يكون ListView حيوي؟ لماذا لا تربط مباشرة إلى مصدر بيانات؟
وتحقق من أساليب السيطرة ListView لشيء من هذا القبيل beginupdate / endupdate أو مجموعة التحديث إلى false (إن أمكن). وهذا يعني أن واجهة المستخدم ليس محاولة لتحديث الشاشة بعد إضافة كل عنصر، مما يجعل مضيفا أسرع بكثير.
تم تصميم جهاز التحكم ListView إلى اتخاذ عدد كبير من العناصر لذلك ينبغي أن يكون من الممكن مع قليل من الحفر.