问题
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?
来源:https://stackoverflow.com/questions/53525751/for-loop-to-iterate-through-all-checkedlistboxes-in-a-windows-form