Usuário com melhor resposta
Transferência de dados entre DataGridView

Pergunta
-
Boa noite pessoal.
Estou com um problema para transferir dados entre datagridview, vou tentar colocar de forma clara o meu problema.
Tenho o form1 com um botão ENVIAR e um datagridview1, onde neste datagridview1 estará relacionado vários pedidos. O usuário selecionará alguns pedidos e clicará em ENVIAR. Abrirá um outro form (form2) com um datagridview2 contendo todos os pedidos selecionados no datagridview1 (do form1). As duas telas ficam abertas, tanto o form1 quanto o form2.
O objetivo é enviar os dados do segundo form por e-mail dentro do C#.
Desde já agradeço a todos que contribuirão para a solução do meu problema.
Forte abraço a todos e até mas!!!!
Respostas
-
Olá Alberto,
estou com muito sono, por isso fiz um exemplo bem simples e em vb.net, espero que ajude
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim dt As New DataTable dt.Columns.Add("teste1") dt.Columns.Add("teste2") dt.Columns.Add("teste3") For i As Integer = 0 To 10 Dim row As DataRow = dt.NewRow row.Item("Teste1") = "11" row.Item("Teste2") = "11" row.Item("Teste3") = "11" dt.Rows.Add(row) Next DataGridView1.DataSource = dt ''DataGridView1.CurrentCell = DataGridView1.Rows(20).Cells(0) End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim dt As New DataTable dt.Columns.Add("teste1") dt.Columns.Add("teste2") dt.Columns.Add("teste3") For Each d As DataGridViewRow In DataGridView1.Rows If d.Cells("Column1").Value = True Then Dim c As DataRow = dt.NewRow c.Item("Teste1") = d.Cells(1).Value c.Item("Teste2") = d.Cells(2).Value c.Item("Teste3") = d.Cells(3).Value dt.Rows.Add(c) End If Next DataGridView2.DataSource = dt End Sub
no load estou carregando o grid1 e button estou verificando o que foi checado no grid1 e jogo no grid2.
Segue abaixo vários links falando sobre envio de email no c#:
http://www.devmedia.com.br/como-enviar-um-e-mail-utilizando-c/15285
http://wiki.locaweb.com.br/pt-br/Envio_de_e-mails_via_.NET_utilizando_o_System.Net.Mail
http://code.msdn.microsoft.com/windowsdesktop/Envio-de-E-mail-em-C-84c68ce6
http://www.macoratti.net/10/12/c_email2.htm
Qualquer dúvida posta ae.
Att,
Wennder A. dos Santos
Se minha resposta solucionou seu problema ou sua dúvida marque como Resposta ou se foi útil marque como útil. Isso ajuda outras pessoas com o mesmo problema ou dúvida.- Editado Wennder SantosMVP sexta-feira, 17 de janeiro de 2014 14:23
- Sugerido como Resposta Diego de Almeida Barreto (Lewis) sexta-feira, 17 de janeiro de 2014 14:35
- Marcado como Resposta AlbertoGold quarta-feira, 21 de outubro de 2015 15:15
Todas as Respostas
-
Olá Alberto,
estou com muito sono, por isso fiz um exemplo bem simples e em vb.net, espero que ajude
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim dt As New DataTable dt.Columns.Add("teste1") dt.Columns.Add("teste2") dt.Columns.Add("teste3") For i As Integer = 0 To 10 Dim row As DataRow = dt.NewRow row.Item("Teste1") = "11" row.Item("Teste2") = "11" row.Item("Teste3") = "11" dt.Rows.Add(row) Next DataGridView1.DataSource = dt ''DataGridView1.CurrentCell = DataGridView1.Rows(20).Cells(0) End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim dt As New DataTable dt.Columns.Add("teste1") dt.Columns.Add("teste2") dt.Columns.Add("teste3") For Each d As DataGridViewRow In DataGridView1.Rows If d.Cells("Column1").Value = True Then Dim c As DataRow = dt.NewRow c.Item("Teste1") = d.Cells(1).Value c.Item("Teste2") = d.Cells(2).Value c.Item("Teste3") = d.Cells(3).Value dt.Rows.Add(c) End If Next DataGridView2.DataSource = dt End Sub
no load estou carregando o grid1 e button estou verificando o que foi checado no grid1 e jogo no grid2.
Segue abaixo vários links falando sobre envio de email no c#:
http://www.devmedia.com.br/como-enviar-um-e-mail-utilizando-c/15285
http://wiki.locaweb.com.br/pt-br/Envio_de_e-mails_via_.NET_utilizando_o_System.Net.Mail
http://code.msdn.microsoft.com/windowsdesktop/Envio-de-E-mail-em-C-84c68ce6
http://www.macoratti.net/10/12/c_email2.htm
Qualquer dúvida posta ae.
Att,
Wennder A. dos Santos
Se minha resposta solucionou seu problema ou sua dúvida marque como Resposta ou se foi útil marque como útil. Isso ajuda outras pessoas com o mesmo problema ou dúvida.- Editado Wennder SantosMVP sexta-feira, 17 de janeiro de 2014 14:23
- Sugerido como Resposta Diego de Almeida Barreto (Lewis) sexta-feira, 17 de janeiro de 2014 14:35
- Marcado como Resposta AlbertoGold quarta-feira, 21 de outubro de 2015 15:15
-
-
Bom dia Wennder.
Não consegui implementar o seu exemplo. Deu o seguinte erro:
"An unhandled exception of type 'System.NullReferenceException' occurred in Integra Processos.exe
Additional information: Object reference not set to an instance of an object."Já tentei criar a tabela em uma classe à parte, mas também não está dando certo. Dá o erro: "Object reference not set to an instance of an object."
Mas a parte de envio de e-mail já está funcionando corretamente, só está faltando mesmo transferir as informações para o segundo datagrid, que será o corpo do e-mail.
Mas mesmo assim lhe agradeço a boa vontade em me ajudar. Caso tenha alguma outra solução, serei grato.
Valeu Wennder, abraçoss e até mas.
-
-
Olá Alberto,
este erro está acontecendo quando você está tentando carregar o grid1 não é? pode postar o trecho de código onde está acontecendo o erro?
Wennder
- Editado Wennder SantosMVP sábado, 18 de janeiro de 2014 12:24
-
Bom dia Wennder.
Segue o código:
private void InserirDadosParaTransferencia() { bdpedidos tab = new bdpedidos(); tab.Tabela.Columns.Add("teste1"); tab.Tabela.Columns.Add("teste2"); tab.Tabela.Columns.Add("teste3"); tab.Tabela.Columns.Add("teste4"); for (int i = 0; i < dgDados.Rows.Count; i++) { if (dgDados.Rows[i].Cells[1].Selected) { tab.Tabela.Rows.Add(Convert.ToString(dgDados.Rows[i].Cells[0].Value), Convert.ToString(dgDados.Rows[i].Cells[0].Value), Convert.ToString(dgDados.Rows[i].Cells[0].Value), Convert.ToString(dgDados.Rows[i].Cells[0].Value)); } } }
Dá o erro na primeira linha:tab.Tabela.Columns.Add("teste1");
-
-
-
-
Wenner, já tentei de várias maneiras. Agora tentei fazer dentro da classe do form, mas também deu o mesmo erro.
Esta foi a que tentei agora.
namespace Integra_Processos { public partial class Ciclo : Form { public DataTable ped;
Mas antes estava declarando na classe do pedido
private DataTable ctabela; public DataTable Tabela { get { return ctabela; } set { ctabela = value; } }
Eu não estou sabendo manipular a DataTable.
- Editado AlbertoGold sábado, 18 de janeiro de 2014 13:30
-
Alberto,
no .net existem 2 tipos de variáveis, as de valor e as de referência.
as de valor = int, boolean, decimal ..
as de instancia = todas que você usa o "new" para poder acessar e o datatable é uma dessa.
Quando você usa o "new" para declarar a variável é alocado na memória, definida pelo framework como memória heap, para essa variável. Como você não está usando o "new" ele não está encontrando, por isso o erro System.NullReferenceException.
Repare em como é declarado o datatable no meu exemplo.
Quando tiver um tempinho vale a pena ler essa explicação
http://www.macoratti.net/vbn_conc.htm
Wennder
- Editado Wennder SantosMVP sábado, 18 de janeiro de 2014 13:42
-
-
-
Este é o código no form1:
public void InserirDadosParaTransferencia() { DataTable ped = new DataTable(); ped.Columns.Add("teste1"); ped.Columns.Add("teste2"); ped.Columns.Add("teste3"); ped.Columns.Add("teste4"); for (int i = 0; i < dgDados.Rows.Count; i++) { if (dgDados.Rows[i].Cells[1].Selected) { ped.Rows.Add(Convert.ToString(dgDados.Rows[i].Cells[0].Value), Convert.ToString(dgDados.Rows[i].Cells[0].Value), Convert.ToString(dgDados.Rows[i].Cells[0].Value), Convert.ToString(dgDados.Rows[i].Cells[0].Value)); } } }
Não estou conseguindo pegar este "ped" e transferir para o form2.
-
-
-
ok,
meu exemplo no começo está fazendo corretamente a cópia das informações, você só precisava converter para c#, de uma olhada abaixo, só troque a validação do if para sua validação, pois, aqui estou usando um checkbox para selecionar, dessa forma pode ser selecionada mais de uma linha por vez.
DataTable ped = new DataTable(); ped.Columns.Add("teste1"); ped.Columns.Add("teste2"); ped.Columns.Add("teste3"); ped.Columns.Add("teste4"); foreach (DataGridViewRow d in dataGridView1.Rows) { if (Convert.ToBoolean(d.Cells[0].Value) == true) { DataRow row = ped.NewRow(); row["teste1"] = d.Cells[1].Value; row["teste2"] = d.Cells[2].Value; row["teste3"] = d.Cells[3].Value; row["teste4"] = d.Cells[4].Value; ped.Rows.Add(row); } }
Wennder
-
-
-
Boa noite Wennder.
Pior que é!!! Estava pulando esta etapa mesmo, fiz o que você falou e funcionou, porem só com uma linha, quando eu marco duas ele dá erro. Não está acrescentando linha no "ped". Dá o erro:
An unhandled exception of type 'System.ArgumentException' occurred in System.Data.dll
Additional information: This row already belongs to this table.Tentei colocar: ped.rows[i].add(row); Mas não aceita!!!
E depois, como vou fazer para conseguir passar para o segund grid no segundo form?
-
-
Bom dia Wennder.
Mas foi assim que fiz, conforme você tinha falado anteriormente, mas deu o erro: An unhandled exception of type 'System.ArgumentException' occurred in System.Data.dll
Additional information: This row already belongs to this table.Funcionou quando marquei somente uma linha, quando fui fazer o teste com duas linhas, deu este erro. Por isso tentei colocar o índice para adicionar a linha. É como se tivesse tentando salvar sobre a linha já existente. (Estou deduzindo que seja isso)
-
Boa tarde Wennder.
Estamos quase lá!!! Repassei o código e consegui achar onde que eu errei. Olhei, reolhei seu código e ví que eu coloquei o código DataRow row = ped.NewRow(); no lugar errado, por isso ele não estava criando a nova linha.
Só ainda não consegui descobrir como vou passar para o segundo form (form2), os pedidos guardados em ped.
Desde já lhe agradeço pela grande força que está me dando. Está me ajudando muito.
Valeu Wennder!!!
-
Olá,
da uma olhada nesses links, vão te ajudar a fazer isso:
http://www.linhadecodigo.com.br/artigo/1741/trocando-informacoes-entre-windows-forms-em-csharp.aspx
Wennder
-
Alberto,
Você poderia tentar usar a orientação neste objeto tendo uma classe Pedido por exemplo e para o form2 passaria um List<Pedido> como parametro, como segue abaixo:
public class Pedido { public int ID { get; set; } public string Numero { get; set; } public decimal Valor { get; set; } }
Código que seria usada para preencher o dataGridView1
private void PreencheDataGridView1() { // aqui eu apenas estou preenchendo uma lsita ficticia para exibir oos dados aqui seria sua busca do banco p/ retornar a list List<Pedido> lstPedidos = new List<Pedido>(); for (int i = 0; i < 100; i++) { Pedido p = new Pedido() { ID = i + 1, Numero = i.ToString(), Valor = i + 100 }; } dataGridView1.DataSource = lstPedidos; }
E este código seria usadao no click do botão que chama o form2 (que recebe como parâmetro no inicializador uma list<pedido>.
void btnEnviar_Click(object sender, EventArgs e) { var qrSelecionados = from row in dataGridView1.SelectedRows.Cast<DataGridViewRow>() select new Pedido() { ID = Convert.ToInt32(row.Cells["ColunaQueArmazenaOIdPedido"].Value), Numero = row.Cells["ColunaQueArmazenaONUmeroPedido"].Value.ToString(), Valor = Convert.ToDecimal(row.Cells["ColunaQueArmazenaOValorDoPedido"].Value) }; Form2 frm = new Form2(qrSelecionados.ToList()); frm.ShowDialog(); }
Acho que assim fica bem fácil, você poderia até usar uma coluna com check box e fazer dai um where no link acima algo que ficaria mais ou menos como o código abaixo:
void btnEnviar_Click(object sender, EventArgs e) { var qrSelecionados = from row in dataGridView1.Rows.Cast<DataGridViewRow>() where Convert.ToBoolean(row.Cells["ColunaCheckBox"]) select new Pedido() { ID = Convert.ToInt32(row.Cells["ColunaQueArmazenaOIdPedido"].Value), Numero = row.Cells["ColunaQueArmazenaONUmeroPedido"].Value.ToString(), Valor = Convert.ToDecimal(row.Cells["ColunaQueArmazenaOValorDoPedido"].Value) }; Form2 frm = new Form2(qrSelecionados.ToList()); frm.ShowDialog(); }
Ai no inicializador do seu form você faria apenas dataGridView2.DataSource=listaPedidoQueVeioComoParametro;
Espero ter ajudado,
Att.
- Editado Lucas D Santos segunda-feira, 20 de janeiro de 2014 13:20
-
Boa noite Wennder.
Dei uma olhada nas suas dicas, mas este tipo de transferência, com um dado, eu consigo fazer, inclusive usei muito isso no meu programa. O meu problema está sendo transferir conjunto de dados.
Mas mesmo assim lhe agradeço imensamente Wennder.
Vou dar uma estudada melhor na dica do nosso amigo Lucas, pois tentei fazer, mas não funcionou.
Valeu Wenner, abraçoss e até mas.
-
Boa noite Lucas.
Tentei implementar sua sugestão, porem não deu certo. Mas vou dar uma estudada melhor nela de depois lhe dou um retorno mais certo. É porque estou meio na correria e não estou tendo muito tempo para mexer no programa. Mas deste final de semana não passa.
Desde já lhe agradeço pela sua força.
Mas acho que a idéia seria fazer uma lista global (não sei se é possível em c#) para poder acessá-la do form2.
Abraçoss e até mas.
-
-
Boa noite Wennder e Lucas.
Desculpe a demora do retorno. Como eu falei, estou na correria. Mas vamos lá!!!
Vejam só, eu acabei fazendo diferente das duas sugestões. Tentei fazer da sua forma Lucas, e deu um erro.
Vou postar aqui a forma que fiz aproveitando as sugestões dadas por vocês:
Tenho uma classe bdpedidos e nesta classe eu criei a tabela:
private static DataTable ctabela; public DataTable tabela { get { return ctabela; } set { ctabela = value; } }
Na classe do form1, coloquei este código (99,9% sugerido pelo nosso amigo Wennder):
public void InserirDadosParaTransferencia() { DataTable ped = new DataTable(); ped.Columns.Add("Cliente"); ped.Columns.Add("Ordem Venda"); ped.Columns.Add("Transportadora"); ped.Columns.Add("Volume"); for (int i = 0; i < dgDados.Rows.Count; i++) { if (dgDados.Rows[i].Cells[1].Selected) { DataRow row = ped.NewRow(); row["Cliente"] = dgDados.Rows[i].Cells[0].Value; row["Ordem Venda"] = dgDados.Rows[i].Cells[1].Value; row["Transportadora"] = dgDados.Rows[i].Cells[2].Value; row["Volume"] = dgDados.Rows[i].Cells[3].Value; ped.Rows.Add(row); } } bdpedidos ax = new bdpedidos(); ax.tabela = ped; }
E no load do form2, coloquei assim:
private void Email_Load(object sender, EventArgs e) { bdpedidos ab = new bdpedidos(); dgmensagem.DataSource = ab.tabela; }
Para mim funcionou perfeitamente!!!
O datagridview2 fica preenchido com todos os ítens selecionados no datagridview1.
Valeu Wennder e Lucas pela força e espero que o meu questionamento e as soluções apresentadas por vocês ajudem os apaixonados por C#.
Abraçoss e até mas!!!