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