VB .NET - Curso Prático ADO .NET - Desenvolvendo uma aplicação : Definindo o código da Interface - XI
O formulário de pedidos - frmPedidos - permite aos clientes visualizar os filmes selecionados com seu total e os dados do seu cartão de crédito previamente cadastrados. O cliente pode então finalizar o pedido clicando no botão - Finalizar Pedido - ou clicar no botão Cancelar para cancelar o pedido.
Este formulário utiliza as seguintes declarações imports que permite o acesso as classes ADO .NET e ao provedor para o SQL Server:
Imports
System.Data
Imports System.Data.SqlClient
No início da classe do formulário temos que declarar as seguintes variáveis:
Private
Shared intTotalFilmesSelecionados As Integer
Private Shared pedidoFilmesSelecionados As List(Of Filme)
Private Shared strIDFilmesSelecionadosTemp As String
Essas variáveis são estáticas e serão visíveis em todo o formulário.
Nota: Uma variável estática na linguagem VB .NET é declarada com a palavra chave Shared e tem sua vida útil até quando o aplicativo estiver em uso. A vida útil é o tempo que ela mantém o seu valor na memória.
Para exibir os pedidos selecionados no formulário de pesquisas - frmPesquisas, o formulário de pedidos deve receber quantidade total dos filmes e a lista de filmes selecionados. Isso é feito através da rotina setFilmesSelecionados() cujo código vemos abaixo:
Public Sub setFilmesSelecionados(ByVal filmesSelecionados As List(Of Filme), ByVal intTotalSelecionados As Integer) intTotalFilmesSelecionados = intTotalSelecionados pedidoFilmesSelecionados = filmesSelecionados End Sub |
A obtenção e a exibição das informações no formulário é feita no evento Load que ocorre quando o formulário é carregado pela primeira vez. A seguir vemos o código usado neste evento:
Private Sub frmPedidos_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'define um datarow para filmes e cartoes Dim drLinhaFilmes As DataRow = Nothing Dim drLinhaCartao As DataRow = Nothing Dim StrConsulta As String 'define um dataset, sqlcommand e sqldataAdapter Dim dsDts As DataSet Dim sqlCon As New SqlConnection(strConexaoSQLServer) Dim sqlAda As New SqlDataAdapter() Dim sqlCmd As New SqlCommand() 'verifica se houve filmes selecionados If intTotalFilmesSelecionados < 1 Then 'se não selecionou nenhum filme então avisa e sai MessageBox.Show("Não foi selecionando nenhum filme. O formulário de pedidos será fechado ! ", "Selecionar Filme", MessageBoxButtons.OK, MessageBoxIcon.Information) Me.Close() End If 'exibe o login do cliente no texto do formulário Me.Text = Text & " - " & Geral.clienteLogin & " - " & Geral.clienteCodigo.ToString strIDFilmesSelecionadosTemp = "" For i = 0 To intTotalFilmesSelecionados - 1 'inclui uma aspa simples strIDFilmesSelecionadosTemp += "'" 'armazena o id do filme selecionado na string strIDFilmesSelecionadosTemp += pedidoFilmesSelecionados.Item(i).Id.ToString() 'inclui outra aspas simples strIDFilmesSelecionadosTemp += "'" 'se houver mais de um item inclui a virgula para separar If i < intTotalFilmesSelecionados - 1 Then strIDFilmesSelecionadosTemp += "," End If Next i 'define a consulta para procurar o filmeid, titulo,ator,diretor, produto e preco associado com o filme selecionado pelo cliente StrConsulta = "SELECT DISTINCT a.FilmeId, a.Titulo, b.Nome AS Ator, c.Nome AS Diretor, d.Nome AS Produtor, f.Preco as Preco FROM Filmes a, Atores b," _ + " Diretores c, Produtores d, AtorFilme e, Video f WHERE a.FilmeId = e.FilmeId AND e.AtorId = b.AtorId AND a.DiretorId = c.DiretorId AND a.ProdutorId = d.ProdutorId AND a.FilmeId = f.FilmeId " _ + " AND a.FilmeId in (" & strIDFilmesSelecionadosTemp & ")" Try 'cria um novo dataset dsDts = New DataSet() 'define um comando e atribui a conexão associa o objecto sqladapter com o objeto connection sqlAda.SelectCommand = sqlCmd sqlAda.SelectCommand.Connection = sqlCon 'define a consulta armzaenda na varivael strConsulta para ser executada sqlAda.SelectCommand.CommandText = StrConsulta 'preenche a tabela Pedidos no dataset com o resultado da consulta sqlAda.Fill(dsDts, "Pedidos") 'limpa o controle listview antes de exibir lvPedidos.Items.Clear() 'define variavel para calcular o custo total Dim dblCustoTotal As Decimal 'percorre a tabela Pedidos preencheida com os dados da consulta For Each drLinhaFilmes In dsDts.Tables("Pedidos").Rows 'monta uma string com os registros da tabela Dim strLinhaFilmes As String() = {drLinhaFilmes(0), drLinhaFilmes(1), drLinhaFilmes(2), drLinhaFilmes(3), drLinhaFilmes(4), drLinhaFilmes(5)} 'exibe o registro no listview lvPedidos.Items.Add(New ListViewItem(strLinhaFilmes)) 'incluir o preco de cada filme calculando o preco total dos filmes dblCustoTotal += CDbl(drLinhaFilmes(5)) Next 'formata o valor e exibe no formulário txtValorTotal.Text = FormatCurrency(dblCustoTotal, 2) 'especifica a consulta para retornar os dados do cartão de credito do cliente para o cliente logado StrConsulta = "SELECT NumeroCartaoCredito, ValidadeCartao, CodigoSegurancaCartao FROM Clientes WHERE Login = '" & Geral.clienteLogin & "'" 'defina a consulta a ser executada sqlAda.SelectCommand.CommandText = StrConsulta 'preenche a tabela CartaoCredito no dataset com o resultado da consulta sqlAda.Fill(dsDts, "CartaoCredito") 'percorre os registros da tabela CartaoCredito For Each drLinhaCartao In dsDts.Tables("CartaoCredito").Rows 'exibe os dados do cartão do cliente no formulário txtNumeroCartaoCredito.Text = drLinhaCartao(0) txtValidadeCartao.Text = drLinhaCartao(1) txtCodigoSeguranca.Text = drLinhaCartao(2) Next Catch ex As Exception 'tratamento de erro MessageBox.Show("Erro : " & ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error) Finally 'libera os objetos usados sqlCon.Close() sqlAda.Dispose() End Try End Sub |
Este código monta uma string com os IDs dos filmes selecionados - strIDFilmesSelecionadosTemp - obtidos da lista dos filmes que o cliente seleciona no formulário de Pesquisa. Usamos a coleção genérica que foi preenchida com os objetos do tipo Filme definidos na classe Filme :pedidoFilmesSelecionados.Item(i).Id.ToString()
A string será usada na consulta SQL (mostrada a seguir) para obter os dados dos filmes que foram selecionados, e a seguir criamos um dataset com os dados da consulta e exibimos os dados no controle ListView:
'define a consulta
para procurar o filmeid, titulo,ator,diretor, produto e preco
associado com o filme selecionado pelo cliente
StrConsulta =
"SELECT DISTINCT a.FilmeId, a.Titulo, b.Nome AS Ator, c.Nome
AS Diretor, d.Nome AS Produtor, f.Preco as Preco FROM Filmes a,
Atores b," _
+ " Diretores c, Produtores d, AtorFilme e, Video f WHERE
a.FilmeId = e.FilmeId AND e.AtorId = b.AtorId AND a.DiretorId =
c.DiretorId AND a.ProdutorId = d.ProdutorId AND a.FilmeId =
f.FilmeId " _
+
" AND a.FilmeId in (" & strIDFilmesSelecionadosTemp & ")"
Continuando, geramos outro dataset para obter os dados do cartão de crédito do cliente e preenchemos os controles TextBox do formulário com as informações:
'especifica a
consulta para retornar os dados do cartão de credito do cliente
para o cliente logado
StrConsulta = "SELECT
NumeroCartaoCredito, ValidadeCartao, CodigoSegurancaCartao FROM
Clientes WHERE Login = '" & Geral.clienteLogin &
"'"
'defina a
consulta a ser executada
sqlAda.SelectCommand.CommandText = StrConsulta
'preenche a
tabela CartaoCredito no dataset com o resultado da consulta
sqlAda.Fill(dsDts, "CartaoCredito")
Quando o usuário clicar no botão Finalizar Pedido - devermos gravar as informações nas tabelas Pedidos e DetalhesPedidos concluindo assim o processo.
Abaixo temos o código associado ao evento Click do botão Finalizar Pedido:
Private Sub btnEfetivarPedido_Click(sender As Object, e As EventArgs) Handles btnEfetivarPedido.Click Dim strConsulta As String Dim intNumeroPedido As Integer ' Dim sqlCon As New SqlConnection(strConexaoSQLServer) Dim sqlAda As New SqlDataAdapter() Dim sqlCmd As New SqlCommand() ' 'chama a função getGeraNumeroPedido que armazena o valor maximo do ultimopedido retornado 'incrementa o numero do pedido de uma unidade intNumeroPedido = getGerarNumeroPedido() + 1 'define uma consulta para retornar o codigo dos videos para os filmes selecionados Dim strSelecao As String = "SELECT MAX(VideoID), COUNT(FilmeId) from Video WHERE FilmeId IN (" & strIDFilmesSelecionadosTemp & ") GROUP BY FilmeId" 'cria um novo dataset Dim DsDataSet As New DataSet 'atribui a consulta e a conexão ao objeto command Dim cmdSeleciona As New SqlCommand(strSelecao, sqlCon) Try sqlAda.SelectCommand = cmdSeleciona 'abre a conexão sqlCon.Open() 'preenche a tabela VideoInfo nodataset com o resultado da consulta sqlAda.Fill(DsDataSet, "VideoInfo") Catch MinhaException As SqlException 'exibe mensagem de erro MessageBox.Show(("Fonte: " & MinhaException.Source & ControlChars.Cr & "Numero: " & MinhaException.Number.ToString() & ControlChars.Cr & _ "Estado: " & MinhaException.State.ToString() & ControlChars.Cr & "Classe: " & MinhaException.Class.ToString() & ControlChars.Cr & "Server: " & MinhaException.Server & ControlChars.Cr & _ "Mensagem: " & MinhaException.Message & ControlChars.Cr & "Procedure: " & MinhaException.Procedure & ControlChars.Cr & "Linha: " & MinhaException.LineNumber.ToString())) Return Finally cmdSeleciona.Dispose() End Try Dim drLinhaVideo As DataRow Dim StrVideoLista As String = "" Dim strQuantidadeFilmes As String = "" Dim nContador As Integer = 0 'define uma array parra armazenar os videos Dim ArrayVideoLista() As String = New String(10) {} 'percorre a tabela VideoInfo e gera uma string com os codigos dos videos para usar na consulta For Each drLinhaVideo In DsDataSet.Tables("VideoInfo").Rows If nContador > 0 Then StrVideoLista += "," End If 'inclui o codigo do video na string StrVideoLista += drLinhaVideo(0).ToString() 'atribui o codigo do video no array ArrayVideoLista(nContador) = drLinhaVideo(0).ToString() 'incrementa o contador nContador += 1 strQuantidadeFilmes = drLinhaVideo(1) Next Dim strValorTotalPedido As String 'define a consulta para calcular o preco total dos filmes do pedido do cliente strConsulta = "SELECT SUM(Preco) FROM Video WHERE VideoId IN (" & StrVideoLista & ")" 'define a consulta a ser executada sqlAda.SelectCommand.CommandText = strConsulta 'preenche a tabela ValorPedido com o resultado da consulta sqlAda.Fill(DsDataSet, "ValorPedido") 'armazena a primeira coluna da primeira linha retornadfa na variavel strValorTotalPedido strValorTotalPedido = DsDataSet.Tables("ValorPedido").Rows(0).Item(0) Dim strQtdTotal As String 'define a consulta para calcular o numero de itens do pedido do cliente strConsulta = "SELECT COUNT(VideoID) FROM Video WHERE VideoID IN (" & StrVideoLista & ")" 'define a consulta a ser executada sqlAda.SelectCommand.CommandText = strConsulta 'preenche a tabela QtdTotal com o resultado da consulta sqlAda.Fill(DsDataSet, "QtdTotal") 'armzena a primeira coluna da primeira linha na variavel strQtdtotal strQtdTotal = DsDataSet.Tables("QtdTotal").Rows(0).Item(0) Dim StrVideoID As String Dim j As Integer Dim intQuantidadeTotal As Integer 'define a consulta para incluir os dados na tabela Pedidos strConsulta = "INSERT INTO Pedidos (ClienteId, PedidoData, QuantidadeTotal, ValorPedido,NumeroPedido) VALUES (@ClienteID, @PedidoData, @QuantidadeTotal,@ValorPedido,@NumeroPedido); SELECT PedidoID, ClienteId, PedidoData, QuantidadeTotal,ValorPedido, NumeroPedido FROM Pedidos WHERE NumeroPedido = " & intNumeroPedido 'cria o objeto command Dim InsertCmdPedidos As New SqlCommand(strConsulta, sqlCon) sqlAda.InsertCommand = InsertCmdPedidos 'associa os parametros com as variaveis e especifica os valores dos parâmetros usados na consulta 'clienteid sqlAda.InsertCommand.Parameters.Add(New SqlParameter("@ClienteId", System.Data.SqlDbType.Int, 2, "ClienteId")) sqlAda.InsertCommand.Parameters(0).Value = Geral.clienteCodigo 'PedidoData sqlAda.InsertCommand.Parameters.Add(New SqlParameter("@PedidoData", System.Data.SqlDbType.Date, 8, "PedidoData")) sqlAda.InsertCommand.Parameters(1).Value = Now.Date 'QuantidadeTotal sqlAda.InsertCommand.Parameters.Add(New SqlParameter("@QuantidadeTotal", System.Data.SqlDbType.Int, 2, "QuantidadeTotal")) sqlAda.InsertCommand.Parameters(2).Value = Convert.ToInt32(strQtdTotal) 'ValorPedido sqlAda.InsertCommand.Parameters.Add(New SqlParameter("@ValorPedido", System.Data.SqlDbType.Money, 8, "ValorPedido")) Dim valorPedido As Decimal = Convert.ToDecimal(strValorTotalPedido) sqlAda.InsertCommand.Parameters(3).Value = valorPedido 'NumeroPedido sqlAda.InsertCommand.Parameters.Add(New SqlParameter("@NumeroPedido", System.Data.SqlDbType.Int, 2, "NumeroPedido")) sqlAda.InsertCommand.Parameters(4).Value = intNumeroPedido Try 'executa a consulta para incluir os dados na tabela Pedidos sqlAda.InsertCommand.ExecuteNonQuery() 'prepara para gravar os detalhes do pedido na tabela PedidosDeTalhes percorre For j = 0 To nContador - 1 'pega o id do video no array StrVideoID = ArrayVideoLista(j) 'armazena a quantidade de filmes na variavel strQuantidadeFilmes intQuantidadeTotal = CInt(strQuantidadeFilmes) 'define a consulta SQL para incluir os dados na tabela PedidosDetalhes strConsulta = "INSERT INTO PedidosDetalhes (VideoId, Quantidade, NumeroPedido) VALUES (@VideoId,@Quantidade,@NumeroPedido)" 'cria o objeto InsertCmdPedidosDetalhes associando-o a consulta e a conexão aberta Dim InsertCmdPedidosDetalhes As New SqlCommand(strConsulta, sqlCon) 'atribui o comando definido ao adapter sqlAda.InsertCommand = InsertCmdPedidosDetalhes sqlAda.InsertCommand.CommandText = strConsulta ' 'associa os parametros com as variaveis e especifica os valores dos parâmetros usados na consulta 'VideoId sqlAda.InsertCommand.Parameters.Add(New SqlParameter("@VideoId", System.Data.SqlDbType.Int, 2, "VideoId")) sqlAda.InsertCommand.Parameters(0).Value = Convert.ToInt32(StrVideoID) 'Quantidade sqlAda.InsertCommand.Parameters.Add(New SqlParameter("@Quantidade", System.Data.SqlDbType.Int, 2, "Quantidade")) sqlAda.InsertCommand.Parameters(1).Value = intQuantidadeTotal 'NumeroPedido sqlAda.InsertCommand.Parameters.Add(New SqlParameter("@NumeroPedido", System.Data.SqlDbType.Int, 2, "NumeroPedido")) sqlAda.InsertCommand.Parameters(2).Value = intNumeroPedido 'executa a consulta sqlAda.InsertCommand.ExecuteNonQuery() Next j Catch MinhaException As SqlException 'tratamento de erros MessageBox.Show(("Fonte: " & MinhaException.Source & ControlChars.Cr & _ "Numero: " & MinhaException.Number.ToString() & ControlChars.Cr & _ "Estado: " & MinhaException.State.ToString() & ControlChars.Cr & _ "Classe: " & MinhaException.Class.ToString() & ControlChars.Cr & _ "Servidor: " & MinhaException.Server & ControlChars.Cr & _ "Mensagem: " & MinhaException.Message & ControlChars.Cr & _ "Procedure: " & MinhaException.Procedure & ControlChars.Cr & _ "Linha: " & MinhaException.LineNumber.ToString())) Return Finally 'libera os recursos sqlCon.Close() sqlAda.Dispose() End Try 'fecha o formulario e exibe mensagem ao cliente Me.Close() MessageBox.Show("Seu pedido será entregue em 5 dias úteis. Obrigado por ser nosso cliente.", "Pedido", MessageBoxButtons.OK) End Sub |
Chamamos a função getGerarNumeroPedido() para obter um número de pedido com base nos pedidos já existente. O código desta função é visto a seguir:
Private Function getGerarNumeroPedido() As String 'define objetos ado net para acesso a dados Dim sqlCon As New SqlConnection(strConexaoSQLServer) Dim sqlAda As New SqlDataAdapter() Dim sqlCmd As New SqlCommand() Dim strSelecaoID As String 'define a consulta para obter o valor maximo do numero do pedido strSelecaoID = "SELECT MAX(NumeroPedido) FROM Pedidos" Dim SelectCmd As New SqlCommand(strSelecaoID, sqlCon) Dim dsDts As DataSet = New DataSet() Try 'define o command, abre a conexão e preenche a tabela PedidosID sqlAda.SelectCommand = SelectCmd sqlCon.Open() sqlAda.Fill(dsDts, "PedidosID") Catch MinhaException As SqlException 'tratamento de erros MessageBox.Show(("Fonte: " & MinhaException.Source & ControlChars.Cr & _ "Numero: " & MinhaException.Number.ToString() & ControlChars.Cr & _ "Estado: " & MinhaException.State.ToString() & ControlChars.Cr & _ "Classe: " & MinhaException.Class.ToString() & ControlChars.Cr & _ "Servidor: " & MinhaException.Server & ControlChars.Cr & _ "Mensagem: " & MinhaException.Message & ControlChars.Cr & _ "Procedure: " & MinhaException.Procedure & ControlChars.Cr & _ "Linha: " & MinhaException.LineNumber.ToString())) Return "" Finally 'libera os recursos sqlCon.Close() SelectCmd.Dispose() sqlAda.Dispose() End Try 'percorre a tabela PedidosID e obtem o numero do pedido Dim drLinhaPedido As DataRow Dim intNumeroPedido As Integer = 1000 For Each drLinhaPedido In dsDts.Tables("PedidosID").Rows 'se for o primeiro pedido então atribui o valor 999 If drLinhaPedido.IsNull(0) Then intNumeroPedido = 999 Else 'obtem o maior valor do pedido intNumeroPedido = drLinhaPedido(0) End If Next 'retorna o numero do pedido obtido getGerarNumeroPedido = intNumeroPedido End Function |
O código obtém um dataset com base no maior número de pedido existente: strSelecaoID = "SELECT MAX(NumeroPedido) FROM Pedidos"
Após obter o número do pedido incrementamos o seu valor de uma unidade e criamos um dataset para obter os códigos dos vídeos para os filmes selecionados usando a string que contém os IDs dos filmes:
'define uma consulta
para retornar o codigo dos videos para os filmes selecionados
Dim strSelecao As String = "SELECT MAX(VideoID), COUNT(FilmeId) from
Video WHERE FilmeId IN (" & strIDFilmesSelecionadosTemp
& ") GROUP BY FilmeId"
A seguir geramos uma nova string contendo os IDs dos vídeos e criamos dois datasets usando consultas SQL com base na string que contém os IDs dos vídeos:
1- O dataset que calcula os preços dos filmes : sqlAda.Fill(DsDataSet, "ValorPedido")
'define a consulta
para calcular o preco total dos filmes do pedido do cliente
strConsulta = "SELECT SUM(Preco) FROM
Video WHERE VideoId IN (" & StrVideoLista &
")"
2- O dataset que calcula o número de itens no pedido : sqlAda.Fill(DsDataSet, "QtdTotal")
'define a consulta
para calcular o numero de itens do pedido do cliente
strConsulta = "SELECT
COUNT(VideoID) FROM Video WHERE VideoID IN (" &
StrVideoLista & ")"
Finalmente usando a instrução SQL INSERT INTO incluímos os dados do pedido do cliente na tabela Pedidos e os itens do pedido na tabela PedidosDetalhes.
As consultas usadas são parametrizadas e os parâmetros são incluídos na coleção Parameters onde primeiro definimos o nome do parâmetro (@VideoId), o seu tipo (System.Data.SqlDbType.Int), o tamanho (3) e a qual campo da tabela ele corresponde(VideoId) e depois atribuímos o valor ao parâmetro:Convert.ToInt32(StrVideoID)
sqlAda.InsertCommand.Parameters.Add(New
SqlParameter("@VideoId", System.Data.SqlDbType.Int, 3,
"VideoId"))
sqlAda.InsertCommand.Parameters(0).Value =
Convert.ToInt32(StrVideoID)
Para executar a instrução SQL usamos o método ExecuteNonQuery do objeto Command: sqlAda.InsertCommand.ExecuteNonQuery()
O objeto Command da ADO.NET fornece o método ExecuteNonQuery para executar consultas que não retornam linhas (registros). Apesar de não retornar registros , qualquer parâmetro de saída ou valores retornados mapeados para parâmetros do objeto Comando são preenchidos com dados.
O método ExecuteNonQuery retorna o número de linhas afetados pelas operações de Insert , Update e Delete. Para todas as demais consultas o valor retornado é -1.
Quando uma consulta falha na execução o provedor gerenciado dispara uma exceção que você pode capturar no seu código. Os provedores gerenciados ADO.NET possuem classes que fazem o tratamento das exceções. Esta classe de exceção é criada e disparada quando um erro é encontrado.
Ao final será exibida uma mensagem ao cliente informando que o pedido foi gravado com sucesso e o prazo para entrega:
Na próxima aula do curso iremos tratar do formulário de registros que será usado para cadastrar os clientes na tabela Clientes da base de dados da empresa CiaFilmes.
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Formulários Windows e a Interface com o Usuário - Macoratti.net
VB.NET - Declaração de variáveis o que mudou - Macoratti.net
ADO.NET - Uma visão geral : Objetos Connection - Macoratti.net