Usuário com melhor resposta
CONDIÇÃO NÃO CONTÊM NO DATAGRIDVIEW

Pergunta
-
Boa noite.
Preciso fazer uma comparação entre dois DataGridView's e exibir em um terceiro DataGridView, as linhas do primeiro que não está contido no segundo.
Abaixo, a imagem dos dois DataGridView's que preciso comparar:
Note que, no primeiro DataGridView, há uma linha com o documento 63989, e no segundo DataGridView, este registro está faltando.
Meu objetivo então, é exibir esta linha que está faltando em um terceiro DataGridView para que o usuário saiba qual documento está faltando.
Tudo que consegui fazer no momento foi o contrário, exibir as linhas que coincidem nos dois DataGridView's.
Segue o código:
private void btAnalisar_Click(object sender, EventArgs e) { if (radioButtonNotasAusentesConsisaNet.Checked == true) { for (int i = 0; i < dataGridViewSefaz.Rows.Count; i++) { for (int index = 0; index < dataGridViewConsisaNet.Rows.Count; index++) { if (dataGridViewSefaz.Rows[i].Cells[2].Value.ToString().Equals(dataGridViewConsisaNet.Rows[index].Cells[2].Value.ToString())) { dataGridViewAnalise.Rows.Insert(0, dataGridViewSefaz.Rows[i].Cells[2].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[3].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[24].Value.ToString()); } } } } }
Como posso proceder?
- Editado JehanKheller sábado, 4 de agosto de 2018 01:14
Respostas
-
JehanKheller,
Nesse caso, você precisa antes rodar o "FOR" inteiro e depois escrever o que achou. É possível usar o "break" para NÃO comparar mais depois que achou uma igualdade. Vamos marcar com uma variável booleana a posição que NÃO foi encontrada ... será "FALSE" se NÃO for encontrado:
private void btAnalisar_Click(object sender, EventArgs e) { bool blnComp = false; if (radioButtonNotasAusentesConsisaNet.Checked == true) { for (int i = 0; i < dataGridViewSefaz.Rows.Count; i++) { for (int index = 0; index < dataGridViewConsisaNet.Rows.Count; index++) { if (dataGridViewSefaz.Rows[i].Cells[0].Value.ToString().Equals(dataGridViewConsisaNet.Rows[index].Cells[0].Value.ToString())) { blnComp = true; break; } } if (!blnComp) { dataGridViewAnalise.Rows.Add(dataGridViewSefaz.Rows[i].Cells[0].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[1].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[2].Value.ToString()); } else { blnComp = false; } } } }
[]'s,
Fabio I.- Editado Fabio I segunda-feira, 6 de agosto de 2018 13:51
- Marcado como Resposta JehanKheller segunda-feira, 6 de agosto de 2018 17:24
Todas as Respostas
-
JehanKheller,
Vou explicar o que fiz de duas formas, uma resumida e uma completa.
======================================================
1º) Resumidamente. Basta trocar "Insert" por "Add" e mais uns acertos na linha. Ficaria dessa forma:dataGridViewAnalise.Rows.Add(dataGridViewSefaz.Rows[i].Cells[0].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[2].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[3].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[24].Value.ToString());
======================================================
2º) Bem completa (precisei fazer para testar):
2.1 - Criei uma classe de dados a saber:namespace clsDataGridView { public class clsDados { #region Construtores #endregion #region Propriedades private int _id; private string _nome; private DateTime _dataNascimento; #endregion #region Métodos public int Id { get { return _id; } set { _id = value; } } public string Nome { get { return _nome; } set { _nome = value; } } public DateTime DataNascimento { get { return _dataNascimento; } set { _dataNascimento = value; } } #endregion } }
2.2 - Carreguei os dados no Form Load:
public void frmDataGridView_Load(object sender, EventArgs e) { List<clsDados> lDados1 = new List<clsDados>(); List<clsDados> lDados2 = new List<clsDados>(); lDados1.Add(new clsDados() { Id = 1, Nome = "Teste1", DataNascimento = Convert.ToDateTime("2001/01/01") }); lDados1.Add(new clsDados() { Id = 2, Nome = "Teste2", DataNascimento = Convert.ToDateTime("2002/02/02") }); lDados1.Add(new clsDados() { Id = 3, Nome = "Teste3", DataNascimento = Convert.ToDateTime("2003/03/03") }); lDados2.Add(new clsDados() { Id = 2, Nome = "Teste2", DataNascimento = Convert.ToDateTime("2002/02/02") }); lDados2.Add(new clsDados() { Id = 3, Nome = "Teste3", DataNascimento = Convert.ToDateTime("2003/03/03") }); lDados2.Add(new clsDados() { Id = 4, Nome = "Teste4", DataNascimento = Convert.ToDateTime("2004/04/04") }); dataGridViewSefaz.DataSource = lDados1; dataGridViewConsisaNet.DataSource = lDados2; }
2.3 - Modifiquei um pouco o código do botão:
private void btAnalisar_Click(object sender, EventArgs e) { if (radioButtonNotasAusentesConsisaNet.Checked == true) { for (int i = 0; i < dataGridViewSefaz.Rows.Count; i++) { for (int index = 0; index < dataGridViewConsisaNet.Rows.Count; index++) { if (dataGridViewSefaz.Rows[i].Cells[0].Value.ToString().Equals(dataGridViewConsisaNet.Rows[index].Cells[0].Value.ToString())) { dataGridViewAnalise.Rows.Add(dataGridViewSefaz.Rows[i].Cells[0].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[1].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[2].Value.ToString()); } } } } }
[]'s,
Fabio I. -
JehanKheller,
Vou explicar o que fiz de duas formas, uma resumida e uma completa.
======================================================
1º) Resumidamente. Basta trocar "Insert" por "Add" e mais uns acertos na linha. Ficaria dessa forma:dataGridViewAnalise.Rows.Add(dataGridViewSefaz.Rows[i].Cells[0].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[2].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[3].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[24].Value.ToString());
======================================================
2º) Bem completa (precisei fazer para testar):
2.1 - Criei uma classe de dados a saber:namespace clsDataGridView { public class clsDados { #region Construtores #endregion #region Propriedades private int _id; private string _nome; private DateTime _dataNascimento; #endregion #region Métodos public int Id { get { return _id; } set { _id = value; } } public string Nome { get { return _nome; } set { _nome = value; } } public DateTime DataNascimento { get { return _dataNascimento; } set { _dataNascimento = value; } } #endregion } }
2.2 - Carreguei os dados no Form Load:
public void frmDataGridView_Load(object sender, EventArgs e) { List<clsDados> lDados1 = new List<clsDados>(); List<clsDados> lDados2 = new List<clsDados>(); lDados1.Add(new clsDados() { Id = 1, Nome = "Teste1", DataNascimento = Convert.ToDateTime("2001/01/01") }); lDados1.Add(new clsDados() { Id = 2, Nome = "Teste2", DataNascimento = Convert.ToDateTime("2002/02/02") }); lDados1.Add(new clsDados() { Id = 3, Nome = "Teste3", DataNascimento = Convert.ToDateTime("2003/03/03") }); lDados2.Add(new clsDados() { Id = 2, Nome = "Teste2", DataNascimento = Convert.ToDateTime("2002/02/02") }); lDados2.Add(new clsDados() { Id = 3, Nome = "Teste3", DataNascimento = Convert.ToDateTime("2003/03/03") }); lDados2.Add(new clsDados() { Id = 4, Nome = "Teste4", DataNascimento = Convert.ToDateTime("2004/04/04") }); dataGridViewSefaz.DataSource = lDados1; dataGridViewConsisaNet.DataSource = lDados2; }
2.3 - Modifiquei um pouco o código do botão:
private void btAnalisar_Click(object sender, EventArgs e) { if (radioButtonNotasAusentesConsisaNet.Checked == true) { for (int i = 0; i < dataGridViewSefaz.Rows.Count; i++) { for (int index = 0; index < dataGridViewConsisaNet.Rows.Count; index++) { if (dataGridViewSefaz.Rows[i].Cells[0].Value.ToString().Equals(dataGridViewConsisaNet.Rows[index].Cells[0].Value.ToString())) { dataGridViewAnalise.Rows.Add(dataGridViewSefaz.Rows[i].Cells[0].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[1].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[2].Value.ToString()); } } } } }
[]'s,
Fabio I.Boa tarde Fábio. Obrigado pela contribuição. Infelizmente o resultado obtido através do seu código, retorna justamente as linhas que são iguais entre as DataGridView's. Ou seja, ela adiciona ao terceiro DataGridView as linhas que contêm o Documento 63987 e 63988.
Meu objetivo é o contrário. Preciso que seja exibido no terceiro DataGridView, justamente a linha em que o Documento não coincide, ou seja, preciso que o terceiro DataGridView apresente a linha com o Documento 63989.
-
JehanKheller,
Nesse caso, você precisa antes rodar o "FOR" inteiro e depois escrever o que achou. É possível usar o "break" para NÃO comparar mais depois que achou uma igualdade. Vamos marcar com uma variável booleana a posição que NÃO foi encontrada ... será "FALSE" se NÃO for encontrado:
private void btAnalisar_Click(object sender, EventArgs e) { bool blnComp = false; if (radioButtonNotasAusentesConsisaNet.Checked == true) { for (int i = 0; i < dataGridViewSefaz.Rows.Count; i++) { for (int index = 0; index < dataGridViewConsisaNet.Rows.Count; index++) { if (dataGridViewSefaz.Rows[i].Cells[0].Value.ToString().Equals(dataGridViewConsisaNet.Rows[index].Cells[0].Value.ToString())) { blnComp = true; break; } } if (!blnComp) { dataGridViewAnalise.Rows.Add(dataGridViewSefaz.Rows[i].Cells[0].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[1].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[2].Value.ToString()); } else { blnComp = false; } } } }
[]'s,
Fabio I.- Editado Fabio I segunda-feira, 6 de agosto de 2018 13:51
- Marcado como Resposta JehanKheller segunda-feira, 6 de agosto de 2018 17:24
-
JehanKheller,
Só por curiosidade criei um novo botão (btAnalisar2) para brincar de "Linq" e "Expressões Lambda", mas precisei converter tudo para "List<>" para poder me divertir.
O "Resultado2" faz a comparação "ao contrário" e pega o que não tem na tabela "dataGridViewConsisaNet" e tem na tabela "dataGridViewSefaz" (comente toda a '#region' do "Resultado2" se você não quiser a comparação invertida).
Veja o código:
private void btAnalisar2_Click(object sender, EventArgs e) { List<clsDados> lSefaz = new List<clsDados>(); List<clsDados> lConsisaNet = new List<clsDados>(); foreach (DataGridViewRow gridRow in dataGridViewSefaz.Rows) { lSefaz.Add(new clsDados() { Id = Convert.ToInt32(gridRow.Cells[0].Value), Nome = gridRow.Cells[1].Value.ToString(), DataNascimento = Convert.ToDateTime(gridRow.Cells[2].Value) }); } foreach (DataGridViewRow gridRow in dataGridViewConsisaNet.Rows) { lConsisaNet.Add(new clsDados() { Id = Convert.ToInt32(gridRow.Cells[0].Value), Nome = gridRow.Cells[1].Value.ToString(), DataNascimento = Convert.ToDateTime(gridRow.Cells[2].Value) }); } var Resultado1 = lSefaz .Select(p => new { Id = p.Id, Nome = p.Nome, DataNascimento = p.DataNascimento }) .Except(lConsisaNet.Select(p => new { Id = p.Id, Nome = p.Nome, DataNascimento = p.DataNascimento })) .ToList();
Resultado1.ForEach(item => dataGridViewAnalise.Rows.Add(item.Id,
item.Nome,
item.DataNascimento));#region Essa parte compara as tabelas ao contrário
var Resultado2 = lConsisaNet .Select(p => new { Id = p.Id, Nome = p.Nome, DataNascimento = p.DataNascimento }) .Except(lSefaz.Select(p => new { Id = p.Id, Nome = p.Nome, DataNascimento = p.DataNascimento })) .ToList(); Resultado2.ForEach(item => dataGridViewAnalise.Rows.Add(item.Id, item.Nome, item.DataNascimento));
#endregion }
[]'s,
Fabio I.- Editado Fabio I segunda-feira, 6 de agosto de 2018 13:46
-
JehanKheller,
Nesse caso, você precisa antes rodar o "FOR" inteiro e depois escrever o que achou. É possível usar o "break" para NÃO comparar mais depois que achou uma igualdade. Vamos marcar com uma variável booleana a posição que NÃO foi encontrada ... será "FALSE" se NÃO for encontrado:
private void btAnalisar_Click(object sender, EventArgs e) { bool blnComp = false; if (radioButtonNotasAusentesConsisaNet.Checked == true) { for (int i = 0; i < dataGridViewSefaz.Rows.Count; i++) { for (int index = 0; index < dataGridViewConsisaNet.Rows.Count; index++) { if (dataGridViewSefaz.Rows[i].Cells[0].Value.ToString().Equals(dataGridViewConsisaNet.Rows[index].Cells[0].Value.ToString())) { blnComp = true; break; } } if (!blnComp) { dataGridViewAnalise.Rows.Add(dataGridViewSefaz.Rows[i].Cells[0].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[1].Value.ToString(), dataGridViewSefaz.Rows[i].Cells[2].Value.ToString()); } else { blnComp = false; } } } }
[]'s,
Fabio I.Bom dia Fabio I.
Sua solução funciona perfeitamente. É exatamente isso que eu estava buscando. Muito obrigado pela contribuição ao meu projeto.
- Marcado como Resposta JehanKheller segunda-feira, 6 de agosto de 2018 15:29
- Não Marcado como Resposta JehanKheller segunda-feira, 6 de agosto de 2018 17:24
-
JehanKheller,
Só por curiosidade criei um novo botão (btAnalisar2) para brincar de "Linq" e "Expressões Lambda", mas precisei converter tudo para "List<>" para poder me divertir.
O "Resultado2" faz a comparação "ao contrário" e pega o que não tem na tabela "dataGridViewConsisaNet" e tem na tabela "dataGridViewSefaz" (comente toda a '#region' do "Resultado2" se você não quiser a comparação invertida).
Veja o código:
private void btAnalisar2_Click(object sender, EventArgs e) { List<clsDados> lSefaz = new List<clsDados>(); List<clsDados> lConsisaNet = new List<clsDados>(); foreach (DataGridViewRow gridRow in dataGridViewSefaz.Rows) { lSefaz.Add(new clsDados() { Id = Convert.ToInt32(gridRow.Cells[0].Value), Nome = gridRow.Cells[1].Value.ToString(), DataNascimento = Convert.ToDateTime(gridRow.Cells[2].Value) }); } foreach (DataGridViewRow gridRow in dataGridViewConsisaNet.Rows) { lConsisaNet.Add(new clsDados() { Id = Convert.ToInt32(gridRow.Cells[0].Value), Nome = gridRow.Cells[1].Value.ToString(), DataNascimento = Convert.ToDateTime(gridRow.Cells[2].Value) }); } var Resultado1 = lSefaz .Select(p => new { Id = p.Id, Nome = p.Nome, DataNascimento = p.DataNascimento }) .Except(lConsisaNet.Select(p => new { Id = p.Id, Nome = p.Nome, DataNascimento = p.DataNascimento })) .ToList();
Resultado1.ForEach(item => dataGridViewAnalise.Rows.Add(item.Id,
item.Nome,
item.DataNascimento));#region Essa parte compara as tabelas ao contrário
var Resultado2 = lConsisaNet .Select(p => new { Id = p.Id, Nome = p.Nome, DataNascimento = p.DataNascimento }) .Except(lSefaz.Select(p => new { Id = p.Id, Nome = p.Nome, DataNascimento = p.DataNascimento })) .ToList(); Resultado2.ForEach(item => dataGridViewAnalise.Rows.Add(item.Id, item.Nome, item.DataNascimento));
#endregion }
[]'s,
Fabio I.- Editado JehanKheller segunda-feira, 6 de agosto de 2018 17:25