VB .NET - Cadastro de Contatos com Foto no SQL Server


A figura abaixo mostra a tela principal do aplicativo para Cadastro de contatos com foto no SQL Server 2008 feito na linguagem VB .NET.

Ele apresenta as funcionalidades básicas de acesso, navegação e manutenção de dados usando um banco de dados SQL Server.

O objetivo deste artigo é mostrar como criar esse aplicativo usando o Visual Basic 2010 Express Edition e o SQL Server 2008 Express Edition.

Existem muitas maneiras diferentes de criarmos uma aplicação como essa no Visual Basic .NET vou citar algumas delas:

Nesta aplicação eu vou incluir o código no formulário por questão de simplicidade. Não vou criar uma aplicação em camadas como sugere as boas práticas.

 

Em um outro artigo eu vou mostrar como ajustar esta aplicação para uma aplicação em camadas.

  Criando o Banco de Dados e a Tabela

Eu vou utilizar a última por apresentar os conceitos básicos das tarefas de acesso e manutenção de dados em um SGBD relacional como SQL Server.

Vou começar criando o banco de dados Cadastro e a tabela Contatos que serão usados no projeto.

Para realizar esta tarefa vou usar o SQL Server 2008 Management Studio (SSMS).

Na figura abaixo temos o banco de dados Cadastro e a tabela Contatos. A estrutura da tabela contato indica que o campo id é uma chave primária do tipo identity e que as imagens serão armazenadas no campo do tipo image;

Após criar o banco de dados e a tabela vamos definir a string de conexão nas propriedades do projeto na guia Settings onde criamos a variável CadastroConnectionString e definimos a string de conexão como sendo : Server=.\SQLExpress;;Initial Catalog=Cadastro;Integrated Security=SSPI

  Criando o projeto Windows Forms

Abra o Visual Basic 2010 Express Edition e no menu File Clique em New Project selecionando o template Windows Forms Application com o nome CadastroVBNET;

A seguir defina o leiaute do formulário padrão form1.vb conforme a imagem a seguir:

 
  • 6 Labels - lblCodigo (as demais labels adotarão o nome padrão)
  • 6 TextBox - txtNome,TxtSobrenome,txtCidade,TxtEstado,txtNascimento e txtEmail
  • 7 Buttons (Operações0 - btnProcurarFoto,btnCadastrar,btnAlterar,btnDeletar,btnLocalizar, btnCarregaDados e btnSair
  • 4 Buttons (Navegação) - btnPrimeiro,btnAnterior,btnProximo e btnUltimo
  • 2 PictureBox - picImagem e picLogo
  • 1 DataGridView - dgvAgenda
  • 1 OpenFileDialog - ofdImagem
 

 Definindo o código do formulário

Vamos agora definir o código inserido no formulário form1.vb onde iremos definir procedimentos e funções bem como incluir código em eventos dos controles de formulário.

1 - declarando os namespaces usados

Imports System.Data
Imports System.Data.SqlClient
Imports System.IO

2- definindo as variáveis globais do formulário

Dim Str As String = My.Settings.CadastroConnectionString.ToString
Dim sqlDa As New SqlDataAdapter
Dim dtb As DataTable
Dim sqlCon As New SqlConnection(Str)
Dim sqlCmd As New SqlCommand

3- Código do evento Load do formulário form1:

 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ofdImagem.Filter = "Todos(*.Jpg, *.Jpeg, *.Bmp)|*.Jpg; *.Jpeg; *.Bmp"
        CarregarDados()
        CarregarImagem()
        'ativa o modo de seleção de linha 
        dgvAgenda.SelectionMode = DataGridViewSelectionMode.FullRowSelect
        'ajusta o tamanho das células
        Me.dgvAgenda.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
        'esconde a coluna da imagem
        Me.dgvAgenda.Columns(1).Visible = False
    End Sub

Este código carrega os dados e a imagem e exibe no controle Datagridview.

 4- Código do procedimento CarregaDados() que seleciona os dados da tabela Contatos e exibe no DataGridView:

Private Sub CarregarDados()
        Try
            With sqlCmd
                .CommandType = CommandType.Text
                .CommandText = "SELECT * from Contatos"
                .Connection = sqlCon
            End With

            With sqlDa
                .SelectCommand = sqlCmd
                dtb = New DataTable
                .Fill(dtb)
                dgvAgenda.DataSource = dtb
            End With

        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            sqlCon.Close()
        End Try
End Sub

 Seleciona todos os dados da tabela Contatos e exibe no datagridview.

5- Código do procedimento CarregarImagem() que atualiza as caixas de texto do formulário com os dados selecionados no DataGridView e obtém a imagem:

 Private Sub CarregarImagem()
        Try
            Me.lblCodigo.Text = Me.dgvAgenda.CurrentRow.Cells("id").Value
            Me.txtNome.Text = Me.dgvAgenda.CurrentRow.Cells("nome").Value
            Me.txtSobrenome.Text = Me.dgvAgenda.CurrentRow.Cells("sobreNome").Value
            Me.txtCidade.Text = Me.dgvAgenda.CurrentRow.Cells("cidade").Value
            Me.txtEstado.Text = Me.dgvAgenda.CurrentRow.Cells("estado").Value
            Me.txtNascimento.Text = Me.dgvAgenda.CurrentRow.Cells("nascimento").Value
            Me.txtEmail.Text = Me.dgvAgenda.CurrentRow.Cells("email").Value

            Dim ms As New MemoryStream(ObtemImagem(CInt(dgvAgenda.SelectedCells(0).Value)))
            picImagem.Image = Image.FromStream(ms)
        Catch ex As Exception
            MsgBox("Erro : " & ex.Message)
        End Try
    End Sub

6 - Código da função ObtemImagem() que retorna um array de bytes contendo a imagem:

 Function ObtemImagem(ByVal Img As Integer) As Byte()

        Dim Imagem() As Byte = Nothing
        With sqlCmd
            .CommandType = CommandType.Text
            .CommandText = "Select imagem From Contatos Where id = " & Img
            .Connection = sqlCon
        End With
        Try
            sqlCon.Open()
            Imagem = CType(sqlCmd.ExecuteScalar(), Byte())
        Catch ex As Exception
            MsgBox("Erro : " + ex.Message)
        Finally
            sqlCon.Close()
        End Try
        Return Imagem
    End Function

7- Código do evento Click do botão de comando Alterar Imagem que abre a caixa de diálogo OpenFileDialog e atualiza o controle PicImage com a imagem selecionada:

Private Sub btnProcurarFoto_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcurarFoto.Click
        If ofdImagem.ShowDialog = DialogResult.OK Then
            picImagem.Image = System.Drawing.Image.FromFile(ofdImagem.FileName)
        End If
    End Sub

8 - Código do evento Click do botão de comando Novo que limpa as caixas de texto, faz a validação e chama a rotina InserirDados() para atualizar a tabela Contatos com um novo registro:

 Private Sub btnCadastrar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCadastrar.Click
        If btnCadastrar.Text = "Novo" Then
            limpaCampos()
            txtNome.Focus()
            btnCadastrar.Text = "Cadastrar"
        Else
            If btnCadastrar.Text = "Cadastrar" Then
                If ValidaDados() Then
                    InserirDados()
                    btnCadastrar.Text = "Novo"
                Else
                    MsgBox("Informe o nome , sobrenome , estado , cidade e selecione Imagem para cadastramento...")
                End If
            End If
        End If
    End Sub

9 - Código da rotina InserirDados() que inclui um novo registro na tabela Contatos:

Private Sub InserirDados()
        Try
            sqlCon.Open()

            Dim arrFilename() As String = Split(Text, "\")
            Array.Reverse(arrFilename)

            Dim ms As New MemoryStream
            picImagem.Image.Save(ms, picImagem.Image.RawFormat)

            Dim arrImage() As Byte = ms.GetBuffer

            With sqlCmd
                .CommandType = CommandType.Text
                .CommandText = ""
                .CommandText = "INSERT INTO Contatos (imagem, nome, sobrenome, cidade, estado, nascimento, email ) _ 
VALUES (@Imagem,@nome,@sobrenome,@cidade,@estado,@nascimento,@email)" _
                               & "SELECT * FROM Contatos WHERE (Id = SCOPE_IDENTITY())"
                .Connection = sqlCon

                .Parameters.Add(New SqlParameter("@Imagem", SqlDbType.Image)).Value = arrImage
                .Parameters.Add(New SqlParameter("@nome", SqlDbType.NVarChar)).Value = txtNome.Text
                .Parameters.Add(New SqlParameter("@sobrenome", SqlDbType.NVarChar)).Value = txtSobrenome.Text
                .Parameters.Add(New SqlParameter("@cidade", SqlDbType.NVarChar)).Value = txtCidade.Text
                .Parameters.Add(New SqlParameter("@estado", SqlDbType.NVarChar)).Value = txtEstado.Text
                .Parameters.Add(New SqlParameter("@nascimento", SqlDbType.NVarChar)).Value = txtNascimento.Text
                .Parameters.Add(New SqlParameter("@email", SqlDbType.NVarChar)).Value = txtEmail.Text
            End With

            sqlCmd.ExecuteNonQuery()
            CarregarDados()
            MsgBox("Registro Inserido com Sucesso.", MsgBoxStyle.Information)

        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            sqlCmd.Parameters.Clear()
            sqlCon.Close()
        End Try
    End Sub

 10 - Código do evento Click do botão de comando Alterar que faz a validação e chama a rotina AlterarDados():

 Private Sub btnAlterar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAlterar.Click
        If ValidaDados() Then
            AlterarDados()
        Else
            MsgBox("Informe o nome , sobrenome , estado e cidade e selecione imagem para alteração de dados...")
        End If
    End Sub

11 - Código da rotina AlterarDados() que altera os dados de um registro na tabela Contatos:

 Private Sub AlterarDados()
        Try
            sqlCon.Open()

            Dim arrFilename() As String = Split(Text, "\")
            Array.Reverse(arrFilename)
            Dim ms As New MemoryStream
            picImagem.Image.Save(ms, picImagem.Image.RawFormat)

            Dim arrImage() As Byte = ms.GetBuffer
            With sqlCmd
                .CommandType = CommandType.Text
                .CommandText = ""
                .CommandText = "UPDATE [Contatos] SET [imagem] = @Imagem, [nome] = '" & txtNome.Text & "', [sobrenome] = '" _ 
                       & txtSobrenome.Text & "' , [email] = '" & txtEmail.Text & "', [cidade] = '" & txtCidade.Text & "' , [estado] = '" _ 
                       & txtEstado.Text & "'  WHERE ([Id] = " & Me.lblCodigo.Text & ");" & _
                    "SELECT * FROM Contatos WHERE (Id = " & Me.lblCodigo.Text & ")"
                .Connection = sqlCon
                .Parameters.Add(New SqlParameter("@Imagem", SqlDbType.Image)).Value = arrImage
            End With

            sqlCmd.ExecuteNonQuery()
            CarregarDados()
            MsgBox("Registro Alterado com Sucesso.", MsgBoxStyle.Information)

        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            sqlCmd.Parameters.Clear()
            sqlCon.Close()
        End Try
    End Sub

12 - Código do evento Click do botão de comando Deletar que chama a rotina ExcluirDados():

 Private Sub btnDeletar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeletar.Click
        If MessageBox.Show("Confirma a Exclusão do registro : " & lblCodigo.Text & " ? ", "Excluir", MessageBoxButtons.YesNo, MessageBoxIcon.Information) = vbYes Then
            ExcluirDados()
        End If
    End Sub

13- Código da rotina ExcluirDados() que remove um registro da tabela Contatos:

Private Sub ExcluirDados()
        Try
            sqlCon.Open()

            With sqlCmd
                .CommandText = "Delete from Contatos where id = " & Me.lblCodigo.Text
                .Connection = sqlCon
            End With

            sqlCmd.ExecuteNonQuery()
            CarregarDados()
            MsgBox("Registro deletado com Sucesso.", MsgBoxStyle.Information)

        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            sqlCmd.Parameters.Clear()
            sqlCon.Close()
        End Try
    End Sub

14 - Código do evento Click do botão de comando Localizar que chama a rotina LocalizarDados():

 Private Sub btnLocalizar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLocalizar.Click
        LocalizarDados()
    End Sub

 15 - Código da rotina LocalizarDados():

 Private Sub LocalizarDados()

        Dim msg, titulo, valor, nome As String
        msg = "Informe o nome a procurar."
        titulo = "Procurar Registro" ' define o titulo.
        valor = "A"                  ' define o valor padrao
        ' Exibe mensagem posicionada 
        nome = InputBox(msg, titulo, valor, 800, 400)

        If nome <> String.Empty Then
            Try

                Dim sqlCmdSqlBuscaRegistro As String = "SELECT * from Contatos where nome like '%" & nome & "%'"

                With sqlCmd
                    .CommandType = CommandType.Text
                    .CommandText = sqlCmdSqlBuscaRegistro
                    .Connection = sqlCon
                End With

                With sqlDa
                    .SelectCommand = sqlCmd
                    dtb = New DataTable
                    .Fill(dtb)
                    dgvAgenda.DataSource = dtb
                End With

            Catch ex As Exception
                MsgBox("Não foram encontrados registros com este parâmetro.")
            End Try
        End If
    End Sub

 16 - Código do evento Click do botão de comando Carregar Dados que chama a rotina CarregarDados():

Private Sub btnCarregaDados_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCarregaDados.Click
        CarregarDados()
    End Sub

 17 - Código da rotina ValidaDados

Private Function ValidaDados() As Boolean
        If txtNome.Text <> String.Empty And txtSobrenome.Text <> String.Empty And txtEstado.Text <> String.Empty And txtCidade.Text <> _ 
String.Empty And picImagem.Image IsNot Nothing Then
            Return True
        Else
            Return False
        End If
    End Function

 18 - Código da rotina LimpaCampos()

Private Sub limpaCampos()
        txtNome.Text = ""
        txtSobrenome.Text = ""
        txtCidade.Text = ""
        txtEstado.Text = ""
        txtEmail.Text = ""
        txtNascimento.Text = ""
        picImagem.Image = Nothing
    End Sub

 19 - Código dos eventos Click dos botões de navegação:

Private Sub btnPrimeiro_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrimeiro.Click
        ' Vai para o primeiro registro...
        Me.BindingContext(dtb).Position = 0
        CarregarImagem()
    End Sub

    Private Sub btnAnterior_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnterior.Click
        ' Volta um registro...
        Me.BindingContext(dtb).Position -= 1
        CarregarImagem()
    End Sub

    Private Sub btnProximo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProximo.Click
        ' Avança um registro...
        Me.BindingContext(dtb).Position += 1
        CarregarImagem()
    End Sub

    Private Sub btnUltimo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUltimo.Click
        ' Vai para o último registro...
        Me.BindingContext(dtb).Position = dtb.Rows.Count
        CarregarImagem()
    End Sub

 20- Código do evento Click do botão de comando Sair:

 Private Sub btnSair_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSair.Click
        If MessageBox.Show("Confirma o encerramento do sistema ? ", "Encerrar", MessageBoxButtons.YesNo, MessageBoxIcon.Information) = vbYes Then
            ExcluirDados()
        End If
    End Sub

 21- Código do eventos CellEndEdit e Click do controle DataGridView:

  Private Sub dgvAgenda_CellEndEdit(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvAgenda.CellEndEdit
        Me.txtNome.Text = Me.dgvAgenda.CurrentCell.Value
        AlterarDados()
        CarregarImagem()
    End Sub

    Private Sub dgvAgenda_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dgvAgenda.Click
        CarregarImagem()
    End Sub

O projeto completo esta no SUPER DVD .NET

Rom 8:5 Pois os que são segundo a carne inclinam-se para as coisas da carne; mas os que são segundo o Espírito para as coisas do Espírito.

Rom 8:6 Porque a inclinação da carne é morte; mas a inclinação do Espírito é vida e paz.

Referências:


José Carlos Macoratti