Saya memiliki kelas Bagian dengan daftar bidang dalam kode di bawah ini. Saya memiliki kontrol DataGridView, yang saya filter dengan DLL Advanced DGV (ADGV) dari NUGET. Saya harus menyertakan ADGV di winform saya. Saat ini saya memiliki DataGridView, kotak pencarian di formulir, dan tombol untuk menjalankan fungsi berikut. Saya perlu menelusuri semua baris yang terlihat, mengumpulkan daftar unik nomor bagian dengan revisi terbarunya, dan kemudian mewarnai baris di DataGridView yang kedaluwarsa dengan memeriksa nomor bagian dan memperbaiki setiap baris dengan daftar terbaru . Untuk 45.000 entri yang ditampilkan di DataGridView, ini membutuhkan waktu ~17 detik. Untuk ~50 entri, dibutuhkan ~1,2 detik. Ini sangat tidak efisien, tetapi saya tidak dapat melihat cara untuk mengurangi waktu.

Sub highlightOutdatedParts()
    'Purpose: use the results in the datagridview control, find the most recent revision of each part, and 
    '           highlight all outdated parts relative to their respective most recent revisions
    'SORT BY PART NUMBER AND THEN BY REV
    If resultsGrid.ColumnCount = 0 Or resultsGrid.RowCount = 0 Then Exit Sub
    Dim stopwatch As New Stopwatch
    stopwatch.Start()
    resultsGrid.Sort(resultsGrid.Columns("PartNumber"), ListSortDirection.Ascending)
    Dim iBag As New ConcurrentBag(Of Part)
    Dim sortedList As Generic.List(Of Part)
    For Each row As DataGridViewRow In resultsGrid.Rows
        If row.Visible = True Then
            Dim iPart As New Part()
            Try
                iPart.Row = row.Cells(0).Value
                iPart.Workbook = CStr(row.Cells(1).Value)
                iPart.Worksheet = CStr(row.Cells(2).Value)
                iPart.Product = CStr(row.Cells(3).Value)
                iPart.PartNumber = CStr(row.Cells(4).Value)
                iPart.ItemNo = CStr(row.Cells(5).Value)
                iPart.Rev = CStr(row.Cells(6).Value)
                iPart.Description = CStr(row.Cells(7).Value)
                iPart.Units = CStr(row.Cells(8).Value)
                iPart.Type = CStr(row.Cells(9).Value)
                iPart.PurchCtgy = CStr(row.Cells(10).Value)
                iPart.Qty = CDbl(row.Cells(11).Value)
                iPart.TtlPerProd = CDbl(row.Cells(12).Value)
                iPart.Hierarchy = CStr(row.Cells(13).Value)
                iBag.Add(iPart)
            Catch ice As InvalidCastException
            Catch nre As NullReferenceException
            End Try
        End If
    Next
    sortedList = (From c In iBag Order By c.PartNumber, c.Rev).ToList()  ' sort and convert to list
    Dim mostUTDRevList As New Generic.List(Of Part)     ' list of most up to date parts, by Rev letter
    For sl As Integer = sortedList.Count - 1 To 0 Step -1   'start at end of list and work to beginning
        Dim query = From entry In mostUTDRevList    ' check if part number already exists in most up to date list
                    Where entry.PartNumber = sortedList(sl).PartNumber
                    Select entry
        If query.Count = 0 Then     ' if this part does not already exist in the list, add.
            mostUTDRevList.Add(sortedList(sl))
        End If
    Next
    'HIGHLIGHT DATAGRIDVIEW ROWS WHERE PART NUMBERS ARE OUT OF DATE
    For Each row As DataGridViewRow In resultsGrid.Rows
        ' if that part with that Rev does not exist in the list, it must be out of date
        Try
            Dim rowPN As String = CStr(row.Cells(4).Value).ToUpper  ' get part number
            Dim rowR As String = CStr(row.Cells(6).Value).ToUpper   ' get Rev
            Dim query = From entry In mostUTDRevList    ' check if that part number with that Rev is in the list.
                        Where entry.PartNumber.ToUpper.Equals(rowPN) AndAlso
                        entry.Rev.ToUpper.Equals(rowR)
                        Select entry
            If query.Count = 0 Then     ' if the part is out of date highlight its' row
                row.DefaultCellStyle.BackColor = Color.Chocolate
            End If
        Catch ex As NullReferenceException
        Catch ice As InvalidCastException
        End Try
    Next
    resultsGrid.Select()
    stopwatch.Stop()
    If Not BackgroundWorker1.IsBusy() Then timertextbox.Text = stopwatch.Elapsed.TotalSeconds.ToString & " secs"
    MessageBox.Show("Highlighting completed successfully.")
End Sub
1
steve 9 Desember 2016, 17:49

1 menjawab

Solusinya sebagian didorong oleh @Plutonix.

Sub highlightOutdatedParts()
    If resultsGrid.ColumnCount = 0 Or resultsGrid.RowCount = 0 Then Exit Sub
    Dim stopwatch As New Stopwatch
    stopwatch.Start()
    resultsGrid.DataSource.DefaultView.Sort = "PartNumber ASC, Rev DESC"
    resultsGrid.Update()
    'HIGHLIGHT DATAGRIDVIEW ROWS WHERE PART NUMBERS ARE OUT OF DATE
    Dim irow As Long = 0
    Do While irow <= resultsGrid.RowCount - 2
        ' if that part with that Rev does not exist in the list, it must be out of date
        Dim utdPN As String = resultsGrid.Rows(irow).Cells(4).Value.ToString().ToUpper()
        Dim utdRev As String = resultsGrid.Rows(irow).Cells(6).Value.ToString().ToUpper()
        Dim iirow As Long = irow + 1
        'If iirow > resultsGrid.RowCount - 1 Then Exit Do
        Dim activePN As String = Nothing
        Dim activeRev As String = Nothing
        Try
            activePN = resultsGrid.Rows(iirow).Cells(4).Value.ToString().ToUpper()
            activeRev = resultsGrid.Rows(iirow).Cells(6).Value.ToString().ToUpper()
        Catch ex As NullReferenceException
        End Try
        Do While activePN = utdPN
            If iirow > resultsGrid.RowCount - 1 Then Exit Do
            If activeRev <> utdRev Then
                resultsGrid.Rows(iirow).DefaultCellStyle.BackColor = Color.Chocolate
            End If
            iirow += 1
            Try
                activePN = resultsGrid.Rows(iirow).Cells(4).Value.ToString().ToUpper()
                activeRev = resultsGrid.Rows(iirow).Cells(6).Value.ToString().ToUpper()
            Catch nre As NullReferenceException
            Catch aoore As ArgumentOutOfRangeException
            End Try
        Loop
        irow = iirow
    Loop
    resultsGrid.Select()
    stopwatch.Stop()
    If Not BackgroundWorker1.IsBusy() Then
        timertextbox.Text = stopwatch.Elapsed.TotalSeconds.ToString & " secs"
        resultcounttextbox.Text = resultsGrid.RowCount - 1 & " results"
    End If
    MessageBox.Show("Highlighting completed successfully.")
End Sub
0
Connor 9 Desember 2016, 17:07