curso - utilizando classe no access - as classes venda e datalhevenda
DESCRIPTION
BomTRANSCRIPT
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 1/19
Home Vídeos-aulas Tutoriais Dicas Blog Downloads Contato Artigo
SELECT Venda.codVenda, Venda.codCliente, Venda.dataVenda, DetalheVenda.codProduto, DetalheVenda.qtdProduto, Produto.descricao, Produto.unidade, Produto.valorUnitario, (Produto.valorUnitario*DetalheVenda.qtdProduto) AS SubTotalFROM Venda LEFT JOIN (Produto RIGHT JOIN DetalheVenda ON Produto.codProduto=DetalheVenda.codProduto) ON Venda.codVenda=DetalheVenda.codVenda;
Option Compare Database
Option Explicit
'Atributos da Classe
'Atributo de backup e atributo identificador da Classe
'PK - Código que identifica a venda.
Private bkpCodVenda As Variant
Private lngCodVenda As Variant
'FK - Código que indica o cliente relativo à venda.
Private lngCodCliente As Variant
'Objeto da classe de Descrição de Tipo
Private objetoCliente As New clsCliente
'Data de realização da venda.
Private dtmDataVenda As Variant
'Métodos Get, Set e Let da Classe
Property Get codVenda() As Variant
codVenda = lngCodVenda
End Property
Property Let codVenda(argCodVenda As Variant)
lngCodVenda = argCodVenda
Utilizando Classe no Access - As Classes Venda e DatalheVenda
Por: Plinio Mabesi
Estamos chegando na reta final da criação do sistema de vendas orientado a objetos.
Nesta etapa veremos a codificação das classes Venda e DetalheVenda, além da implementação de umPDV que será a nossa interface gráfica para realização das vendas.
No desenrolar da criação dos códigos com certeza você encontrará rotinas repetitivas, funções nãotão necessárias e instâncias em excesso. Além disso, poderá sentir falta de funcionalidadesimportantes em um PDV ou mesmo na totalidade do sistema de vendas. E digo mais, agora que já épraticamente um “expert” em VBA e orientação a objetos perceberá que um ou outro método poderiaser mais bem implementado de outra maneira. Mas antes de queimar neurônios tentando entender porque o trabalho está assim tão “mal projetado”, lembre-se que tudo foi feito com fins didáticos, e arepetitividade foi proposital, somente para que você fique cansado de tanto manipular objetos erealmente aprenda como utilizá-los.
Não estaremos totalmente livres do aparecimento de “bugs”, pois apenas nos locais estritamentenecessários foram inseridas rotinas de tratamento de erros. Estes algoritmos são cansativos de sepreparar, então me dei ao luxo de não incluir em todos os procedimentos, funções e métodos dosistema. Porém nada impede que você, que já pesquisou o assunto e agora “saca” muito deprogramação, implemente ao seu bel prazer, corrigindo erros que porventura se apresentem.
Então chega de papo e mãos à obra...
A Consulta CVenda
Deveremos criar uma consulta que será utilizada por um método da classe Venda. O nome daconsulta será CVenda e seu código SQL será o seguinte:
A Classe Venda
O objetivo desta classe, conforme dito anteriormente, é oferecer funcionalidades de inclusão,consulta, atualização e exclusão dos objetos do tipo venda.
Este é o código da classe, com todos os seus atributos e métodos, que se utilizam de funçõespróprias, bem como dos métodos dos objetos da classe ConexaoBD e da classe Cliente.
Código da classe:
Usando Access
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 2/19
If IsEmpty(bkpCodVenda) Then
bkpCodVenda = lngCodVenda
End If
End Property
Property Get codCliente() As Variant
codCliente = lngCodCliente
End Property
Property Let codCliente(argCodCliente As Variant)
lngCodCliente = argCodCliente
End Property
Property Get dataVenda() As Variant
dataVenda = dtmDataVenda
End Property
Property Let dataVenda(argDataVenda As Variant)
dtmDataVenda = argDataVenda
End Property
Property Get objCliente() As Variant
If Not IsEmpty(codCliente) Then
If objetoCliente.obter(codCliente) Then
Set objCliente = objetoCliente
End If
End If
End Property
'Método Existe [Com conhecimento de SQL]
'Verifica a existência do objeto Venda na tabela
'correspondente no Banco de Dados
Function existe(argCodVenda As Variant) As Boolean
On Error GoTo Err_existe
Dim objCon As New aclConexaoBD
Dim rstExiste As Recordset
Dim strSql As String
existe = False
strSql = "Select * " & _
"From Venda " & _
"Where codVenda = " & objCon.valorSql(argCodVenda)
Set rstExiste = objCon.consulta(strSql)
If rstExiste.RecordCount > 0 Then
existe = True
End If
'Fecha o Recordset existe
rstExiste.close
Exit_existe:
Set rstExiste = Nothing
Exit Function
Err_existe:
existe = False
GoTo Exit_existe
End Function
'Método Incluir [Com conhecimento de SQL]
'Inclui um novo objeto na tabela correspondente
'dentro do Banco de dados
Function incluir() As Boolean
On Error GoTo Err_incluir
Dim objCon As New aclConexaoBD
Dim strSql As String
strSql = "Insert Into " & _
"Venda(codVenda,codCliente,dataVenda) " & _
"Values(" & objCon.valorSql(codVenda) & "," & _
objCon.valorSql(codCliente) & "," & _
objCon.valorSql(dataVenda) & ")"
incluir = (objCon.executa(strSql) > 0)
If incluir Then
'Atualiza os campos de backup
bkpCodVenda = codVenda
End If
Exit_incluir:
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 3/19
Exit Function
Err_incluir:
incluir = False
GoTo Exit_incluir
End Function
'Método Excluir [Com conhecimento de SQL]
'Exclui o objeto atual na tabela correspondente
'dentro do Banco de dados
Function excluir() As Boolean
On Error GoTo Err_excluir
Dim objCon As New aclConexaoBD
Dim strSql As String
strSql = "Delete From Venda " & _
"Where codVenda = " & objCon.valorSql(codVenda)
excluir = (objCon.executa(strSql) > 0)
Exit_excluir:
Exit Function
Err_excluir:
excluir = False
GoTo Exit_excluir
End Function
'Método Obter [Com conhecimento de SQL]
'Recupera o objeto Venda através dos argumentos informados
Function obter(argCodVenda As Variant) As Boolean
On Error GoTo Err_obter
Dim objCon As New aclConexaoBD
Dim rstObter As Recordset
Dim strSql As String
strSql = "Select * " & _
"From Venda " & _
"Where codVenda = " & objCon.valorSql(argCodVenda)
Set rstObter = objCon.consulta(strSql)
If rstObter.RecordCount = 0 Then
obter = False
Exit Function
End If
'Atualiza os campos de backup
'e os identificadores
codVenda = argCodVenda
bkpCodVenda = argCodVenda
'Atualiza os campos restantes
codCliente = rstObter.Fields("codCliente")
dataVenda = rstObter.Fields("dataVenda")
obter = True
'Fecha o Recordset obter
rstObter.close
Exit_obter:
Set rstObter = Nothing
Exit Function
Err_obter:
obter = False
GoTo Exit_obter
End Function
'Método Salvar [Com conhecimento de SQL]
'Salva o objeto atual na tabela correspondente
'dentro do Banco de dados
Function salvar() As Boolean
On Error GoTo Err_salvar
Dim objCon As New aclConexaoBD
Dim strSql As String
If existe(bkpCodVenda) Then
strSql = "Update Venda " & _
"Set codVenda = " & objCon.valorSql(codVenda) & _
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 4/19
", codCliente = " & objCon.valorSql(codCliente) & _
", dataVenda = " & objCon.valorSql(dataVenda) & _
" Where codVenda = " & objCon.valorSql(bkpCodVenda)
salvar = (objCon.executa(strSql) > 0)
Else
salvar = incluir
End If
If salvar Then
'Atualiza as variáveis de backup
'com o novo valor da chave
bkpCodVenda = codVenda
End If
Exit_salvar:
Exit Function
Err_salvar:
salvar = False
GoTo Exit_salvar
End Function
'Método getValorTotal
'Calcula a valor total da venda atual e
'devolve o valor como resultado.
Function getValorTotal() As Currency
getValorTotal = Nz(DSum("SubTotal", "CVenda", _
"codVenda=" & Nz(lngCodVenda, -1)))
End Function
'Fim da classe...
Option Compare Database
Option Explicit
'Atributos da Classe
'Atributo de backup e atributo identificador da Classe
'PK - FK - Código que indica o produto relacionado.
Private bkpCodProduto As Variant
Private lngCodProduto As Variant
'Atributo de backup e atributo identificador da Classe
'PK - FK - Código que indica a venda relacionada.
Private bkpCodVenda As Variant
Private lngCodVenda As Variant
'Quantidade do poduto relacionado.
Private dblQtdProduto As Variant
'Métodos Get, Set e Let da Classe
Property Get codProduto() As Variant
codProduto = lngCodProduto
End Property
Property Let codProduto(argCodProduto As Variant)
lngCodProduto = argCodProduto
If IsEmpty(bkpCodProduto) Then
bkpCodProduto = lngCodProduto
End If
End Property
Property Get codVenda() As Variant
codVenda = lngCodVenda
End Property
Property Let codVenda(argCodVenda As Variant)
lngCodVenda = argCodVenda
If IsEmpty(bkpCodVenda) Then
A Classe DetalheVenda
O objetivo desta classe, conforme dito anteriormente, é oferecer funcionalidades de consulta eatualização dos objetos de ligação entre a venda e os produtos componentes.
Este é o código da classe, com todos os seus atributos e métodos, que se utilizam de funçõespróprias, bem como dos métodos dos objetos da classe ConexaoBD e da classe Produto.
Código da classe:
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 5/19
bkpCodVenda = lngCodVenda
End If
End Property
Property Get qtdProduto() As Variant
qtdProduto = dblQtdProduto
End Property
Property Let qtdProduto(argQtdProduto As Variant)
dblQtdProduto = argQtdProduto
End Property
'Método Existe [Com conhecimento de SQL]
'Verifica a existência do objeto DetalheVenda na
'tabela correspondente no Banco de Dados
Function existe(argCodProduto As Variant, _
argCodVenda As Variant) As Boolean
On Error GoTo Err_existe
Dim objCon As New aclConexaoBD
Dim rstExiste As Recordset
Dim strSql As String
existe = False
strSql = "Select * " & _
"From DetalheVenda " & _
"Where codProduto = " & objCon.valorSql(argCodProduto) _
And codVenda = " & objCon.valorSql(argCodVenda)"
Set rstExiste = objCon.consulta(strSql)
If rstExiste.RecordCount > 0 Then
existe = True
End If
'Fecha o Recordset existe
rstExiste.close
Exit_existe:
Set rstExiste = Nothing
Exit Function
Err_existe:
existe = False
GoTo Exit_existe
End Function
'Método Incluir [Com conhecimento de SQL]
'Inclui um novo objeto na tabela correspondente
'dentro do Banco de dados
Function incluir() As Boolean
On Error GoTo Err_incluir
Dim objCon As New aclConexaoBD
Dim strSql As String
strSql = "Insert Into " & _
"DetalheVenda(codProduto,codVenda,qtdProduto) " & _
"Values(" & objCon.valorSql(codProduto) & "," & _
objCon.valorSql(codVenda) & "," & _
objCon.valorSql(qtdProduto) & ")"
incluir = (objCon.executa(strSql) > 0)
If incluir Then
'Atualiza os campos de backup
bkpCodProduto = codProduto
bkpCodVenda = codVenda
End If
Exit_incluir:
Exit Function
Err_incluir:
incluir = False
GoTo Exit_incluir
End Function
'Método Excluir [Com conhecimento de SQL]
'Exclui o objeto atual na tabela correspondente
'dentro do Banco de dados
Function excluir() As Boolean
On Error GoTo Err_excluir
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 6/19
Dim objCon As New aclConexaoBD
Dim strSql As String
strSql = "Delete From DetalheVenda " & _
"Where codProduto = " & objCon.valorSql(codProduto) & _
" and codVenda = " & objCon.valorSql(codVenda)
excluir = (objCon.executa(strSql) > 0)
Exit_excluir:
Exit Function
Err_excluir:
excluir = False
GoTo Exit_excluir
End Function
'Método Obter [Com conhecimento de SQL]
'Recupera o objeto DetalheVenda através dos argumentos informados
Function obter(argCodProduto As Variant, _
argCodVenda As Variant) As Boolean
On Error GoTo Err_obter
Dim objCon As New aclConexaoBD
Dim rstObter As Recordset
Dim strSql As String
strSql = "Select * " & _
"From DetalheVenda " & _
"Where codProduto = " & objCon.valorSql(argCodProduto) & _
" And codVenda = " & objCon.valorSql(argCodVenda)
Set rstObter = objCon.consulta(strSql)
If rstObter.RecordCount = 0 Then
obter = False
Exit Function
End If
'Atualiza os campos de backup
'e os identificadores
codProduto = argCodProduto
bkpCodProduto = argCodProduto
codVenda = argCodVenda
bkpCodVenda = argCodVenda
'Atualiza os campos restantes
qtdProduto = rstObter.Fields("qtdProduto")
obter = True
'Fecha o Recordset obter
rstObter.close
Exit_obter:
Set rstObter = Nothing
Exit Function
Err_obter:
obter = False
GoTo Exit_obter
End Function
'Método Salvar [Com conhecimento de SQL]
'Salva o objeto atual na tabela correspondente
'dentro do Banco de dados
Function salvar() As Boolean
On Error GoTo Err_salvar
Dim objCon As New aclConexaoBD
Dim strSql As String
If existe(bkpCodProduto, bkpCodVenda) Then
strSql = "Update DetalheVenda " & _
"Set codProduto = " & objCon.valorSql(codProduto) & _
", codVenda = " & objCon.valorSql(codVenda) & _
", qtdProduto = " & objCon.valorSql(qtdProduto) & _
" Where codProduto = " & objCon.valorSql(bkpCodProduto) & _
" and codVenda = " & objCon.valorSql(bkpCodVenda)
salvar = (objCon.executa(strSql) > 0)
Else
salvar = incluir
End If
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 7/19
If salvar Then
'Atualiza as variáveis de backup
'com o novo valor da chave
bkpCodProduto = codProduto
bkpCodVenda = codVenda
End If
Exit_salvar:
Exit Function
Err_salvar:
salvar = False
GoTo Exit_salvar
End Function
'Método getSubTotal
'Calcula o subtotal do produto vendido para a
'venda atual e devolve o valor como resultado
Function getSubTotal() As Currency
Dim objProduto As New clsProduto
If Not IsNull(lngCodProduto) And Not IsNull(dblQtdProduto) Then
If objProduto.obter(lngCodProduto) Then
getSubTotal = objProduto.valorUnitario * dblQtdProduto
End If
End If
End Function
'Método getListaProduto(argCodVenda As Long)
'Recebe como parâmetro um código de uma venda e devolve
'um conjunto de registros contendo os códigos dos produtos,
'além de outros dados, relativos à venda informada.
Function getListaProduto(argCodVenda As Long) As Recordset
Dim strSql As String
Dim objCon As New aclConexaoBD
strSql = "SELECT Venda.codVenda, Venda.codCliente, Venda.dataVenda, " & _
"DetalheVenda.codProduto, DetalheVenda.qtdProduto, " & _
"Produto.descricao, Produto.unidade, Produto.valorUnitario, " & _
"(Produto.valorUnitario * DetalheVenda.qtdProduto) AS SubTotal " & _
"FROM Venda LEFT JOIN (Produto RIGHT JOIN DetalheVenda ON " & _
"Produto.codProduto=DetalheVenda.codProduto) " & _
"ON Venda.codVenda=DetalheVenda.codVenda " & _
"Where Venda.codVenda=" & argCodVenda
Set getListaProduto = objCon.consulta(strSql)
End Function
'Fim da classe...
Function listaProdutos(argCodVenda As Long, _
Optional ultimos As Integer = 0) As String
Dim rstLista As Recordset
Dim objDetalheVenda As New clsDetalheVenda
Dim contador
Set rstLista = objDetalheVenda.getListaProduto(argCodVenda)
If Not rstLista.EOF Then
rstLista.MoveLast
Else
listaProdutos = ""
Exit Function
End If
While Not rstLista.BOF And (contador < ultimos Or ultimos = 0)
listaProdutos = " " & FormatNumber(rstLista("qtdProduto"), 3) & _
" x " & FormatCurrency(rstLista("valorUnitario")) & _
Mais Funções Auxiliares
Para exibir os itens vendidos na tela, no formato de um cupom fiscal, necessitaremos de uma funçãoque busque os últimos itens registrados na venda para que possamos apresentá-los ao usuário.
Assim sendo deveremos incluir mais uma função no módulo Funcoes criado anteriormente, que seráchamada de listaProdutos() e receberá como parâmetros o código da venda e o número de itens, apartir do último, que devem ser retornados.
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 8/19
" " & FormatCurrency(rstLista("SubTotal")) & _
vbCrLf & listaProdutos
listaProdutos = Format(rstLista("codProduto"), "000000") & " " & _
rstLista("unidade") & " " & rstLista("descricao") & _
vbCrLf & listaProdutos
rstLista.MovePrevious
contador = contador + 1
Wend
End Function
'Objeto da classe de Descrição de Tipo
Private objetoCliente As New clsCliente
...
Property Get objCliente() As Variant
If Not IsEmpty(codCliente) Then
If objetoCliente.obter(codCliente) Then
Set objCliente = objetoCliente
End If
End If
End Property
...
cupomVenda = cupomVenda & "CPF: " & objVenda.objCliente.cpf & vbCrLf
cupomVenda = cupomVenda & "Nome: " & objVenda.objCliente.nomeCliente & vbCrLf
Nome: FVenda
Largura: 22cm
Altura: Cabeçalho (1,6cm) / Detalhe (15cm)
Repare que a função busca os itens começando do final do conjunto de registros, inclusive montandoas linhas também do final para o início, até que seja completada a quantidade de itens solicitada, outodos os itens caso a opção não seja informada.
Ponto Importante
Desta vez, relembrando e aprimorando os conceitos da orientação a objetos, vamos destacar o pontoa seguir.
1. Atributo do tipo objeto: Nos atributos da classe Venda podemos encontrar um que faz referênciaà classe Cliente, ou seja, o atributo é um objeto da classe Cliente. Por que isto? Apenas adiantandoum pouco o assunto do próximo artigo criaremos um modelo de cupom fiscal (bem simples, lógico!!!)no qual esta opção será muito útil. Ao invés de criarmos uma variável de objeto da classe Cliente e ainstanciarmos bastará utilizarmos o atributo incluído na classe Venda depois que a mesma for obtidaatravés do código da venda. Neste caso o objeto cliente será instanciado dentro da classe Vendaautomaticamente assim que o atributo for referenciado. Com isso será possível também acessar todosos atributos e métodos do objeto cliente. Veja os trechos de código, primeiro o método de acesso aoatributo e depois a montagem do cupom fiscal:
Declaração da variável e método de acesso ao atributo:
Montagem do Cupom Fiscal:
A Interface Gráfica
Desta vez para que possamos visualizar e manipular os dados das vendas resolvi criar um interessantesistema de PDV para ser a nossa interface gráfica, já que há tanta curiosidade acerca dos mesmos.
A tela contará com exibição dos itens registrados em formato de cupom, além do cálculo e registro deprodutos utilizando o esquema de digitação do código multiplicado pela quantidade em um únicocampo. Também faremos a verificação da descrição do produto a partir do código e o cálculo detroco a partir do valor pago, além de outras pequenas funções.
Como não poderia faltar faremos o controle de estoque, tanto baixando itens vendidos como subindoprodutos devolvidos, além de verificação de estoque baixo.
A seguir serão definidas as características para o PDV. Assim como nos anteriores as especificaçõesde design também são apenas sugestões, porém as informações de origem de dados, bloqueio decampos e formatos de dados são obrigatórias, sob pena de, novamente, não obter a funcionalidadedesejada. Como de praxe as especificações estarão marcadas com um asterisco vermelho ao lado.
No formulário teremos um rótulo que exibirá os produtos vendidos, alguns campos de texto paradigitação das informações e os botões de comando para criar e cancelar vendas, excluir produtos efechar a tela do PDV.
Obs: Somente as propriedades que foram alteradas para um valor diferente do padrão serãoapresentadas. Para as demais utilize o padrão do sistema, ou o valor que desejar, desde que nãocomprometa a funcionalidade do sistema.
Formulário
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 9/19
Cor do fundo: Cabeçalho (Vermelho) / Detalhe (Azul escuro)
Legenda: Sistema de Vendas
Estilo da borda: Fino
Seletores de registro: Não
Botões de navegação: Não
Linhas divisórias: Não
Barras de rolagem: Nenhuma
Caixa de controle: Não
Botão Fechar: Não
Botões Min Max: Nenhum
Popup: Sim
Janela Restrita: Não
Nome: lblProdutos *
Largura: 9,7cm *
Altura: 10,4cm *
Nome: txtCodigoVenda *
Formato: 000000
Ativado: Não *
Bloqueado: Sim *
Cor do fundo: Cinza
Alinhamento: Centro
Nome: txtData *
Formato: dd/mm/yyyy *
Cor do fundo: Branco
Máscara de entrada: 00/00/00;;_
Alinhamento: Centro
Nome: txtCodCliente *
Formato: 000
Cor do fundo: Branco
Alinhamento: Centro
Nome: txtNomeCliente *
Cor do fundo: Cinza
Alinhamento: Esquerda
Ativado: Não *
Bloqueado: Sim *
Nome: txtProdutoQtd *
Cor do fundo: Amarelo
Alinhamento: Esquerda
Tamanho da Fonte: 28
Nome: txtDescricao *
Cor do fundo: Cinza
Alinhamento: Esquerda
Tamanho da Fonte: 14
Ativado: Não *
Bloqueado: Sim *
Nome: txtUnidade *
Cor do fundo: Cinza
Alinhamento: Centro
Tamanho da Fonte: 14
Ativado: Não *
Bloqueado: Sim *
Nome: txtQtd *
Cor do fundo: Cinza
Formato: Padrão
Casas decimais: 3
Alinhamento: Centro
Tamanho da Fonte: 14
Ativado: Não *
Bloqueado: Sim *
Nome: txtValorUnt *
Cor do fundo: Cinza
Formato: Unidade Monetária
Alinhamento: Direita
Tamanho da Fonte: 14
Ativado: Não *
Bloqueado: Sim *
Nome: txtSubTotal *
Cor do fundo: Cinza
Formato: Unidade Monetária
Controle Label
Controles Textbox
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 10/19
Alinhamento: Direita
Tamanho da Fonte: 14
Ativado: Não *
Bloqueado: Sim *
Nome: txtTotal *
Cor do fundo: Laranja
Formato: Unidade Monetária
Alinhamento: Direita
Tamanho da Fonte: 24
Ativado: Não *
Bloqueado: Sim *
Nome: txtPago *
Cor do fundo: Cinza
Formato: Unidade Monetária
Alinhamento: Direita
Tamanho da Fonte: 16
Nome: txtTroco *
Cor do fundo: Cinza
Formato: Unidade Monetária
Alinhamento: Direita
Tamanho da Fonte: 16
Ativado: Não *
Bloqueado: Sim *
Nome: btnExcluirProduto *
Legenda: Excluir Produto
Cor da Fonte: Vermelho escuro
Nome: btnCancelar *
Legenda: Cancelar Venda
Cor da Fonte: Vermelho escuro
Nome: btnNovo *
Legenda: Nova Venda
Cor da Fonte: Azul escuro
Nome: btnFechar *
Legenda: Fechar
Cor da Fonte: Vermelho escuro
Botões de Comando
Como sugestão de design os campos deverão estar posicionados conforme demonstrado na figura aseguir, assim como devem ser adicionadas as legendas dos campos, as quais não foram descritasanteriormente:
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 11/19
Private Sub limpaExibicaoProduto()
txtDescricao = Null
txtUnidade = Null
txtQtd = Null
txtValorUnt = Null
txtSubtotal = Null
End Sub
Private Sub limpaCampos()
txtCodigoVenda = Null
txtData = Null
txtCodCliente = Null
txtNomeCliente = Null
txtProdutoQtd = Null
txtTotal = Null
txtPago = Null
txtTroco = Null
Call limpaExibicaoProduto
lblProdutos.Caption = ""
txtProdutoQtd.SetFocus
End Sub
Private Sub btnNovo_Click()
Call limpaCampos
End Sub
Private Sub txtPago_AfterUpdate()
If Not IsNull(txtPago) Then
txtTroco = CDbl(txtPago) - CDbl(Nz(txtTotal))
Else
txtTroco = Null
End If
End Sub
Sub atualizaLista()
Dim objVenda As New clsVenda
If Not IsNull(txtCodigoVenda) Then
If objVenda.obter(txtCodigoVenda) Then
lblProdutos.Caption = listaProdutos(Nz(txtCodigoVenda, -1), 10)
txtTotal = objVenda.getValorTotal
Call txtPago_AfterUpdate
End If
End If
End Sub
Códigos do Formulário
Para que nosso formulário seja capaz de manipular os dados dos objetos produto deveremosimplementar as funcionalidades necessárias que permitam criar uma nova venda, calcular os valoresdos produtos vendidos, registrar as vendas, controlar estoque, devolver produtos e cancelar a venda.
Sendo assim criaremos algumas funções genéricas que sejam úteis para quantos procedimentos delasnecessitem, reaplicando o conceito da reutilização de código. Além disso, incluiremos os códigos doscampos que possuem eventos, assim como dos botões de comando.
Todos os códigos a seguir deverão ser colocados no módulo do formulário FVenda.
1. Limpeza dos campos: Para efetuar a limpeza dos campos de preenchimento utilizaremos doisprocedimentos genérico cuja função será a de atribuir o valor nulo a todos os campos de texto, deixaro rótulo de exibição do cupom em branco e enviar o foco ao campo txtProdutoQtd. Repare que umprocedimento reutiliza o código do outro, já que os dois são independentes e o primeiro é utilizadoapenas na descrição do produto e o segundo limpa todos os campos da tela.
2. Nova venda: Para a criação de uma nova venda em branco simplesmente iremos chamar oprocedimento limpaCampos() no evento Ao Clicar do botão btnNovo.
3. Cálculo do troco: Com a finalidade de informar o valor do troco a partir do valor da venda e dovalor pago utilizaremos um procedimento que será acionado no evento Após Atualizar do campotxtPago.
4. Exibição da lista de produtos registrados: Para exibir a lista de produtos registrados sempreque for incluído ou retirado algum produto utilizaremos um procedimento genérico cuja função será ade buscar o lista utilizando a função listaProdutos(), atualizar a exibição do valor total da venda nocampo txtTotal e acionar o procedimento que calcula e exibe o valor do troco.
5. Carregamento do formulário: No evento Ao Carregar do formulário implementaremos umapequena rotina que simplesmente atualizará a lista de produtos e moverá o foco para o campo
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 12/19
Private Sub Form_Load()
Call atualizaLista
txtProdutoQtd.SetFocus
End Sub
Sub preencheVenda()
If IsNull(txtCodigoVenda) Then
txtCodigoVenda = proximoCodigo("codVenda", "Venda")
End If
If IsNull(txtData) Then
txtData = Date
End If
End Sub
Private Sub txtCodCliente_AfterUpdate()
Dim objCliente As New clsCliente
If Not IsNull(txtCodCliente) Then
If objCliente.obter(CLng(txtCodCliente)) Then
Call preencheVenda
txtNomeCliente = objCliente.nomeCliente
Else
txtNomeCliente = Null
txtCodCliente = Null
MsgBox "Código do cliente inválido!", _
vbExclamation, "Erro!"
End If
End If
End Sub
Private Sub txtProdutoQtd_Change()
Dim objProduto As New clsProduto
If txtProdutoQtd.Text <> "" Then
If InStr(txtProdutoQtd.Text, "*") = 0 Then
If IsNumeric(txtProdutoQtd.Text) Then
If objProduto.obter(CLng(txtProdutoQtd.Text)) Then
txtDescricao = objProduto.descricao
txtUnidade = objProduto.unidade
Else
txtDescricao = "Código não cadastrado..."
txtUnidade = Null
End If
txtQtd = Null
txtValorUnt = Null
txtSubtotal = Null
End If
End If
Else
txtDescricao = Null
txtUnidade = Null
End If
End Sub
txtProdutoQtd. A atualização da lista só fará sentido quando abrirmos novamente um formulário jácarregado anteriormente (por exemplo, quando abrimos o formulário, mudamos para o modo Design evoltamos para o modo Formulário).
6. Criação da venda: Ao iniciarmos uma venda deveremos gerar o código da mesma. Assim criaremosum procedimento genérico que lança mão da função proximoCodigo() para gerar o código da venda,além de atribuir a data atual caso o usuário não tenha informado alguma data específica.
7. Busca do cliente: Para que seja exibido o nome do cliente assim que o código for informadoutilizaremos esta rotina no evento Após Atualizar do campo txtCodCliente. Assim será preenchido ocampo txtNomeCliente a partir dos dados retornados pelo objeto cliente, ou então um aviso aousuário informando que o código do cliente é inválido. Ao ser informado um cliente válido a vendatambém será gerada através de uma chamada ao procedimento preencheVenda().
8. Busca do produto em tempo real: O procedimento a seguir permitirá que seja exibida a descriçãoe a unidade do produto no exato momento em que o código for digitado. Ele será incluído no eventoAo Alterar do campo txtProdutoQtd. Caso o código não corresponda a nenhum produto será exibidauma mensagem no campo txtDescricao informando que o código não está cadastrado. Veja que elesomente será executado completamente caso o valor digitado possa ser interpretado como valornumérico, ou seja, um valor compatível com o código do produto.
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 13/19
Sub exibeProduto(argDetalhe As clsDetalheVenda)
Dim objProduto As New clsProduto
If objProduto.obter(argDetalhe.codProduto) Then
txtDescricao = objProduto.descricao
txtUnidade = objProduto.unidade
txtQtd = argDetalhe.qtdProduto
txtValorUnt = objProduto.valorUnitario
txtSubtotal = argDetalhe.getSubTotal
End If
End Sub
Private Sub txtProdutoQtd_BeforeUpdate(Cancel As Integer)
On Error GoTo Err_txtProdutoQtd_AfterUpdate
Dim codigoProduto As Long
Dim qtdProduto As Double
Dim posicao As Integer
Dim status As Integer
Dim objVenda As New clsVenda
Dim objDetalhe As New clsDetalheVenda
Dim objProduto As New clsProduto
status = 0
If Not IsNull(txtProdutoQtd) Then
Call preencheVenda
posicao = InStr(txtProdutoQtd, "*")
If posicao > 0 Then
status = 1
codigoProduto = CLng(Left(txtProdutoQtd, posicao - 1))
status = 2
qtdProduto = CDbl(Right(txtProdutoQtd, Len(txtProdutoQtd) - posicao))
Else
status = 3
codigoProduto = CLng(txtProdutoQtd)
qtdProduto = 1
End If
status = 4
objVenda.codVenda = CLng(txtCodigoVenda)
status = 5
objVenda.dataVenda = CDate(txtData)
status = 6
If Not IsNull(txtCodCliente) Then
objVenda.codCliente = CLng(txtCodCliente)
End If
If objProduto.obter(codigoProduto) Then
If objProduto.qtdEstoque < qtdProduto Then
MsgBox "O estoque existente não é suficiente!" & vbCrLf & vbLf & _
"Estoque atual: " & FormatNumber(objProduto.qtdEstoque, 3) & _
" " & objProduto.unidade, _
vbExclamation, "Estoque Baixo"
Cancel = True
Exit Sub
End If
End If
9. Exibição de produto: Para exibirmos todos os dados do produto a ser registrado em uma vendacriaremos um procedimento genérico que recebe como argumento um objeto detalhe de venda cujaspropriedades e métodos fornecerão as informações para o preenchimento dos campos. Repare que ovalor do subtotal é calculado pelo método getSubTotal() do objeto.
10. Registro do produto: Cada produto constante da venda deverá ser registrado antes dofechamento da venda. Para isto deveremos realizar várias verificações, utilizando vários objetos nesteprocedimento que será incluído no evento Antes de Atualizar do campo txtProdutoQtd para queseja capaz de cancelar o registro caso alguma informação não esteja correta. Primeiro será verificadaa validade do código do produto e a correta informação da quantidade, caso seja incluída, atribuindouma unidade em caso contrário. Em seguida será checada a validade do código da venda e tambémda data, além do código do cliente, caso seja informado (uma venda sem cliente será consideradavenda ao consumidor). Para não ocorrerem conflitos o código da venda será sempre geradoautomaticamente, não sendo permitida sua alteração posterior. O próximo passo será verificar se aquantidade solicitada existe em estoque. Caso não possa ser atendida integralmente o registro écancelado. Existindo a quantidade o produto é registrado, assim como qualquer alteração nos dadosda venda. Por último a exibição dos dados é atualizada e o estoque atualizado, informando o usuáriose o estoque ficar abaixo do mínimo. Caso ocorram erros durante o processo o esquema detratamento de erros avisa o usuário sobre qual passo gerou o problema.
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 14/19
status = 7
If objVenda.salvar Then
objDetalhe.codVenda = objVenda.codVenda
objDetalhe.codProduto = codigoProduto
objDetalhe.qtdProduto = qtdProduto
status = 8
If objDetalhe.salvar Then
Call exibeProduto(objDetalhe)
Call atualizaLista
If objProduto.obter(codigoProduto) Then
status = 9
If objProduto.baixarEstoque(qtdProduto) Then
If objProduto.estoqueBaixo Then
MsgBox "O estoque ficou abaixo da quantidade mínima!" & _
vbCrLf & vbLf & _
"Estoque atual: " & FormatNumber(objProduto.qtdEstoque, 3) & _
" " & objProduto.unidade, vbExclamation, "Estoque Baixo"
End If
Else
MsgBox "Ocorreu um erro na atualização do estoque.", _
vbExclamation, "Erro!"
End If
End If
Else
MsgBox "Ocorreu um erro ao incluir o produto.", _
vbExclamation, "Erro!"
Cancel = True
End If
Else
MsgBox "Ocorreu um erro ao incluir a venda.", _
vbExclamation, "Erro!"
Cancel = True
End If
End If
Exit_txtProdutoQtd_AfterUpdate:
Exit Sub
Err_txtProdutoQtd_AfterUpdate:
Select Case status
Case 1, 3
MsgBox "Código do produto inválido!", vbExclamation, "Erro!"
Case 2
MsgBox "Quantidade do produto inválida!", vbExclamation, "Erro!"
Case 5
MsgBox "Data inválida!", vbExclamation, "Erro!"
Case 6
MsgBox "Código do cliente inválido!", vbExclamation, "Erro!"
Case 7
MsgBox "Ocorreu um erro ao incluir a venda!", vbExclamation, "Erro!"
Case 8
MsgBox "Ocorreu um erro ao incluir o produto!", vbExclamation, "Erro!"
Case 9
MsgBox "Ocorreu um erro ao atualizar o estoque!", vbExclamation, "Erro!"
Case Else
MsgBox "Ocorreu um erro. O sistema informou a seguinte mensagem:" & _
vbCrLf & vbLf & Err.Description, vbExclamation, "Erro!"
End Select
Cancel = True
Resume Exit_txtProdutoQtd_AfterUpdate
End Sub
Private Sub txtProdutoQtd_AfterUpdate()
btnNovo.SetFocus
txtProdutoQtd.SetFocus
txtProdutoQtd = Null
Call preencheVenda
Obs: Apenas para esclarecimento sobre o tratamento de erros lembre-se que este não é umsistema real. Sendo assim os códigos foram colocados de qualquer maneira para atingir o objetivodo curso: aprender a utilizar os objetos. Da maneira que foram implementados os registros um errono meio do processo impediria que o final do registro de uma venda ou de um produto ocorresse,deixando os dados corrompidos. Em um sistema real deveriam ser utilizadas transações paragarantir que todos os processos ocorressem integralmente, do início ao fim, ou então que todas asetapas fossem canceladas e os dados retornassem ao estado original. Não poderíamos, porexemplo, ter uma venda registrada sem que o estoque fosse atualizado. Mas isto é outra história...
11. Atualização das informações: Após o registro de um produto as informações exibidas devemser atualizadas e o foco retornar para o campo de digitação de produto e quantidade, a fim de queele esteja pronto para efetuar novo registro. Para executar esta tarefa criaremos um procedimento noevento Após Atualizar do campo txtProdutoQtd.
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 15/19
Call atualizaLista
End Sub
Private Sub btnExcluirProduto_Click()
Dim objDetalheVenda As New clsDetalheVenda
Dim objProduto As New clsProduto
Dim codigoProduto As String
If Not IsNull(txtCodigoVenda) Then
codigoProduto = InputBox("Informe o código do produto a ser excluído:", _
"Exclusão de Produto")
Else
Exit Sub
End If
If codigoProduto <> "" Then
If IsNumeric(codigoProduto) Then
If objDetalheVenda.obter(CLng(codigoProduto), CLng(txtCodigoVenda)) Then
If objProduto.obter(CLng(codigoProduto)) Then
If objProduto.subirEstoque(objDetalheVenda.qtdProduto) Then
If objDetalheVenda.excluir Then
MsgBox "O produto foi excluído com sucesso!", _
vbInformation, "Exclusão de Produto"
Call atualizaLista
Else
MsgBox "Ocorreu um erro durante a exclusão do produto!", _
vbExclamation, "Exclusão de Produto"
End If
End If
End If
End If
Else
MsgBox "Código de produto inválido!", _
vbExclamation, "Exclusão de Produto"
End If
End If
End Sub
Private Sub btnCancelar_Click()
Dim objVenda As New clsVenda
Dim objDetalheVenda As New clsDetalheVenda
Dim objProduto As New clsProduto
Dim rstLista As Recordset
If objVenda.obter(Nz(txtCodigoVenda, -1)) Then
If MsgBox("Confirma o cancelamento da venda?", _
vbQuestion + vbYesNo, "Cancelar Venda") = vbYes Then
Set rstLista = objDetalheVenda.getListaProduto(txtCodigoVenda)
While Not rstLista.EOF
Call objProduto.obter(rstLista("codProduto"))
Call objProduto.subirEstoque(rstLista("qtdProduto"))
rstLista.MoveNext
Wend
If objVenda.excluir Then
MsgBox "A venda foi cancelada com sucesso.", _
vbInformation, "Cancelar Venda"
12. Exclusão de produto da venda: Caso tenhamos que excluir um único produto da venda, antesque ela seja fechada, deveremos desfazer os passos executados no registro do mesmo. Para istodevemos criar um procedimento no evento Ao Clicar do botão btnExcluirProduto. Ele seráencarregado de solicitar ao usuário o código do produto que deverá ser excluído, checando suavalidade, atualizando o estoque e finalmente excluindo o produto, sendo que os dados de exibiçãodevem ser novamente atualizados através de uma chamada ao procedimento genéricoatualizaLista(). Repare que não excluiremos o produto em si, mas apenas o seu registro na venda.
Obs: Veja que não incluí tratamento de erro neste procedimento. Também não incluí e nem incluireiem vários outros. Esta tarefa deverá ser executada no evento Ao Praticar do objetoLeitorAplicado.
13. Cancelamento da venda: Assim como podemos excluir um produto registrado também podemoscancelar uma venda inteira. Para executar esta tarefa deveremos desfazer todos os passosexecutados para registrar todos os produtos até o momento. O procedimento responsável seráincluído no evento Ao Clicar do botão btnCancelar. O cancelamento deverá contemplar a busca doconjunto de registros dos produtos da venda, através do método getListaProduto() do objetodetalhe de venda, que serão verificados um a um para retorno ao estoque. Em seguida a venda seráexcluída, ocasionando a exclusão dos registros associados na tabela DetalheVenda pelo mecanismodo relacionamento em cascata. Após a exclusão os campos serão limpos para iniciar nova venda.
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 16/19
Call limpaCampos
Else
MsgBox "Ocorreu um erro durante o cancelamento.", _
vbExclamation, "Cancelar Venda"
End If
End If
End If
End Sub
Private Sub btnFechar_Click()
DoCmd.close
End Sub
Venda00.zip
Artigos Relacionados
Utilizando Classe no Access - Introdução
Utilizando Classe no Access - Parte 1 - Orientação a Objetos
Utilizando Classe no Access - Parte 2 - Programação OO no Access/Vba
Utilizando Classe no Access - Parte 4 - As Classes Auxiliares
Utilizando Classe no Access - Parte 5 - A Classe Cliente
Utilizando Classe no Access - Parte 6 - A Classe Produto
Utilizando Classe no Access - Parte 7 - As Classes Venda e Detalhe de Venda
Utilizando Classe no Access - Parte 8 - Finalização do Sistema
Utilizando Classe no Access - Parte 9 - Genesis: A Ferramenta Case
Utilizando Classe no Access - Parte 10 - Conclusão
Como estudar com o Pesquisador de Objetos
14. Fechamento do PDV: Para encerrarmos as atividades no PDV simplesmente iremos incluir umprocedimento que fecha o formulário no evento Ao Clicar do botão btnFechar.
Sistema de Exemplo
Novamente será disponibilizado o link para download do sistema de vendas, já atualizado com todosos recursos do estado de desenvolvimento em que se encontrar o projeto.
Continua a recomendação de consultar o exemplo apenas para tirar dúvidas e verificar como foi feito,além de ver o sistema em funcionamento. Treinem bastante, digitem, testem, façam o cérebro pedirágua. Esta é a única maneira de realmente assimilar o conhecimento.
Segue o link para download:
Caso ainda não esteja com uma tela principal abra o formulário FVenda diretamente na janela Bancode Dados (Access 2003-) ou no Painel de Navegação (Access 2007+).
Conclusão
Depois desta exaustiva etapa foi possível percebermos o quanto os objetos devem interagir parachegar ao fim de uma tarefa. Funções, procedimentos, eventos, métodos e atributos trabalham emconjunto para produzir resultados que atendam as necessidades do usuário.
Este artigo foi dedicado a demonstrar de maneira maçante a criação, utilização e troca deinformações entre objetos em meio aos códigos do restante do sistema, por isso mesmo foi bem maislongo que os demais.
Além de toda a programação em si foi possível trabalharmos apresentando um sistema interessante,útil e muito comum no dia a dia, do qual muitos tinham a curiosidade de conhecer e compreender aforma de implementação: o PDV. Mas nosso sistema de vendas ultramoderno, com tecnologiaorientada a objetos, não estaria completo sem ele, não é mesmo?
Aqui praticamente encerramos a parte mais trabalhosa. De agora em diante veremos apenas afinalização do sistema, algo mais estético do que funcional, além de um pouco mais teoria nos artigosseguintes, com a apresentação do Genesis, a ferramenta case para VBA que facilitará a sua vida, e aabordagem sobre utilização de objetos no MS-Access para aprimorar seus projetos.
Conto com a presença de todos na próxima etapa, pois esta é a razão de ser desta série de artigos.
Até lá...
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 17/19
Enoque Nunes 15/09/2010 13:25:27
E ai grande mestre Plínio, beleza meu amigo?
Cara, você está de parabens mesmo pelo artigo, baixei seu segundo exemplo e pasme, achei fantástico, sempre quis fazer algo semelhante e nãosabia nem por onde começar. rsrsrsrs
Mas, vamos lá.
Estive explorando ontem à noite seu PDV e acredito que encontrei um o erro.
Veja só.
Cadastrei um produto e dei entrada de 05 peças, fui dando baixa um a um, até ai tudo bem, o problema veio depois que as 05 peças tinhamacabado e o PDV continuou aceitando baixa e sem zerar o estoque, ele fica parado sempre com uma peça no estoque e sem abrir mensagem deestoque zero.
Assim, lancei várias saidas no PDV com uma única peça de saldo no estoque, eu tinha dado entrada apenas de 05 peças.
Dá uma checada ai amigão.
Abraços e fica com Deus.
Plinio Mabesi 17/09/2010 18:01:55
Olá Grande Enoque...
Estive aí na sua terrinha semana passada, mas foi uma passagem rápida.Vou checar o programa e assim que corrigir peço para o Avelino postar a correção.
Valeu...
Enoque Nunes 18/09/2010 09:02:47
Cara, como é que você faz uma coisa dessas, vir aqui e não me avisar? rsrsrsrs, iria lhe convidar para comer um delicioso churrasco de tambaqui.
Mas, oportunidades acredito que não irão faltar.
Abraços amigão e fica na paz do Senhor Jesus.
Até mais.
Plinio Mabesi 22/09/2010 20:02:04
O erro está no método baixarEstoque() da classe Produto. O código deve ser alterado para este:
Function baixarEstoque(argQtd As Double) As Boolean
If dblQtdEstoque - Abs(argQtd) < 0 ThenbaixarEstoque = FalseElsedblQtdEstoque = dblQtdEstoque - Abs(argQtd)baixarEstoque = salvarEnd If
End Function
Como o método considerava como falso resultados menores ou iguais a zero o estoque nunca reduzia a quantidade para abaixo de 1 unidade.Deixando falso apenas os valores menores que zero tudo corre normalmente.Mas lembrem-sem que isto não quer dizer que não haja outros erros.Agradeço por novas informações.
Valeu Enoque...
Enoque Nunes 24/09/2010 08:57:54
Valeu Grande Plínio.
Testei e está tudo certinho dessa vez.
Abraços e fica com Deus.
Enoque Nunes 27/09/2010 13:52:30
E ai Plínio, beleza?
Cara, me diz uma coisa, o problema todo estava sendo causado apenas pelo sinal de "=" na linha: If dblQtdEstoque - Abs(argQtd) <= 0 Then ?
Foi a única coisa que alterei no exemplo anterior para poder funcionar normalmente, depois disso funcionou sem problemas, até arrisquei colocarde volta o sinal de "=" para ver o que ia acontecer e para minha surpresa funcionou sem erros.
Não sei qual foi a jogada, mas funcionou.
Abraços amigão e até a próxima.
| Home | Vídeos-aulas | Tutoriais | Dicas | Blog | Downloads | Contato | Artigo |
9 comentários
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 18/19
Wemerson Bernardo 31/01/2011 13:05:31
Olá,
Sei que já contrinbuiu demais com o bd disponibilizado (VendaOO). Confesso que segui suas dicas, estou estudando bastanteo Gênesis, e as dicas no site. Mas como não entendia muito de VBA, até assimilar tudo pode ser que demore um pouco, e ainda assim continuo comdúvida.Como vc me orientou, gerei os códigos com o gênesise não consegui ainda. Primeiro acrescentei o campo codBarra como string, coloquei como chave primária tb, o acrescentei na tab DetalheVenda, fiz as relações e nada.
Sem sucesso, tentei apenas mudar as propriedades do campo existente codProduto para texto. (Para caber a qtd de digitos)
Gerei o código com o gêneses e comparei linha por linha com o do projeto original (e não vi nada diferente).
Então. Acho que o erro está no evento AO ALTERAR do campo txtProdutoQtd
sempre que vou digitar mostra o seguinte erro:
Mesmo o produto estando cadastrado na tabela Produto informa: Código não Cadastrado e também
"Erro SQL: Select*From Produto Where codProduto=1 (= a Um ou o 1º nº digitado)
Outro caso é a linha if is numeric, acho que deveria alterar, já que o campo passou a ser texto, não?
Enfim, gostaria muito dessa ajuda.
----------------Private Sub txtProdutoQtd_Change()
Dim objProduto As New clsProduto
If txtProdutoQtd.Text <> "" ThenIf InStr(txtProdutoQtd.Text, "*") = 0 ThenIf IsNumeric(txtProdutoQtd.Text) ThenIf objProduto.obter(CLng(txtProdutoQtd.Text)) ThentxtDescricao = objProduto.descricaotxtUnidade = objProduto.unidadeElsetxtDescricao = "Código não cadastrado..."txtUnidade = NullEnd IftxtQtd = NulltxtValorUnt = NulltxtSubtotal = NullEnd IfEnd IfElsetxtDescricao = NulltxtUnidade = NullEnd If
End Sub
No evento antes de atualizarPrivate Sub txtProdutoQtd_BeforeUpdate(Cancel As Integer)On Error GoTo Err_txtProdutoQtd_AfterUpdate
Dim codigoProduto As Long não sei se continua como long ouDim codigoProduto As String
Mais uma vez, Desculpas e Grato desde já.
johann 28/05/2013 19:55:08
Boa noite plinio, meu nome é johann e eu gostei do seu resultado sobre o pdv mostrado no seu site e dei uma melhorada colocando senhas elogins, permissoes de usuarios e entre outros pra transformar em um verdadeiro sistema mais tenho uma duvida, se vc poder me ajudar eu sereimuito grato. Eu queria colocar ao inves de codproduto*qtdproduto na tela de venda codigoDeBarra*qdeProduto ou se podesse digitar codigo doproduto ou codigo de barra x a quantidade do produto e ele funcionasse. Porque aonde eu trabalho tanto eu digito o codigo do produto como ocodigo de barra. Obrigado e fico no seu aguardo.
Gil Kléber 16/04/2014 16:55:58
Olá Plínio! Parabens pela atitude de deixar seu sistema disponivel para download! Me ajudou muuito!!!No entanto, há algo (que para vc deve sem bem simples de fazer) que não consigo fazer:
Coloquei uma caixa de combinação no formulário FVenda, para selecionar 2 vendedores. Consegui fazer com que aparecesse no cupom fiscal semproblemas, mas não consigo salvar na tabela Vendas. (preciso salvar esse campo e o campo TOTAL, pq faço calculos de comissão no final do mês).Pode me ajudar?
Mais uma coisinha... não consigo adicionar 2 produtos do mesmo código e isso será recorrente aqui na minha lojinha... como posso fazer??
Grande abraço e mais uma vez, obrigado!
Envie seu comentário:
Nome:
30/06/2015 Curso - Utilizando Classe no Access - As Classes Venda e DatalheVenda
http://www.usandoaccess.com.br/tutoriais/classe-no-access-venda.asp?id=1#inicio 19/19
Comentário:
Digite o número setecentos e onze
comentar
© 1999 Pontocom Serviços Tecnológicos