VB .NET - Curso Prático ADO .NET - Desenvolvendo uma aplicação : Definindo o código da Interface - X


Neste artigo do curso prático iremos definir o código do formulário de pesquisas.

O formulário de pesquisa permite aos clientes pesquisar a base de dados CiaFilmes. Para se conectar ao banco de dados a partir do formulário de pesquisa, vamos precisa usar o provedor .NET para o SQL Server e as classes da ADO .NET. Portanto temos que declarar os seguintes namespaces no início do formulário frmPesquisas.vb:

A seguir vemos o fluxo de utilização do formulário de Pesquisas - frmPesquisas:

No formulário de pesquisas iremos utilizar os seguintes funções:

  1. frmPesquisas_Load
  2. btnProcurar_Click
  3. btnFazerPedido_Click
  4. btnSair_Click

O evento Load do formulário será executado antes de uma instância do formulário ser exibida. No formulário de pesquisas a função frmPesquisas_Load deverá receber código que executa as seguintes tarefas:

Portanto, quando o cliente abrir o formulário de pesquisa, a opção do filme estará selecionado na combobox, e o botão btnFazerPedido estará desativado. Abaixo vemos o código que implementa isso:

    Private Sub frmPesquisas_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        cboPesquisarPor.SelectedIndex = 0
        btnFazerPedido.Enabled = False
    End Sub

A função btnProcurar_Click é executada quando o cliente clica no botão Procurar e primeiro ela verifica se o cliente inseriu um texto na caixa de texto 'Texto a Pesquisar', se ela estiver em branco uma mensagem será exibida ao cliente.

Com base no texto inserido e com o valor selecionado na combobox cboPesquisarPor criaremos uma consulta SQL que será executada e os resultados armazenados em um conjunto de dados.

Havendo resultados eles serão exibidos no controle ListView - lvResultadoPesquisa e o botão Fazer pedido será habilitado. Se não for encontrado nenhum resultado e o conjunto de dados estiver vazio iremos exibir uma mensagem ao cliente usando a classe MessageBox.

Nota: A classe Messagebox exibe textos em uma caixa de diálogo e um conjunto de botões.  Ela possui somente um método estático ; o método Show. Este método aceita 6 parâmetros principais diferentes e usar todos não é obrigatório.  Podemos ter até 12 tipos de sobreposições para as várias combinações de parâmetros.

Abaixo temos o código atribuido ao evento Click do botão Procurar:

  Private Sub btnProcurar_Click(sender As Object, e As EventArgs) Handles btnProcurar.Click

        'define os objetos ADO .NET para acessar e tratar as informações do banco de dados
        Dim dsDts As DataSet
        Dim sqlCon As New SqlConnection(strConexaoSQLServer)
        Dim sqlAda As New SqlDataAdapter()
        Dim sqlCmd As New SqlCommand()

        'define a variavel para a consuulta SQL e para a seleção da opção de busca
        Dim strConsulta As String
        Dim selecao As Integer
        'Declara uma variavel para contar o numero de registros obtidos
        Dim intNumeroRegistros As Integer = 0

        strConsulta = "SELECT DISTINCT a.FilmeId , b.AtorId, c.DiretorId, d.ProdutorId, a.Titulo, b.Nome AS Ator, c.Nome AS Diretor, d.Nome AS Produtor " _
                             + "FROM Filmes a, Atores b, Diretores c, Produtores d, AtorFilme e " _
                             + "WHERE a.FilmeId = e.FilmeId AND e.AtorId = b.AtorId AND a.DiretorId = c.DiretorId AND a.ProdutorId = d.ProdutorId"

        Select Case cboPesquisarPor.SelectedIndex
            Case 0 'filme
                If Not String.IsNullOrEmpty(txtTextoPesquisar.Text) Then
                    strConsulta += " AND a.Titulo LIKE '" & txtTextoPesquisar.Text & "%'"
                End If
                selecao = 0
            Case 1 'ator
                If Not String.IsNullOrEmpty(txtTextoPesquisar.Text) Then
                    strConsulta += " AND (b.Nome LIKE '" & txtTextoPesquisar.Text & "%' OR b.Sobrenome LIKE '" & txtTextoPesquisar.Text & "%') "
                End If
                selecao = 1
            Case 2 'diretor
                If Not String.IsNullOrEmpty(txtTextoPesquisar.Text) Then
                    strConsulta += " AND (c.Nome LIKE '" & txtTextoPesquisar.Text & "%' OR c.Sobrenome LIKE '" & txtTextoPesquisar.Text & "%') "
                End If
                selecao = 2
            Case 3 'produtor
                If Not String.IsNullOrEmpty(txtTextoPesquisar.Text) Then
                    strConsulta += " AND d.Nome LIKE '" & txtTextoPesquisar.Text & "%'"
                End If
                selecao = 3
        End Select
        Try
            'cria um  novo dataset
            dsDts = New DataSet()
            'atribui o comando ao dataadapter
            sqlAda.SelectCommand = sqlCmd
            'atribui a string de consulta sql montada ao command
            sqlAda.SelectCommand.CommandText = strConsulta
            'executa a consulta
            sqlAda.SelectCommand.Connection = sqlCon
            'preenche a tabela Resultado no dataset com o resultado da consulta
            sqlAda.Fill(dsDts, "Resultado")
            'limpa o controle listview
            lvResultadoPesquisa.Items.Clear()

            'percorre os registros tabela obtida
            For Each drLinha In dsDts.Tables("Resultado").Rows
                'obtem as linhas e atribui a uma array de strings : Id do filme(0) , o titulo(4), ator(5), diretor(6) e produtor(7)
                Dim strRegistrosResultado As String() = {drLinha(0), drLinha(4), drLinha(5), drLinha(6), drLinha(7)}
                'exibe cada linha do array no controle listview
                lvResultadoPesquisa.Items.Add(New ListViewItem(strRegistrosResultado))
                'incrementa o contador de registros
                intNumeroRegistros += 1
            Next

            'exibe mensagens conforme a seleção se não houver registros e habilita/desabilita botão de fazer pedido
            If intNumeroRegistros = 0 Then
                If (selecao = 0) Then
                    MessageBox.Show("O filme não foi localizado no acervo.", "Filme", MessageBoxButtons.OK, MessageBoxIcon.Information)
                ElseIf (selecao = 1) Then
                    MessageBox.Show("Não foi encontrado nenhum filme para este Ator.", "Ator", MessageBoxButtons.OK, MessageBoxIcon.Information)
                ElseIf (selecao = 2) Then
                    MessageBox.Show("Não foi encontrado nenhum filme para este Diretor.", "Diretor", MessageBoxButtons.OK, MessageBoxIcon.Information)
                ElseIf (selecao = 3) Then
                    MessageBox.Show("Não foi encontrado nenhum filme para este Produtor.", "Produtor", MessageBoxButtons.OK, MessageBoxIcon.Information)
                End If
                btnFazerPedido.Enabled = False
            Else
                'habilita o botão para fazer o pedido
                btnFazerPedido.Enabled = True
            End If

        Catch ex As Exception
            MessageBox.Show("Erro : " & ex.Message)
        Finally
            'fecha e libera os recursos usados
            sqlCon.Close()
            sqlCon.Dispose()
            sqlCmd.Dispose()
            sqlAda.Dispose()
        End Try
    End Sub

O código acima monta uma string e consulta usando comandos SQL:

strConsulta = "SELECT DISTINCT a.FilmeId , b.AtorId, c.DiretorId, d.ProdutorId, a.Titulo, b.Nome AS Ator, c.Nome AS Diretor, d.Nome AS Produtor " _
                    + "FROM Filmes a, Atores b, Diretores c, Produtores d, AtorFilme e " _
                    + "WHERE a.FilmeId = e.FilmeId AND e.AtorId = b.AtorId AND a.DiretorId = c.DiretorId AND a.ProdutorId = d.ProdutorId"

E dependendo da seleção de critério que o cliente escolheu a consulta é complementada usando o operador LIKE e o valor dos campos da respectiva tabela:

A função LIKE que pode ser usada com a cláusula WHERE sendo que ela retorna todas as linhas cujo conteúdo das colunas  for igual ao literal passado na função.

SELECT PubId, Name , State FROM Publishers WHERE State LIKE ('B%')

O comando acima exibe todas as colunas indicadas da tabela Publishers onde a coluna state for iniciada com a letra B.

Nota: Você deve usar o caractere % ao invés do asterístico (*).

Usamos um Select / Case definindo o SelectIndex que como opção de seleção e concluímos a montagem da instrução SELECT conforme a opção selecionada:

Select Case cboPesquisarPor.SelectedIndex
Case 0
'filme
If Not String.IsNullOrEmpty(txtTextoPesquisar.Text) Then
     strConsulta += " AND a.Titulo LIKE '" & txtTextoPesquisar.Text & "%'"
End If
selecao = 0
Case 1
'ator
If Not String.IsNullOrEmpty(txtTextoPesquisar.Text) Then
    strConsulta += " AND (b.Nome LIKE '" & txtTextoPesquisar.Text & "%' OR b.Sobrenome LIKE '" & txtTextoPesquisar.Text & "%') "
End If
selecao = 1
Case 2
'diretor
If Not String.IsNullOrEmpty(txtTextoPesquisar.Text) Then
    strConsulta += " AND (c.Nome LIKE '" & txtTextoPesquisar.Text & "%' OR c.Sobrenome LIKE '" & txtTextoPesquisar.Text & "%') "
End If
selecao = 2
Case 3
'produtor
If Not String.IsNullOrEmpty(txtTextoPesquisar.Text) Then
    strConsulta += " AND d.Nome LIKE '" & txtTextoPesquisar.Text & "%'"
End If
selecao = 3
End Select

Após a consulta percorremos o dataset gerado, extraímos as informações para cada registro e exibimos no controle ListView:

'percorre os registros tabela obtida
For Each drLinha In dsDts.Tables("Resultado").Rows
  
'obtem as linhas e atribui a uma array de strings : Id do filme(0) , o titulo(4), ator(5), diretor(6) e produtor(7)
   Dim strRegistrosResultado As String() = {drLinha(0), drLinha(4), drLinha(5), drLinha(6), drLinha(7)}
  
'exibe cada linha do array no controle listview
   lvResultadoPesquisa.Items.Add(New ListViewItem(strRegistrosResultado))
  
'incrementa o contador de registros
   intNumeroRegistros += 1
Next

Estamos usando um bloco Try/Catch/Finally para capturar possíveis erros e na cláusula Finally estamos liberando os recursos usados.

O bloco try-catch-finally é usado para envolver o código onde existe a possibilidade de uma exceção/erro ocorrer. Um bloco try-catch-finally é constituído das seguintes seções :

  1. O código que pode gerar uma exceção é colocando dentro do bloco try
  2. Se o erro/exceção ocorrer o bloco catch entra em ação e o você faz o tratamento do erro
  3. Dentro do bloco finally você coloca o código que deverá ser executado sempre quer ocorra ou não a exceção.
Try
 
 'Código que pode gerar(levantar)  um erro.
Catch
   '
Código para tratamento de erros.
Finally
  
'Código de execução obrigatória.
End Try

Obs: O VB.NET ainda mantém , por questões de compatibilidade ,  a sintaxe : "On Error Goto" e você ainda pode usá-la mas prefira usar a estrutura try-catch.

Executando o projeto e realizando uma pesquisa usando somente o critério de busca sem informar um texto será exibido todos os registros que atendem o critério:

Ao informar um texto a consulta será refinada filtrando as informações com base no texto informado:

Definindo do botão Fazer Pedido.

A função btnFazerPedido_Click será executada quando o cliente seleciona um item do controle ListView e clica no botão Fazer Pedido.

O código desta função deve verificar se o cliente selecionou todos os registros exibidos no seu resultado da pesquisa. Se não houver itens selecionados será exibida uma mensagem ao cliente.

Se o usuário for um cliente registrado e estiver logado o formulário de Pedidos - frmPedidos - será exibido para que o cliente faça o seu pedido. Caso contrário ele terá que efetuar o login ou se registrar usando o formulário frmRegistros.

Abaixo vemos o código da associado ao evento Click do botão bntFazerPedido:

 Private Sub btnFazerPedido_Click(sender As Object, e As EventArgs) Handles btnFazerPedido.Click
         'conta quantos itens forma selecionados do listview
        Dim intTotalSelecionadosContador As Integer = lvResultadoPesquisa.CheckedItems.Count
        'se houve itens então obtém os valores dos itens e preenche a classe Filme 
        If intTotalSelecionadosContador > 0 Then
            For Each item As ListViewItem In lvResultadoPesquisa.CheckedItems
                filmesSelecionados.Add(New Filme() With 
{.Id = item.SubItems(0).Text, .titulo = item.SubItems(1).Text, .ator = item.SubItems(2).Text, .diretor = item.SubItems(3).Text, .produtor = item.SubItems(4).Text})
            Next
        Else
            MessageBox.Show("Você não selecionou nenhum filme." & vbCrLf 
& "Por gentileza, selecione os filmes a partir da lista e clique no botão ""Fazer Pedido"" ! ", "Selecionar Filme", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Return
        End If
            'Verifica se o cliente esta logado 
        If (String.IsNullOrEmpty(Geral.clienteLogin)) Then
            MessageBox.Show("Você não realizou o login ou não é um cliente cadastrado." & vbCrLf & "Faça o logon ou registre-se para poder realizar pedidos.")
            Return
        Else
            'cria uma instância do formulário de pedidos
            oFrmPedidos = New frmPedidos
            'invoca a função setFilmesSelecionados() passando a lista de filmes selecionados e a quantidade como parâmetro
            oFrmPedidos.setFilmesSelecionados(filmesSelecionados, intTotalSelecionadosContador)
            'exibe o formulário do pedido
            oFrmPedidos.Show()
        End If
    End Sub

Entendendo o código:

Contamos quantos itens foram selecionados no controle ListView usando a propriedade Count na coleção CheckedItems.

Se houver pelo menos um item selecionado então vamos extrair os valores a partir do controle Listview percorrendo a coleção CheckedItems usando o um laço For Each:

For Each item As ListViewItem In lvResultadoPesquisa.CheckedItems
       filmesSelecionados.Add(New Filme() With {.Id = item.SubItems(0).Text, .titulo = item.SubItems(1).Text, .ator = item.SubItems(2).Text, .diretor = item.SubItems(3).Text, .produtor = item.SubItems(4).Text})
Next

Nesta laço estamos preenchendo uma lista genérica de filmes com objetos da classe Filme.

A lista genérica do tipo Filme foi definida como estática no início do formulário : Public Shared filmesSelecionados As New List(Of Filme)

Esta usando a coleção List(Of T) que representa uma lista fortemente tipada de objetos que podem ser acessados através de um índice. Fornece os métodos Search, Sort e efetua a manipulação da lista. No nosso exemplo T seria a classe Filme.

Verificamos também se o cliente esta logado consultando a variável pública ClienteLogin definida no módulo Geral. No formulário de Login se o cliente se logar com sucesso essa variável receberá o login do usuário caso contrário ele estará vazia.

Para os clientes logados iremos abrir o formulário de pedidos usando o código abaixo:

'cria uma instância do formulário de pedidos
oFrmPedidos = New frmPedidos
'invoca a função setFilmesSelecionados() passando a lista de filmes selecionados e a quantidade como parâmetro
oFrmPedidos.setFilmesSelecionados(filmesSelecionados, intTotalSelecionadosContador)
'exibe o formulário do pedido
oFrmPedidos.Show()

Note que criamos uma instância da classe frmPedidos : oFrmPedidos = New frmPedidos

E atribuímos a coleção preenchida com os valores dos itens selecionados e o contador de itens ao método setFilmesSelecionados() do formulário frmPedidos.

A seguir abrimos e exibimos este formulário ao cliente: oFrmPedidos.Show()

Na próxima aula iremos criar o código do formulário de pedidos frmPedidos.

Referências:


José Carlos Macoratti