Desenvolvimento - Visual Basic .NET

Formulários padrões e reutilização de código

Este artigo visa uma explanação rápida sobre utilização de reuso de código e formulários de cadastro e consultas utilizando programação orientada a objetos. No exemplo, utilizamos o Visual Basic 2005.

por Ives Fernando Bertoli



Este artigo visa uma explanação rápida sobre utilização de reuso de código e formulários de cadastro e consultas utilizando programação orientada a objetos. No exemplo, utilizamos o Visual Basic 2005.

Muito se fala em aproveitamento de código. Nas faculdades isto é alvo de dezenas de aulas, porém nem tudo que se diz é interpretado da forma que deve ser. Tão quanto implementado em sistemas, e como sabemos na “prática a teoria é outra!”.

Durante atividades profissionais na área de desenvolvimento podemos sentir a real necessidade do tal “reaproveitamento de código”. Onde podemos facilmente sintetizar simplesmente dizendo: “Reaproveitamento de código é a utilização de um trecho de programa por diversas funções de um mesmo sistema ou por mais de um sistema de forma idêntica e compartilhada”.

Neste artigo irei abordar funções desenvolvidas para facilitar a prática da programação de sistemas possibilitando maior produtividade em seus sistemas. Neste artigo irei abordar algumas funções muito úteis principalmente para iniciantes em tecnologia VB.NET, mas é claro que o “reaproveitamento de código” não é uma tecnologia específica e sim uma teoria de programação.

Um sistema é composto de diversas telas, funções e outros procedimentos, as famosas telas de Cadastro são sem dúvidas as mais comuns e todas elas possuem as mesmas funções em um sistema, desde funções até aparências. Aqui iremos abordar uma simples tela de cadastro utilizando um DataGrid do Visual Basic 2005.

Neste formulário temos o exemplo de um cadastro baseado em um DataGrid com as funções de inclusão, alteração, exclusão e busca. Este é o exemplo mais simples de reutilização de código. Onde facilmente, mais propriamente em 1 linha podemos moldar 100% do formulário para que este cadastro seja útil para diversos cadastros (é claro que os cadastros são bastante básicos).

Mas afinal, o que temos codificado neste formulário ???

1) Declaramos 3 itens que garantirão o compartilhamento de valores pelo formulário, sendo “ds” um dataset que será utilizado para a geração e controle do datagrid; “da” data Adapter, que será instanciado com a conexão padrão no banco de dados; “v_txtSQL” receberá todas as definições SQL ANSI para manipulação de Banco de dados.

    Dim ds As New DataSet

    Dim da As New Npgsql.NpgsqlDataAdapter("", connPSQL)

    Dim v_txtSQL As String

2) Foi implementado um método construtor que recebe parâmetros para sua inicialização e carga inicial. O método construtor segue abaixo devidamente comentado. O que vale maior foco são os parâmetros do construtor, onde este recebe (1) DataAdapter com os valores a serem “montados” em tempo de execução e Titulo para o formulário.

    "Construtor da classe form

    Public Sub New(ByVal objData As Npgsql.NpgsqlDataAdapter, ByVal v_titulo As String)

        " This call is required by the Windows Form Designer.

        InitializeComponent()

        " Add any initialization after the InitializeComponent() call.

        Try

            da = objData

            da.Fill(ds, "grupo")

            grdGrupo.DataSource = ds.Tables("grupo")

            Me.Text = v_titulo

        Catch ex As Exception

Msgbox (“houve falha ao carregar objeto”)

Me.dispose()

        End Try

    End Sub

3) Todas as alterações que forem realizadas no grid não serão salvas de forma automática, pois estamos trabalhando com dados desconectados. Para isto é imprescindível que tenhamos um mecanismo para fazer o sincronismo entre os dados visualizados e dados reais em banco de dados. Para este objetivo, temos a função abaixo que permite o melhor entendimento da forma que a sincronização  é realizada.

    "botão Salvar

    Private Sub btnSalvar_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSalvar.Click

        If ds.HasChanges = True Then " Verifica se houve alterações nos registros do DataSet Desconectado

            Try

                Dim cmdSQL As Npgsql.NpgsqlCommandBuilder = New Npgsql.NpgsqlCommandBuilder(da)

                Dim alteracoes As DataSet = ds.GetChanges "Captura dados alterados

                da.Update(alteracoes.Tables(0)) "Atualiza atraves do tunel do Data Adapter

                ds.AcceptChanges() "Atualiza dados do dataset (Marca como "Atualizado")

                ds.Clear() "Limpa o Dataset

                da.Fill(ds, "grupo") "Recarrega Dataset

            Catch ex As Exception

                F_Erro(Err.Description, Err.Number)

            End Try

        Else

            F_Aviso("Não existem alterações a serem salvas")

        End If

    End Sub

Para o exemplo acima é muito importante dizer que foi utilizado (para testes) o banco de dados PostgreSQL 8.2 (que será alvo de futuros artigos). As funções de inserção, alteração e exclusão são de padrão do próprio datagrid.

Mas afinal, como invocar a utilização do formulário genérico ? Simples, afinal, como diria minha adorável noiva, “simples como um beijo” conforme descrito na linha abaixo.

Dim frmCurso As New frmCad_Geral(New Npgsql.NpgsqlDataAdapter("select * from curso order by descricao", connPSQL), "Cadastro de Cursos")  "Instancia objeto com construtor recebendo parâmentros.

frmCurso.Show()"Carrega o formulário

Ah já tava me esquecendo, existe um item muito importante, é claro, de que vale um cadastro se este não pode ser filtrado ou consultado. Podemos fazer de diversas formas este recurso de consulta, mas não seria inteligente criar-mos uma consulta para cada formulário, concorda? Pois bem, vamos criar um formulário padrão, simples e que realmente funciona para efeito de consulta em cadastros. Neste exemplo, estarei criando tabela temporária em banco de dados, o que não irei explicar motivos e formas de uso pois será alvo de artigos futuros.

Assim como no exemplo de cadastro, temos a seguinte tela de consulta:

Neste formulário temos 1 datagrid (somente leitura), 3 botões com as respectivas funções e uma caixa de texto para criação dos filtros.

Mas e o complexo código utilizado? Sou adepto da teoria que o mais simples é o que realmente funciona, inventar é “arrumar para a cabeça”, portanto vamos aos códigos.

Public Class frmConsultar

    Dim v_txtSQL As String

    Dim v_criterio As String

    Dim v_campo_consulta As String

    Dim v_ddl As String

    "Carregando Formulário

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

        F_Atualizar_Tabela()

    End Sub

    "Construtor Nulo

    Public Sub New()

        " This call is required by the Windows Form Designer.

        InitializeComponent()

        " Add any initialization after the InitializeComponent() call.

    End Sub

    "Construtor Parametrizado

    Public Sub New(ByVal v_titulo As String, ByVal v_SQL As String, ByVal criterio_adicional As String, ByVal campo_consulta As String)

        " This call is required by the Windows Form Designer.

        InitializeComponent()

        " Add any initialization after the InitializeComponent() call.

        Me.Text = v_titulo

        v_ddl = v_SQL

        v_criterio = criterio_adicional

        v_campo_consulta = campo_consulta

    End Sub

    "Atualizar Tabela (GRID)

    Public Sub F_Atualizar_Tabela()

        Try

            Dim v_codigo As Integer = 0

            Dim v_nometabela As String = " v_tmp"

            "Dim v_ddl As String = v_txtSQL

            v_ddl = "create temp view " & v_nometabela & " as (" & v_ddl & ") "

            If F_SalvarDDL(v_ddl) = False Then

                F_Aviso("Houve erro ao criar visão de banco de dados.")

                Exit Sub

            End If

            If v_criterio.Length > 0 Then

                v_txtSQL = "select * from " & v_nometabela & " where " & v_criterio & " and " & v_campo_consulta & " like "" & txtcriterio.Text & "%""

            Else

                v_txtSQL = "select * from " & v_nometabela & " where " & v_campo_consulta & " like "" & txtcriterio.Text & "%""

            End If

            Dim da As New Npgsql.NpgsqlDataAdapter(v_txtSQL, connPSQL)

            Dim tabela As New DataSet

            da.Fill(tabela)

            grdTabela.DataSource = tabela.Tables(0)

            TotalRegistro.Text = "Total de Registros Encontrados: " & grdTabela.RowCount.ToString

            lblCampo.Text = v_campo_consulta

            da.Dispose()

            F_SalvarDDL("drop view " & v_nometabela)

            txtcriterio.Focus()

        Catch

            F_Aviso("Erro ao processar informações. Persistindo o erro, informe ao Suporte" & vbCrLf & "Erro: " & Err.Description)

            F_Transportar(False)

        End Try

    End Sub

    "Ao Clicar sobre o cabeçalho do campo

    Private Sub grdTabela_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles grdTabela.ColumnHeaderMouseClick

        If v_campo_consulta = grdTabela.Columns(e.ColumnIndex).HeaderText Then Exit Sub

        If F_Questao("Deseja alterar o critério de consulta de: " & v_campo_consulta.ToString & " para: " & grdTabela.Columns(e.ColumnIndex).HeaderText.ToString, 2) = True Then

            v_campo_consulta = grdTabela.Columns(e.ColumnIndex).HeaderText.ToString

            F_Atualizar_Tabela()

        End If

    End Sub

    "Acionar botão "Buscar"

    Private Sub btnBuscar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBuscar.Click

        F_Atualizar_Tabela()

    End Sub

    "Clique sobre o botão CANCELAR

    Private Sub btnCancelar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancelar.Click

        F_Transportar(False)

    End Sub

 

  "Clique sobre o botão Aceitar

    Private Sub btnAceitar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAceitar.Click

        F_Transportar(True)

    End Sub

    "Ação a ser tomada de acordo com a operação selecionada - True (OK e Duplo Click), False (Cancelar)

    Sub F_Transportar(ByVal v_acao As Boolean)

        If v_acao = True Then

            If grdTabela.SelectedRows.Count >= 1 Then

                Me.Tag = grdTabela.SelectedCells(0).Value.ToString

            Else

                If F_Questao("Você não selecionou um registro. Deseja cancelar a operação ?", 2) = True Then

                    Me.Tag = "Cancel"

                Else

                    Exit Sub

                End If

            End If

            Me.Hide()

        Else

            Me.Tag = "Cancel"

            Me.Hide()

        End If

    End Sub

    "Duplo click na tabela

    Private Sub grdTabela_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles grdTabela.DoubleClick

        F_Transportar(True)

    End Sub

    "Tecla Esc

    Private Sub frmConsultar_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown

        If e.KeyCode = Keys.Escape Then F_Transportar(False)

    End Sub

    "Inicio do redimencionamento

    Private Sub frmConsultar_ResizeBegin(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ResizeBegin

        Me.Opacity = 0.5

    End Sub

    "Final do redimencionamento

    Private Sub frmConsultar_ResizeEnd(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ResizeEnd

        Me.Opacity = 1

    End Sub

End Class

Hei, mas como funciona isto? Bem precisamos comentar sobre o código? Acredito que não, pois está todo comentado! O mais legal é que esta consulta permite ordenação por coluna e alteração automática de critério, ou seja, para você alterar mudar o campo a ser filtrado, basta clicar sobre o cabeçalho da coluna e pronto, você já alterou o campo filtrado.

Chegamos até aqui e percebo o óbvio, você deve estar perguntando porque criar uma visão temporária ?  Este cara deve estar querendo complicar? Digo que não, a visão temporária talvez seja a forma mais fácil de eliminar-mos o problema de campos com mesmo nome, como o famoso “descrição” e se utilizar o JOIN (SQL ANSI) o sistema não saber.

Possivelmente você irá ver algumas funções iniciadas com “F”, o que isto representa? Tenho como padrão (para minha organização) padrões de nomenclatura. Desta forma, tudo que tenha F, saiba que deverá ser explanado para que você entenda o conteúdo. Hoje temos o F_Aviso, F_Questao e F_SalvarDDL:

F_Aviso à é utilizada para mostrar mensagens de alerta na tela. Por que não utilizar msgbox ? Simples, para manter o padrão em todo o sistema

    "Função para emissão de aviso (Tipo Alert)

    Sub F_Aviso(ByRef v_mensagem As String)

        MsgBox(v_mensagem.ToString, MsgBoxStyle.Information, "Aviso do Sistema")

    End Sub

F_Questao à é utilizada para mostrar confirmações do usuário, onde Verdadeiro representa o clique em SIM e False, representa click em NÃO.

    "Função de confirmação

    Function F_Questao(ByRef v_mensagem As String, ByVal v_padrao As Integer) As Boolean

        If v_padrao = 1 Then

            If MsgBox(v_mensagem, MsgBoxStyle.Question + MsgBoxStyle.YesNo + MsgBoxStyle.DefaultButton1, "Aviso do Sistema") = MsgBoxResult.Yes Then

                Return True

            Else

                Return False

            End If

        ElseIf v_padrao = 2 Then

            If MsgBox(v_mensagem, MsgBoxStyle.Question + MsgBoxStyle.YesNo + MsgBoxStyle.DefaultButton2, "Aviso do Sistema") = MsgBoxResult.Yes Then

                Return True

            Else

                Return False

            End If

        Else

            If MsgBox(v_mensagem, MsgBoxStyle.Question + MsgBoxStyle.YesNo, "Aviso do Sistema") = MsgBoxResult.Yes Then

                Return True

            Else

                Return False

            End If

        End If

    End Function

F_SalvaDDL à é utilizada para executar um script DDL no banco de dados

    "Função para Executa comandos de Definição (DDL)

    Function F_SalvarDDL(ByRef v_string As String) As Boolean

        Dim cmdSQL As New Npgsql.NpgsqlCommand(v_string, connPSQL)

        Try

            cmdSQL.ExecuteNonQuery()

            Return True

        Catch ex As Exception

            Return False

        End Try

   End Function

Termino aqui esta rápida explanação sobre reuso de código. Aguarde novos exemplos sobre reutilização com formas mais utilizadas possibilitando formulários mais elaborados. Boas programações!!!!

Ives Fernando Bertoli

Ives Fernando Bertoli