For loop to iterate through all checkedlistboxes i

2019-09-21 11:56发布

问题:

I have already a solution for my problem but it takes too long to process. I would like to get some help in a way that i can loop through all the 10 checkedlistboxes i have in my form in order to each one fill a column of my datagridview. This is the code i have

1st block of code:

Dim dt As New DataTable
dt.Columns.Add("Região", Type.GetType("System.String"))
dt.Columns.Add("Produto", Type.GetType("System.String"))
dt.Columns.Add("Cliente", Type.GetType("System.String"))
dt.Columns.Add("Tipo Atividade", Type.GetType("System.String"))
dt.Columns.Add("Acabamento", Type.GetType("System.String"))
dt.Columns.Add("Cores", Type.GetType("System.String"))
dt.Columns.Add("Gramagem", Type.GetType("System.String"))
dt.Columns.Add("Tipo Embalagem", Type.GetType("System.String"))
dt.Columns.Add("Formatos", Type.GetType("System.String"))
dt.Columns.Add("Contagem", Type.GetType("System.String"))
dt.Columns.Add("Transporte", Type.GetType("System.String"))
dt.Columns.Add("Moeda", Type.GetType("System.String"))
dt.Columns.Add("Preço", Type.GetType("System.String"))
dt.Columns.Add("Data Inicio", Type.GetType("System.String"))
dt.Columns.Add("Data Fim", Type.GetType("System.String"))
dt.Columns.Add("Standard", GetType(Boolean))

Dim dataInicio, dataFim As String
dataInicio = DateTimeInicio.Value.ToString("dd-MM-yyyy")
dataFim = DateTimeFim.Value.ToString("dd-MM-yyyy")
Dim a, b, c, d, f, g, h, i, j, k As Integer
Dim dr As DataRow = dt.NewRow

2nd block of code :

 For a = 0 To ChkListRegiao.Items.Count - 1
            For b = 0 To ChkListProduto.Items.Count - 1
                For c = 0 To ChkListTipoAtividade.Items.Count - 1
                    For d = 0 To ChkListAcabamento.Items.Count - 1
                        For f = 0 To ChkListCores.Items.Count - 1
                            For g = 0 To ChkListGramagem.Items.Count - 1
                                For h = 0 To ChkListTipoEmbalagem.Items.Count - 1
                                    For i = 0 To ChkListFormatos.Items.Count - 1
                                        For j = 0 To ChkListContagem.Items.Count - 1
                                            For k = 0 To ChkListTransporte.Items.Count - 1
                                                dr("Região") = ChkListRegiao.GetItemChecked(a)
                                                dr("Produto") = ChkListProduto.GetItemChecked(b)
                                                dr("Cliente") = ""
                                                dr("Tipo Atividade") = ChkListTipoAtividade.GetItemChecked(c)
                                                dr("Acabamento") = ChkListAcabamento.GetItemChecked(d)
                                                dr("Cores") = ChkListCores.GetItemChecked(f)
                                                dr("Gramagem") = ChkListGramagem.GetItemChecked(g)
                                                dr("Tipo Embalagem") = ChkListTipoEmbalagem.GetItemChecked(h)
                                                dr("Formatos") = ChkListFormatos.GetItemChecked(i)
                                                dr("Contagem") = ChkListContagem.GetItemChecked(j)
                                                dr("Transporte") = ChkListTransporte.GetItemChecked(k)
                                                dr("Moeda") = txtMoeda.Text
                                                dr("Preço") = txtPrecoTon.Text
                                                dr("Data Inicio") = dataInicio
                                                dr("Data Fim") = dataFim
                                                dr("Standard") = chkStandard.Checked
                                                If ChkListRegiao.GetItemChecked(a) And ChkListProduto.GetItemChecked(b) And ChkListTipoAtividade.GetItemChecked(c) And
                                                    ChkListAcabamento.GetItemChecked(d) And ChkListCores.GetItemChecked(f) And ChkListGramagem.GetItemChecked(g) And
                                                    ChkListTipoEmbalagem.GetItemChecked(h) And ChkListFormatos.GetItemChecked(i) And ChkListContagem.GetItemChecked(j) And
                                                    ChkListTransporte.GetItemChecked(k) Then
                                                    dt.Rows.Add(ChkListRegiao.Items(a), ChkListProduto.Items(b), "", ChkListTipoAtividade.Items(c), ChkListAcabamento.Items(d), ChkListCores.Items(f),
                                                                ChkListGramagem.Items(g), ChkListTipoEmbalagem.Items(h), ChkListFormatos.Items(i),
                                                                ChkListContagem.Items(j), ChkListTransporte.Items(k), txtMoeda.Text, txtPrecoTon.Text, dataInicio, dataFim, chkStandard.Checked)
                                                    DataGridView1.DataSource = dt
                                                End If
                                            Next
                                        Next
                                    Next
                                Next
                            Next
                        Next
                    Next
                Next
            Next
        Next

回答1:

Take this line:

DataGridView1.DataSource = dt

And move it after all of the For loops end. This is not the only thing that slows you down, but I suspect it is the biggest... trying to rebuild the grid after every change.

Additionally, you can restructure the loops to filter at each level before calling into the other levels, and save quite a bit of work this way. For example, say you only have 3 lists, each with 5 out of 10 items selected. The original code would run the entire if() conditions 1000 times, each with 3 boolean comparisons, in order to produce only 125 results. By filtering at each level before descending into the next, you minimize the number of failed checks. The same 3 lists would only require 310 boolean checks to produce the same 125 results if you don't pre-cache selections, or 30 boolean checks + a little extra memory if you do:

Dim dt As New DataTable
dt.Columns.Add("Região", Type.GetType("System.String"))
dt.Columns.Add("Produto", Type.GetType("System.String"))
dt.Columns.Add("Cliente", Type.GetType("System.String"))
dt.Columns.Add("Tipo Atividade", Type.GetType("System.String"))
dt.Columns.Add("Acabamento", Type.GetType("System.String"))
dt.Columns.Add("Cores", Type.GetType("System.String"))
dt.Columns.Add("Gramagem", Type.GetType("System.String"))
dt.Columns.Add("Tipo Embalagem", Type.GetType("System.String"))
dt.Columns.Add("Formatos", Type.GetType("System.String"))
dt.Columns.Add("Contagem", Type.GetType("System.String"))
dt.Columns.Add("Transporte", Type.GetType("System.String"))
dt.Columns.Add("Moeda", Type.GetType("System.String"))
dt.Columns.Add("Preço", Type.GetType("System.String"))
dt.Columns.Add("Data Inicio", Type.GetType("System.String"))
dt.Columns.Add("Data Fim", Type.GetType("System.String"))
dt.Columns.Add("Standard", GetType(Boolean))

Dim dataInicio As String = DateTimeInicio.Value.ToString("dd-MM-yyyy")
Dim dataFim As String = DateTimeFim.Value.ToString("dd-MM-yyyy")

'Uncached:
For Each a In ChkListRegiao.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)
    For Each b In ChkListProduto.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)
        For Each c In ChkListTipoAtividade.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)
            For Each d In ChkListAcabamento.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)
                For Each f In ChkListCores.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)
                    For Each g In ChkListGramagem.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)
                        For Each h In ChkListTipoEmbalagem.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)
                            For Each i In ChkListFormatos.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)
                                For Each j In ChkListContagem.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)
                                    For Each k In ChkListTransporte.Items.Cast(Of ListItem)().Where(Function(li) li.Selected)

                                        dt.Rows.Add(a, b, "", c, d, f, g, h, i, j, k, txtMoeda.Text, txtPrecoTon.Text, dataInicio, dataFim, chkStandard.Checked)

                                    Next
                                Next
                            Next
                        Next            
                    Next
                Next
            Next
        Next
    Next 
Next
DataGridView1.DataSource = dt

'Cached:
Dim regiao = ChkListRegiao.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList()
Dim produto = ChkListProduto.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList()
Dim tipoatividade = ChkListTipoAtividade.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList()
Dim acabamento = ChkListAcabamento.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList()
Dim cores = ChkListCores.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList()
Dim gramagem = ChkListGramagem.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList()
Dim tipoembalagem = ChkListTipoEmbalagem.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList() 
Dim formatos = ChkListFormatos.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList()
Dim contagem = ChkListContagem.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList()
Dim transporte = ChkListTransporte.Items.Cast(Of ListItem)().Where(Function(li) li.Selected).ToList()

For Each a In regiao
    For Each b In produto
        For Each c In tipoatividade
            For Each d In acabamento
                For Each f In cores
                    For Each g In gramagem
                        For Each h In tipoembalagem
                            For Each i In formatos
                                For Each j In contagem
                                    For Each k In transporte

                                        dt.Rows.Add(a, b, "", c, d, f, g, h, i, j, k, txtMoeda.Text, txtPrecoTon.Text, dataInicio, dataFim, chkStandard.Checked)

                                    Next
                                Next
                            Next
                        Next            
                    Next
                Next
            Next
        Next
    Next 
Next
DataGridView1.DataSource = dt

You'll want to try both to see which is faster for your environment.

But even this seems wrong. Do you really want every possible combination of items selected from all the lists?