VB .NET - Criando um formulário de consulta


Neste artigo eu mostro como criar um formulário básico para consultas com ADO .NET e utilizando uma arquitetura em camadas.

Abaixo temos o formulário do projeto:

Os controles usados no formulário são:
  • GroupBox - gbCriterio, gbResultado;
  • ComboBox - cboCampo, CboParametro;
  • TextBox - txtValor;
  • Button - btnOK;
  • DataGridView - gdvConsulta;

Ao iniciar a aplicação os dados da tabela que desejamos consultar serão exibidos no DataGridView e o controle ComboBox - cboCampo - será preenchido com os nomes dos campos da tabela:

Ao selecionar um campo da ComboBox - cboCampo , a outra combobox CboParametro exibirá os valores relacionados conforme a tabela abaixo:

Campo do tipo String Campo do tipo Integer
=
Começa com
Termina em
Contém
=
>
>=
<
<=
<>

tabela 1.0

Em seguida basta informar o valor desejado para que string SQL seja montada e executada para obter os valores da consulta desejada.

Vou usar o Visual Basic 2008 Express Edition e o banco de dados SQL Server 2005 Express Edition.

Neste exemplo eu vou usar o banco de dados Macoratti.mdf e a usar a tabela Clientes.

A string de conexão para o banco de dados usado no exemplo é a seguinte:

Data Source=.\SQLEXPRESS;AttachDbFilename="C:\DadosMacoratti.mdf";Integrated Security=True;Connect Timeout=30;User Instance=True

Você pode obter a string de conexão criando uma nova conexão no DataBase Explorer, selecionando o banco de dados e visualizar o valor da propriedade Connection String na janela de Propriedades.

Vocé pode armazenar a string de conexão no arquivo App.Config conforme abaixo:

   <applicationSettings>
        <ConsultaNet.My.MySettings>
            <setting name="conexaoBD" serializeAs="String">
                <value>Data Source=.\SQLEXPRESS;AttachDbFilename="C:\Dados\Macoratti.mdf";Integrated Security=True;Connect Timeout=30;_
User Instance=True</value>
            </setting>
        </ConsultaNet.My.MySettings>
    </applicationSettings>

Obs: Para criar o App.Config e ter incluida a string de conexão conforme acima no menu Data selecione a opção Add New Data Source... e siga as orientações do assistente até salvar a string de conexão. Em seguida exclua o dataset gerado pois não será usado neste aplicação.

Pode também definir a string de conexão no seu projeto clicando em My Project e na guia Configurações(Settings) definir um nome, tipo, escopo e valor para a string de conexão conforme a figura abaixo:

Na aplicação exemplo deste artigo eu vou usar esta última forma onde defini a variável conexaoBD contendo o valor da string de conexão. Ela será acessada via recurso My.Settings.

Nesta aplicação vamos usar uma arquitetura em camadas de forma a ter um código mais organizado de fácil manutenção e reutilização.

Para isso vamos criar uma estrutura da seguinte forma:

Nesta arquitetura temos que:

Podemos definir esta estrutura criando 3 projetos distintos ou em um mesmo projeto criar uma classe para a camada de negócios(BLL) e outra classe para a camada de acesso a dados (DAL). No nosso exemplo irei usar esta última opção.

Abra o Visual Basic 2008 Express Edition e crie um novo projeto do tipo Windows Application usando a linguagem Visual Basic com o nome ConsultaNet;

A seguir vamos incluir uma nova classe no projeto, para isso clique com o botão direito do mouse sobre o nome do projeto e selecionando a opção Add -> New Item;

A seguir selecione o template Class e informe o nome DAL para a classe. Esta classe irá conter o código de acesso a dados.

Repita o procedimento acima e inclua uma nova classe com o nome ClienteBLL que deverá conter o código da lógica de negócio da aplicação.

O projeto deverá possuir neste momento a seguinte estrutura:

Definindo o código da camada de acesso a dados (DAL)

A classe DAL vai conter o código da camada de acesso a dados. Esta camada deve saber tudo sobre acesso a dados e para isso deverá conter os namespaces System.Data e System.Data.SqlClient.

Definimos o namespace DAL para esta classe e definimos a classe AcessoBD com os seguintes métodos:

Imports System.Data
Imports System.Data.SqlClient

Namespace DAL
    Public Class AcessoBD

        Dim strConexao As String = My.Settings.conexaoBD

        Private Function openConexao() As SqlConnection
            Dim cn As New SqlConnection
            cn.ConnectionString = strConexao
            cn.Open()
            Return cn
        End Function

        Private Sub closeConexao(ByVal cn As SqlConnection)
            If cn.State = ConnectionState.Open Then
                cn.Close()
            End If
        End Sub

        Public Sub ExecuteComando(ByVal consulta As String)
            Dim cn As New SqlConnection()
            Try
                cn = openConexao()
                Dim cmdCommand As New SqlCommand
                With cmdCommand
                    .CommandText = consulta.ToString
                    .CommandType = CommandType.Text
                    .Connection = cn
                    .ExecuteNonQuery()
                End With
            Catch ex As Exception
                Throw
            Finally
                closeConexao(cn)
            End Try
        End Sub

        Public Function GetDataSet(ByVal consulta As String) As DataSet
            Dim cn As New SqlConnection()
            Try
                cn = openConexao()
                Dim cmdCommand As New SqlCommand
                With cmdCommand
                    .CommandText = consulta.ToString
                    .CommandType = CommandType.Text
                    .Connection = cn
                    .ExecuteNonQuery()
                End With
                Dim da As New SqlDataAdapter
                Dim ds As New DataSet
                With da
                    .SelectCommand = cmdCommand
                    .Fill(ds)
                End With
                Return ds
            Catch ex As Exception
                Throw
            Finally
                closeConexao(cn)
            End Try
        End Function

        Public Function GetDataReader(ByVal consulta As String) As SqlDataReader
            Dim cn As New SqlConnection()
            Try
                cn = openConexao()
                Dim cmdCommand As New SqlCommand
                With cmdCommand
                    .CommandText = consulta.ToString
                    .CommandType = CommandType.Text
                    .Connection = cn
                End With
                Return cmdCommand.ExecuteReader
            Catch ex As Exception
                Throw
            Finally
                closeConexao(cn)
            End Try
        End Function

   End Class
End Namespace

Dessa forma temos pronto o código para realizar as operações básicas de acesso a dados na nossa aplicação.

Definindo o código da camada de lógica de negócios (BLL)

A classe clienteBLL irá conter o código da lógica de negócio que nosso exemplo será bem simples. Ela conterá dois métodos:

Ambos os métodos são chamados a partir de uma instância da camada de acesso a dados (dal).

Observe que os métodos e variáveis dessa classe são estáticas (shared) e portanto não precisam que uma instância da classe seja criada para serem invocadas.

A classe utiliza o namespace ConsultaNet.DAL pois necessita ter acesso aos métodos da classe DAL.

Imports ConsultaNet.DAL

Namespace BLL
    Public Class ClienteBLL

        Private Shared dal As AcessoBD

        Public Shared Function getClientes(ByVal consulta As String) As DataSet
            dal = New AcessoBD
            Return dal.GetDataSet(consulta)
        End Function

        Public Shared Function pesquisaClientes(ByVal Campo As String, ByVal Parametro As String, _ 
                                                                        ByVal Valor As String, ByVal tipo As String) As DataSet
            Dim sql As String = "SELECT * From Clientes WHERE " & Campo & " " & Parametro & " " & Valor
            dal = New AcessoBD
            Return dal.GetDataSet(sql)
        End Function

    End Class
End Namespace

Definindo o código da camada de interface (UI)

Camada de interface irá exibir as informações e permitir a interação com o usuário. Ela deverá acessar a camada de negócios (BLL) que por sua vez acessará a camada de acesso a dados (DAL) que por sua vez acessa os dados e retorna o resultado ou realiza a operação desejada.

Como esta camada vai usar os métodos da camada de negócios (BLL) devemos declarar o seguine namespace no formulário:

Imports ConsultaNet.BLL

Em seguida vamos definir o seguinte código no formulário:

    Dim tipoCampo As Type

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim i As Integer
        Dim ds As New DataSet
        ds = ClienteBLL.getClientes("Select * from Clientes")
        cboCampo.Items.Clear()
        For i = 0 To ds.Tables(0).Columns.Count - 1
            cboCampo.Items.Add(ds.Tables(0).Columns(i).ColumnName.ToString)
        Next i
        Me.gdvConsulta.AutoGenerateColumns = True
        Me.gdvConsulta.DataSource = ds.Tables(0)
    End Sub

    Private Sub cboCampo_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ 
Handles cboCampo.SelectedIndexChanged
        Dim ds As New DataSet
        tipoCampo = Me.gdvConsulta.Columns(cboCampo.SelectedIndex).ValueType

        If tipoCampo.ToString = "System.Int32" Then
            cboParametro.Items.Clear()
            cboParametro.Items.Add("=")
            cboParametro.Items.Add(">")
            cboParametro.Items.Add(">=")
            cboParametro.Items.Add("<")
            cboParametro.Items.Add("<=")
            cboParametro.Items.Add("<>")
        End If

        If tipoCampo.ToString = "System.String" Then
            cboParametro.Items.Clear()
            cboParametro.Items.Add("=")
            cboParametro.Items.Add("Começa com")
            cboParametro.Items.Add("Termina em")
            cboParametro.Items.Add("Contém")
        End If
    End Sub


    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        Dim campo As String = cboCampo.Text
        Dim parametro As String = cboParametro.Text
        Dim valor As String = txtValor.Text
        Dim tipo As String = tipoCampo.ToString
        Dim ds As New DataSet

        If tipo = "System.String" Then
            If parametro = "Tem a palavra" Then
                parametro = "Like "
                valor = "%" & valor & "%"
            End If
            If parametro = "=" Then
                valor = "" & valor & ""
            End If
            If parametro = "Começa com" Then
                parametro = "Like "
                valor = "" & valor & "%"
            End If
            If parametro = "Termina em" Then
                parametro = "Like "
                valor = "%" & valor & ""
            End If
        End If

        ds = ClienteBLL.pesquisaClientes(campo, parametro, valor, tipo)
        Me.gdvConsulta.AutoGenerateColumns = True
        Me.gdvConsulta.DataSource = ds.Tables(0)
    End Sub

Vamos entender o código:

No evento Load do formulário criamos um dataset e acessamos o método getClientes da camada de negócios - ClienteBLL passando como parâmetro a instrução SQL=(Select * from Clientes);

ds = ClienteBLL.getClientes("Select * from Clientes")

Note que não necessitamos criar uma instância da classe ClienteBLL pois o método getClientes é estático (Shared)

- Limpamos a combobox - cboCampo.Items.Clear()

- Percorremos as colunas da tabela retornada pelo dataset e preenchemos a combobox com os nomes dos campos:

For i = 0 To ds.Tables(0).Columns.Count - 1
     cboCampo.Items.Add(ds.Tables(0).Columns(i).ColumnName.ToString)
Next i


- Exibimos o dataset retornado no DataGridView:

Me.gdvConsulta.AutoGenerateColumns = True
Me.gdvConsulta.DataSource = ds.Tables(0)


No evento SelectedIndexChanged da combobox que ocorre sempre que um item for selecionado, iremos obter o tipo de campo selecionado e se o mesmo for do tipo string iremos preencher a combobox com os valores mostrados na tabela 1.0.

No evento Click do botão OK verificamos o tipo do item selecionado e conforme o seu conteúdo definimos os parâmetros : parametro e valor como Like e/ou % para montar a instrução SQL:

If tipo = "System.String" Then
    If parametro = "Tem a palavra" Then
         parametro = "Like "
        valor = "%" & valor & "%"
    End If
   If parametro = "=" Then
      valor = "" & valor & ""
   End If
   If parametro = "Começa com" Then
      parametro = "Like "
      valor = "" & valor & "%"
   End If
   If parametro = "Termina em" Then
       parametro = "Like "
       valor = "%" & valor & ""
   End If
End If

Em seguida chamamos o metódo pesquisaClientes passando o parâmetros definidos como critério para pesquisa. Será retornado o dataset contendo os registros que atendem o critério que serão exibidos no DataGridView:

ds = ClienteBLL.pesquisaClientes(campo, parametro, valor, tipo)
Me.gdvConsulta.AutoGenerateColumns = True
Me.gdvConsulta.DataSource = ds.Tables(0)


Executando o projeto e definindo um critério onde o campo nome contém a letra M, conforme abaixo, iremos obter como resultado:

Serão exibidos apenas os registros que atendem o critério definido.

Nota: Voce pode evitar que o formulário seja fechado acidentalmente definindo o seguinte código no evento FormClosing() do formulário
Private Sub frmConsulta_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)_
Handles MyBase.FormClosing
  If MessageBox.Show("Deseja fechar o formulário", "Fechar Form", MessageBoxButtons.YesNo, MessageBoxIcon.Hand) = _
      Windows.Forms.DialogResult.No Then
         e.Cancel = True
  End If
End Sub

Pegue o projeto completo aqui: ConsultaNet.zip

Eu sei é apenas VB .NET, mas eu gosto...

Referências:


José Carlos Macoratti