C# - DataGridView - Salvando o conteúdo e realizando cálculos


Neste artigo eu vou mostrar como podemos salvar o conteúdo de um controle DataGridView e realizar cálculos que envolvam as células do controle.

Imagine que você tenha um formulário contendo um controle DataGridView que esta sendo usado para incluir informações de itens de um pedido :

Nesta interface o usuário poderá digitar diretamente no DataGridView informando a descrição, a quantidade e o preço sendo que o valor total é calculado automaticamente pela multiplicação das colunas quantidade e preço. O total geral exibido em uma caixa de texto abaixo do DataGridView é uma somatória dos valores da coluna Total.

Ao final da entrada dos dados o usuário poderá clicar no botão Salvar para salvar todos os valores informados no DataGridView.

Então, vamos ver como é que se faz isso...

Criando o Projeto

Abra o Visual Studio 2012 Express for Windows desktop e clique em New Project;

Escolha a linguagem Visual C# -> Windows e a o template Windows Forms Application informando o nome DataGridView_WF;

No formulário padrão form1.cs inclua a partir da ToolBox os seguintes controles:

Disponha os controles no formulário conforme o leiaute abaixo:

Criando o banco de dados e a tabela

Eu criei um banco de dados chamado Vendas.mdf no SQL Server Local DB e a tabela Itens que possui a seguinte estrutura:

A string de conexão do banco de dados esta armazenada no arquivo App.Config:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<startup>

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />

</startup>

<connectionStrings>

     <add name="VendasSQL" connectionString="Data Source=(localDB)\v11.0;Initial Catalog=Vendas;Integrated Security=True"/>

</connectionStrings>

</configuration>

 

No menu PROJECT clique em Add Reference e selecione o namespace System.Configuration que será usado para acessar o arquivo de configuração App.Config.

No formulário form1.cs declare os seguintes namespaces:

using System;

using System.Configuration;

using System.Data.SqlClient;

using System.Windows.Forms;

Agora no evento Load do formulário form1.cs inclua o código abaixo que acessa o banco de dados Vendas e exibe os registros no controle DataGridView:

 private void Form1_Load(object sender, EventArgs e)
  {
            try
            {
                DataTable oTable = new DataTable();
                using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["VendasSQL"].ConnectionString))
                {
                    string sql = "Select * from Itens";
                    con.Open();
                    SqlCommand cmd = new SqlCommand(sql, con);
                    cmd.CommandText = sql;
                    cmd.CommandType = CommandType.Text;
                    SqlDataReader oDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                    oTable.Load(oDataReader);
                    gdvItens.DataSource = oTable;
                    formataGridView();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
 }

A rotina formataGridView realiza uma formatação no controle DataGridView permitindo uma exibição formata das colunas:

 private void formataGridView()
 {
            var grade = gdvItens;
            grade.AutoGenerateColumns = false;
            grade.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders;
            grade.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
            //altera a cor das linhas alternadas no grid
            grade.RowsDefaultCellStyle.BackColor = Color.White;
            grade.AlternatingRowsDefaultCellStyle.BackColor = Color.Cyan;
            //altera o nome das colunas
            grade.Columns[0].HeaderText = "Id";
            grade.Columns[1].HeaderText = "Descrição";
            grade.Columns[2].HeaderText = "Quantidade";
            grade.Columns[3].HeaderText = "Preco";
            grade.Columns[4].HeaderText = "Total";
            grade.Columns[0].Width = 70;
            grade.Columns[1].Width = 150;
            //formata as colunas valor, vencimento e pagamento
            grade.Columns[3].DefaultCellStyle.Format = "c";
            grade.Columns[4].DefaultCellStyle.Format = "c";
            //seleciona a linha inteira
            grade.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            //não permite seleção de multiplas linhas   
            grade.MultiSelect = false;
            // exibe nulos formatados
            //grade.DefaultCellStyle.NullValue = " - ";
            //permite que o texto maior que célula não seja truncado

            grade.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
            //define o alinhamento à direita
            grade.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            grade.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
  }

No evento Click do botão Salvar temos a chamada para a rotina SalvarDados():

 private void btnSalvar_Click(object sender, EventArgs e)
 {
            SalvarDados();
 }

O código da rotina é mostrado a seguir:

public void SalvarDados()
 {
            try
            {
                if (gdvItens.Rows.Count > 1)
                {
                    for (int i = 0; i <= gdvItens.Rows.Count - 1; i++)
                    {
                         int col1 = Convert.ToInt32(gdvItens.Rows[i].Cells[0].Value); //id
                         string col2 = gdvItens.Rows[i].Cells[1].Value.ToString(); //Descricao
                         int col3 = Convert.ToInt32(gdvItens.Rows[i].Cells[2].Value); //Quantidade
                         decimal col4 = Convert.ToDecimal(gdvItens.Rows[i].Cells[3].Value); //Preco
                         decimal col5 = Convert.ToDecimal(gdvItens.Rows[i].Cells[4].Value); //Total

                        using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["VendasSQL"].ConnectionString))
                        {
                            string insert = "INSERT INTO Itens(Id,Descricao,Quantidade,Preco,Total) VALUES (@Codigo,@Descricao,@Quantidade,@Preco,@Total)";
                            con.Open();
                            SqlCommand cmd = new SqlCommand(insert, con);
                            cmd.Parameters.AddWithValue("@Codigo", col1);
                            cmd.Parameters.AddWithValue("@Descricao", col2);
                            cmd.Parameters.AddWithValue("@Quantidade", col3);
                            cmd.Parameters.AddWithValue("@Preco", col4);
                            cmd.Parameters.AddWithValue("@Total", col5);

                            cmd.ExecuteNonQuery();
                            con.Close();
                        }
                    }
                }
          MessageBox.Show("Dados incluídos com sucesso !!", "Inclusão", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
 }

Este código verifica se existem linhas no controle DataGridView ( dvItens.Rows.Count > 1) e em caso positivo percorre cada uma das linhas atribuindo os valores das células à variáveis.

A seguir abrirmos uma conexão com o banco de dados Vendas e definimos a instrução SQL INSERT/INTO passando os parâmetros para o objeto Command.

O método ExecuteNonQuery inclua os valores das células obtidas a partir do DataGridView na tabela Itens.

Para realizar o cálculo automático das colunas Quantidade e Preço vamos usar o evento CellEndEdit definindo o código abaixo:

private void gdvItens_CellEndEdit(object sender, DataGridViewCellEventArgs e)
 {
            try
            {
                if (e.ColumnIndex == 3)
                {
                    decimal cell1 = Convert.ToDecimal(gdvItens.CurrentRow.Cells[2].Value);
                    decimal cell2 = Convert.ToDecimal(gdvItens.CurrentRow.Cells[3].Value);
                    if (cell1.ToString() != "" && cell2.ToString() != "")
                    {
                        gdvItens.CurrentRow.Cells[4].Value = cell1 * cell2;
                    }
                }

                decimal valorTotal = 0;
                string valor = "";

                if (gdvItens.CurrentRow.Cells[4].Value != null)
                {
                    valor = gdvItens.CurrentRow.Cells[4].Value.ToString();
                    if (!valor.Equals(""))
                    {
                        for (int i = 0; i <= gdvItens.RowCount - 1; i++)
                        {
                            if (gdvItens.Rows[i].Cells[4].Value != null)
                                valorTotal += Convert.ToDecimal(gdvItens.Rows[i].Cells[4].Value);
                        }
                        if (valorTotal == 0)
                        {
                            MessageBox.Show("Nenhum registro encontrado");
                        }
                        txtTotal.Text = valorTotal.ToString("C");
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

No código verificamos se a coluna atual é a coluna Preco (e.ColumnIndex == 3). Em caso positivo estamos calculando o valor da coluna total :

decimal cell1 = Convert.ToDecimal(gdvItens.CurrentRow.Cells[2].Value);
decimal cell2 = Convert.ToDecimal(gdvItens.CurrentRow.Cells[3].Value);
if (cell1.ToString() != "" && cell2.ToString() != "")
{
         gdvItens.CurrentRow.Cells[4].Value = cell1 * cell2;
}

A seguir verificamos se o valor da coluna Total não é nulo e estamos somando os valores desta coluna e exibindo no controle TextBox.(txtTotal)

Abaixo vemos o projeto em execução:

O objetivo deste artigo é mostrar algumas técnicas que podem ser uteis no dia a dia e que você pode adaptar para a sua situação.

Eu não estou encorajando você a usar essa implementação em seu projeto visto que no exemplo eu tenho código de acesso a dados no formulário e não em uma camada de acesso a dados como seria o correto.

Alerto também para o fato de que eu não estou realizando validações na entrada de dados o que é obrigatório fazer em uma aplicação de produção.

Pegue o projeto completo aqui :   DataGridView_WF.zip

Joã 3:35 O Pai ama ao Filho, e todas as coisas entregou nas suas mãos.

Joã 3:36 Quem crê no Filho tem a vida eterna; o que, porém, desobedece ao Filho não verá a vida, mas sobre ele permanece a ira de Deus.

 

Veja os Destaques e novidades do SUPER DVD Visual Basic  (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Veja mais sistemas completos para a plataforma .NET no Super DVD .NET , confira...

Quer aprender C# ??

Chegou o Super DVD C#  com exclusivo material de suporte e vídeo aulas com curso básico sobre C#.

Veja também os Cursos com vídeo aulas e projetos exemplos:

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti