VB.NET - Manutenção de dados com DataGrid


 

O controle DataGrid do VB.NET pode ser usado de muitas formas e em diversas aplicações. Neste artigo vou mostrar como podemos usar o DataGrid para efetuar a manutenção de uma fonte de dados Access (mas podia ser MySql, FirebBird, SQL Server, etc)

 

Para este exemplo eu criei um banco de dados no Access chamado Empresa.mdb e uma tabela chamada funcionarios cuja estrutura é exibida a seguir:

 

 

O objetivo é efetuar a manutenção dos dados dos funcionários exibindo os seus dados em um DataGrid e fornecendo ao usuário as opções de : Incluir, Excluir, e Alterar dados.

 

Abaixo temos uma visão do formulário da aplicação com os controles usados e a aplicação quando da sua execução exibindo os dados:

 

O formulário da aplicação  A aplicação exibindo os dados cadastrados

 

Inicie uma nova solução chamada funcionarios no VS.NET do tipo Windows Application usando a linguagem VB.NET.

 

A seguir inclua no formulário form1.vb os componentes:

Agora vamos dar uma olhada no código do projeto e na sua estrutura atual. Ao espiar o código você veria o seguinte :

 

O código ao lado exibe o recurso de criarmos regiões identificadas onde o código fica agrupado, tornando assim , mais fácil manter e localizar um trecho de código específico.

Para ver o código sob a região basta clicar no sinal de + .

 

 

A primeira coisa a fazer é importar o namespace System.Data.OleDb , pois vamos efetuar o acesso em uma base de dados Access.

 

Vejamos a seguir o restando do código por região:

 

1-) Na region Declarations temos :

 

Dim cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Empresa.mdb")

Dim da As New OleDbDataAdapter

Dim ds As New DataSet

Dim dt As DataTable

Dim rc As Integer

Dim r As DataRow

 

Apenas estou definindo as variáveis que serão usadas no projeto e a conexão com o banco de dados Empresa.mdb

 

2-) Código da  Region Form Load:

 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


Me
.Text = "Controle de Funcionários"


Try

   da = New OleDbDataAdapter("select * from Funcionarios", cn)

   da.Fill(ds, "Funcionarios")

   dt = ds.Tables(0)

   DataGrid1.DataSource = dt

   formload()

Catch ex As Exception

   MessageBox.Show(ex.Message)

End Try
 

End Sub

 

- Atribuímos o título - Controle de Funcionários - ao formulário atual.

 

- Criamos um DataAdpater - da - , extraindo dados da tabela Funcionarios  na conexão cn.

 

- Preenchemos um DataSet - ds - , e, obtendo a primeira e única tabela (Tables(0)) atribuímos ao DataGrid para exibir os dados.

 

3-) Na Region DataGrid o código abaixo obtém a linha atual selecionada(rc = DataGrid1.CurrentRowIndex) e a exibe nas caixas de texto.

 

Private Sub DataGrid1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGrid1.MouseUp


rc = DataGrid1.CurrentRowIndex

obtemFuncionario(rc)


TextBox1.ReadOnly =
True

TextBox2.ReadOnly = False

TextBox3.ReadOnly = False

TextBox4.ReadOnly = False

edita.Enabled = True

deleta.Enabled = True

cmdInclui.Text = "Inclui"

End Sub

 

4-) Na Region TextBoxes temos o seguinte código:

 

Private Sub TextBox2_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox2.KeyPress

  e.Handled = SomenteCaracteres(Asc(e.KeyChar))

End Sub


Private Sub TextBox3_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox3.KeyPress

   e.Handled = SomenteNumeros(Asc(e.KeyChar))

End Sub
 

Private Sub TextBox4_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox4.KeyPress

   e.Handled = SomenteCaracteres(Asc(e.KeyChar))

End Sub

 

Em cada evento KeyPress dos textboxes : TextBox1 (Nome) ,  TextBox1 (Salário) , TextBox1 (Setor) estou atribuindo código que faz o seguinte:

 

a) TextBox2(Nome) :   e.Handled = SomenteCaracteres(Asc(e.KeyChar)) - Permite somente a impostação de valores caracteres (de a a z)

 

b) TextBox3(Salario) :   e.Handled = SomenteNumeros(Asc(e.KeyChar)) - Permite somente a impostação de valores numéricos (dígitos de 0 a 9)

 

a) TextBox4(Setor) :   e.Handled = SomenteCaracteres(Asc(e.KeyChar)) - Permite somente a impostação de valores caracteres (de a a z)

 

5-) Na Region Button temos o código atribuído a cada botão de comando. Vamos mostrar cada um deles:

 

a-) O botão Inclui também faz as vezes do botão cancela, por isto, eu verifico se o texto do botão acionado é Inclui, e, neste caso é feita a preparação para a inclusão dos dados. O foco vai para o TextBox2 (Nome) e ao TextBox1(Código) é atribuído um número inteiro que corresponde ao número de registros mais um.

 

Se o texto do botão for - Cancela - a rotina carregaFormulario será chamada. Ela apenas limpa os TextBox e desabilita os botões necessários.

 

Private Sub cmdInclui_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdInclui.Click


Try

    If cmdInclui.Text = "Inclui" Then
 

      TextBox2.Focus()

      TextBox1.Text = Integer.Parse(dt.Rows(dt.Rows.Count - 1).Item(0)) + 1

      TextBox1.ReadOnly = True

      TextBox2.ReadOnly = False

      TextBox3.ReadOnly = False

      TextBox4.ReadOnly = False

      TextBox2.Clear()

      TextBox3.Clear()

      TextBox4.Clear()

 

      Me.edita.Enabled = False

        Me.deleta.Enabled = False

        Me.salva.Enabled = True

       Me.cmdInclui.Text = "Cancela"


   ElseIf
cmdInclui.Text = "Cancela"
Then

       carregaFormulario()

       Me.cmdInclui.Text = "Inclui"

   End If

Catch ex As Exception

   MessageBox.Show(ex.Message)

End Try

 

End Sub

 

b-) O código do botão Deleta exibido abaixo faz o seguinte :

 

- obtém a linha atual selecionada do DataGrid - Dim dr As DataRow = dt.Rows(DataGrid1.CurrentRowIndex)

- Obtém o nome da linha atual tomando o cuidado de efetuar a conversão para String - Dim nome As String = CType(dr.Item(1), String)

- Solicita a confirmação da exclusão

- Se houver confirmação deverá ser criado um objeto CommandBuilder para que sejam gerados automaticamente os comandos que conciliam as mudanças feitas para o DataSet com o banco de dados associado. Sem isto a operação irá falhar.

- A seguir usamos o método Delete() para marcar a linha para ser removida. A remoção ocorre quando  o método AcceptChanges for invocado. (Poderiamos ter usado o método Remove() que remove a linha da coleção de linhas de imediato).

- Aplicamos o método Update() do objeto DataAdapter. Ao fazer isto o DataAdapter examina a propriedade RowState e executa o comando SQL (INSERT,UPDATE,DELETE) requerido para cada linha baseado na ordem dos índices configurados no DataSet.

 

Private Sub deleta_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles deleta.Click


Dim
dt As DataTable = DataGrid1.DataSource

Dim dr As DataRow = dt.Rows(DataGrid1.CurrentRowIndex)

Dim nome As String = CType(dr.Item(1), String)


If
MessageBox.Show("Confirma exclusão deste registro => " & nome.ToUpper, "Deleta", MessageBoxButtons.YesNo, _
MessageBoxIcon.Warning) = DialogResult.No
Then

    MsgBox("Operação Cancelada.", MsgBoxStyle.Information, "Cancelada.")

    Exit Sub

End If
 

rc = DataGrid1.CurrentRowIndex

dt.Rows(rc).Delete()


MsgBox("Exclusão realizada com sucesso.", MsgBoxStyle.Information, "Sucesso")

da.Update(ds, "Funcionarios")


carregaFormulario()


End
Sub

 

c-) O código do botão - Salva - realiza as seguintes tarefas:

 

- Cria um objeto CommandBuilder para conciliar as alterações feitas no DataSet com o Banco de dados

- obtém o código do funcionário - str = TextBox1.Text

- converte o código para Inteiro - id = Integer.Parse(str)

- Verifica se o código corresponde ao um novo registro e neste caso cria uma nova linha na tabela -  r = dt.NewRow

- atribui os valores das caixas de texto ao vetor de linhas e os adiciona na coleção de linhas - dt.Rows.Add(r)

- Invoca o método Update() do objeto DataAdapter. Ao fazer isto o DataAdapter examina a propriedade RowState e executa o comando SQL (INSERT,UPDATE,DELETE) requerido para cada linha baseado na ordem dos índices configurados no DataSet.

- se o código já existir então é feito uma atualização dos dados.

 

Private Sub salva_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles salva.Click


Dim
id As
Integer

Dim str As String

Dim cmd As New OleDbCommandBuilder(da)


str = TextBox1.Text

id = Integer.Parse(str)


If
id = dt.Rows.Count + 1
Then

   r = dt.NewRow

  r(0) = TextBox1.Text

  r(1) = TextBox2.Text

  r(2) = TextBox3.Text

  r(3) = TextBox4.Text

  dt.Rows.Add(r)


  da.Update(ds, "Funcionarios")
 

  MessageBox.Show("Inclusão realizada com sucesso.")

  Me.cmdInclui.Text = "Inclui"

  Me.cmdInclui.Enabled = True

  Me.edita.Enabled = True

  Me.deleta.Enabled = True

  Me.salva.Enabled = False
 

ElseIf id < dt.Rows.Count + 1 Then


  r = dt.Rows(id - 1)

  r("nome") = TextBox2.Text

  r("salario") = TextBox3.Text

  r("setor") = TextBox4.Text

  da.Update(ds, "Funcionarios")

  Me.salva.Enabled = False


End
If

 

End Sub

 

d-) O botão Edita , cujo código esta a seguir, apenas obtém a linha selecionada e habilita e desabilita os botões necessários.

 

Private Sub edita_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles edita.Click


r = dt.Rows(rc)


TextBox1.ReadOnly =
True

TextBox2.ReadOnly = False

TextBox3.ReadOnly = False

TextBox4.ReadOnly = False


cmdInclui.Text = "Cancela"


Me
.salva.Enabled =
True

Me.edita.Enabled = False


cmdInclui.Text = "Cancela"


Me
.cmdInclui.Enabled =
True

Me.deleta.Enabled = False


End
Sub

 

A última Region é a Methods que contém as rotinas :

Public Sub obtemFuncionario(ByVal i As Integer)

   r = dt.Rows(i)

   TextBox1.Text = r("codigo")

   TextBox2.Text = r("nome")

   TextBox3.Text = r("salario")

   TextBox4.Text = r("setor")

End Sub
 

Public Sub carregaFormulario()

   Me.TextBox1.ReadOnly = True

    Me.TextBox2.ReadOnly = True

   Me.TextBox3.ReadOnly = True

    Me.TextBox4.ReadOnly = True

   TextBox1.Clear()

   TextBox2.Clear()

   TextBox3.Clear()

   TextBox4.Clear()

   Me.cmdInclui.Enabled = True

    Me.edita.Enabled = False

    Me.salva.Enabled = False

    Me.deleta.Enabled = False

End Sub

 

Public Function SomenteNumeros(ByVal Key As String) As Boolean

If (Key >= 48 And Key <= 57) Or Key = 8 Then

   SomenteNumeros = False

Else

   SomenteNumeros = True

End If
End
Function
 

Public Function SomenteCaracteres(ByVal key As String) As Boolean


If
(key >= 65 And key <= 90) Or (key >= 97 And key <= 122) Or key = 8
Then

    SomenteCaracteres = False

Else

    SomenteCaracteres = True

    MsgBox("informe somente caracteres alfanuméricos.", MsgBoxStyle.Information, "Não informe números.")

End If

End Function

 

 

Para finalizar temos ainda o código que será executado quando o formulário for fechado.

 

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing

If MessageBox.Show("Deseja realmente encerrar a aplicação ? ", "Encerrar", MessageBoxButtons.YesNo, MessageBoxIcon.Stop) = DialogResult.No Then

    e.Cancel = True

End If

End Sub

 

E chegamos ao fim da nossa saga para manter dados usando um Datagrid via DataSet com ADO.NET.

 

Creio que não existem dificuldades insuperáveis no código exibido, pelo contrário , ele é muito simples , agora resta a você aprender e refinar pois além de esta não ser a única forma de fazer isto usando ADO.NET com certeza o código pode ser otimizado.

 

Pegue o projeto completo aqui : manDados.zip

 

Eu sei , é apenas VB,  but I like it  !!!
 

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

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ?


  Gostou
?   Compartilhe no Facebook   Compartilhe no Twitter

 

Referências:


José Carlos Macoratti