... Pague apenas R$47,00 uma única vez e tenha acesso por 1 ano aos vídeos e arquivos exemplos do site ...

Clique aqui e obtenha mais detalhes.


Utilizando Classe no Access - Modelagem do Sistema de Vendas

Por: Plinio Mabesi
 

Nesta etapa da série definiremos o modelo de classes do nosso sistema de vendas de alimentos. Consequentemente, faremos também o mapeamento das classes para o modelo de banco de dados relacional, o qual utilizaremos para persistir os objetos criados.

Conforme foi dito anteriormente não serão abordados tópicos aprofundados sobre o assunto. A modelagem utiliza alguns diagramas da Linguagem de Modelagem Unificada (UML), mas não segue plenamente o padrão proposto nem contempla todas as fases da modelagem. Para maiores informações sobre a UML consulte um manual especializado ou sites de referência na Internet.

Além disso o modelo adotado tem caráter didático e não pretende servir como um padrão para aplicações reais. As relações criadas, as funções definidas e os atributos escolhidos terão como objetivo maior demonstrar como funciona a aplicação da orientação a objetos no Access / VBA, mesmo não sendo a forma mais correta e eficiente de modelagem de classes ou de banco de dados.

Portanto preocupe-se em visualizar e compreender bem as técnicas utilizadas nas chamadas de métodos, criação de atributos, passagem de parâmetros, enfim esteja focado em aprender como se dá a interação entre os objetos dentro do sistema.

Padrão de Nomenclatura

O padrão que será utilizado neste trabalho obedecerá às seguintes definições:

> Não serão usados acentos, símbolos ou espaços nos nomes, já que isto é uma prática que causa problemas na maioria das linguagens de programação existentes, não sendo nem mesmo aceita em várias delas.

> Nomes de classes começando em maiúsculas, com o restante em minúsculas. Quando o nome da classe for formado por mais de uma palavra elas serão separadas por maiúscula.

Ex: Cliente, Venda, DetalheVenda;

>
Nomes de atributos em minúsculas. Quando o nome do atributo for formado por mais de uma palavra elas serão separadas por maiúscula.

Ex: cpf, nomeCliente, descricao;

> Nomes de métodos em minúsculas seguidos por parênteses. Quando o nome do atributo for formado por mais de uma palavra elas serão separadas por maiúscula.

Ex: obter(), salvar(), consulta(), calculaClasse();

> Nomes de tabelas começando em maiúsculas, com o restante em minúsculas. Quando o nome da tabela for formado por mais de uma palavra elas serão separadas por maiúscula.

Ex: Cliente, Venda, DetalheVenda;

> Nomes de campos de tabelas em minúsculas. Quando o nome do campo for formado por mais de uma palavra elas serão separadas por maiúscula.

Ex: cpf, nomeCliente, descricao;

> Nomes de consultas começando em maiúsculas, precedidos pela letra C, com o restante em minúsculas. Quando o nome da consulta for formado por mais de uma palavra elas serão separadas por maiúscula.

Ex: CCliente, CVenda, CDetalheVenda;

> Nomes de formulários começando em maiúsculas, precedidos pela letra F, com o restante em minúsculas. Quando o nome do formulário for formado por mais de uma palavra elas serão separadas por maiúscula.

Ex: FCliente, FVenda, FDetalheVenda;

> Nomes de relatórios começando em maiúsculas, precedidos pela letra R, com o restante em minúsculas. Quando o nome o relatório for formado por mais de uma palavra elas serão separadas por maiúscula.

Ex: RCliente, RVenda, RDetalheVenda;

Obs: No momento da implementação das classes será adicionado o prefixo cls ao nome daquelas que dizem respeito a objetos persistentes e acl ao nome das que são auxiliares. O motivo desta escolha será explicado no artigo sobre o Genesis, a ferramenta case para o Access.

Modelo de Classes

Para criarmos um sistema de vendas necessitaremos dos seguintes itens básicos:

1- Os PRODUTOS que serão vendidos;

2- Os CLIENTES que irão comprar os PRODUTOS;

3- Cada grupo de PRODUTOS vendido a um CLIENTE irá gerar uma VENDA.

Então inicialmente podemos dizer que nosso sistema deverá ser capaz de manipular os objetos Cliente, Produto e Venda. Sendo assim estas serão as classes que deveremos modelar.

Obs: Consideraremos que já foi feito um prévio levantamento de requisitos e que já foram definidos quais atributos e métodos as classes devem ter.

Nas interações entre os objetos poderemos perceber que:

1- Um cliente pode ser cadastrado mesmo que não tenha comprado ainda;

2- Então um cliente cadastrado pode comprar zero ou mais vezes, por isso poderão ser realizadas
    zero ou mais vendas para cada cliente;

3- Cada venda realizada deve ser feita, obrigatoriamente, a um determinado cliente;

4- Cada produto cadastrado pode estar presente ou não em uma ou mais vendas;

5- Cada venda realizada deve conter, obrigatoriamente, um ou mais produtos.

 

A figura abaixo ilustra então o modelo de classes referente à descrição anterior:

Classe Access 2007/2010

Para executar funções genéricas e comuns a várias classes do sistema criaremos ainda mais duas classes, uma para realizar a conexão com banco de dados e persistir ou buscar os objetos e outra para realizar tarefas de validação e transformação de valores, as quais serão utilizadas pela classe Cliente. Estas serão chamadas de ConexaoBD e Utilitario.

Mas antes de definirmos o esquema básico de nossas classes temos que ajustar a relação entre Venda e Produto. Como todos já perceberam esta é uma relação muitos-para-muitos, então as regras de modelagem nos mandam criar uma classe de associação para gerenciar a ligação entre elas. Portanto teremos também a classe DetalheVenda.

Estas serão as outras classes criadas para completar nosso modelo:

Uso de classe no Access 2007/2010

Descrição das Classes

A seguir serão descritas as estruturas básicas de cada uma das classes. Porém neste artigo ainda não serão detalhadas as formas de implementação das funcionalidades de cada método definido no modelo. Apenas a assinatura de cada método será informada, contendo seu objetivo, seus parâmetros de entrada e seu tipo de retorno. Os métodos Let, Get e Set também não serão abordados por enquanto.

Classe Utilitário

Objetivo: oferecer funcionalidades de validação de dados e transformação de valores, necessárias para o correto funcionamento da classe Cliente, ou qualquer outra classe ou função que venha a precisar dela, a qualquer momento. Isto se deve ao fato da classe possuir métodos genéricos e reutilizáveis, podendo ser reaproveitados, sem nenhuma alteração, em qualquer sistema.

Funções:

validaCpf(argCpf As String) As Boolean: recebe como argumento um texto contendo um CPF, sem pontos nem traço, e devolve um valor booleano, verdadeiro ou falso, indicando se o CPF é ou não válido;

validaEmail(argEmail As String) As Boolean: recebe como argumento um texto contendo um e-mail e devolve um valor booleano, verdadeiro ou falso, indicando se o e-mail é ou não válido, sendo que a verificação é feita apenas no seu formato;

nomeProprio(argNome As String) As String: recebe como argumento um texto qualquer e devolve o mesmo texto com as iniciais dos nomes em maiúsculas e o restante em minúsculas, levando em consideração as partículas de ligação de nomes, as quais permanecem em minúsculas;

desacentua(argTexto As String) As String: recebe como argumento um texto qualquer e devolve o mesmo texto sem acentos;

abreviaNome(argNome As String) As String: recebe como argumento um texto qualquer e devolve o mesmo texto com a penúltima parte do nome abreviada, levando em consideração as partículas de ligação de nomes, as quais permanecem inalteradas.

Classe ConexaoBD

Objetivo: oferecer funcionalidades de consulta e atualização do banco de dados. Possui também métodos genéricos que podem ser reaproveitados em qualquer sistema. Uma das maiores vantagens de se utilizar uma classe de conexão é que no caso de mudança do tipo de Sistema Gerenciador de Banco de Dados (SGBD) somente ela deverá ser alterada, permanecendo todas as outras intocadas, desde que seja mantida a interface de comunicação dos métodos. Um exemplo seria a troca do back-end para MySql, Postgres ou Sql Server.

Funções:

executa(codigoSql As String) As Long: recebe como argumento um texto contendo um código SQL de inserção, exclusão ou alteração, executa o código e devolve o número de registros afetados na operação;

consulta(codigoSql As String, Optional editavel As Boolean = False) As Recordset: recebe como argumento um texto contendo um código SQL de consulta de registros e um valor lógico que define o modo de bloqueio de execução, permitindo ou não a edição dos dados durante a operação, e devolve um recordset contendo o conjunto de registros que atenderem aos critérios;

logicoSql(ByVal argValor As Boolean) As String: recebe como parâmetro um valor booleano e devolve um texto contendo os valores True ou False, necessário para códigos SQL;

pontoVirgula(varValor As Variant) As String: recebe como parâmetro um valor decimal em que o padrão de separação da parte inteira e a decimal é a vírgula, e devolve um texto contendo o mesmo valor agora separado por ponto, necessário para códigos SQL;

dataSql(ByVal argData As Date) As String: recebe como parâmetro uma data em qualquer formato e devolve um texto contendo a data no padrão #mm/dd/yyyy#, necessário para códigos SQL;

valorSql(ByVal argValor As Variant) As String: recebe como parâmetro um valor qualquer, verifica o seu formato e devolve um valor no formato padrão dos códigos SQL, fazendo uso das funções anteriores, caso necessário.

Classe Cliente

Objetivo: oferecer funcionalidades de consulta e atualização dos objetos do tipo cliente.

Atributos:

codCliente (Long);
cpf (String);
nomeCliente (String);
email (String);
renda (Currency);
classe (String).

Funções:

existe(argCodCliente As Long) As Boolean: recebe como argumento um código de um cliente, utiliza a classe de conexão para consultar e devolve um valor booleano que indica se o cliente existe ou não no banco de dados;

incluir() As Boolean: persiste o objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso. Este é um método privado, somente sendo acessível pelos métodos internos da classe;

obter(argCodCliente As Long) As Boolean: recebe como argumento um código de um cliente, utiliza a classe de conexão para consultar, atualiza o objeto com os dados e devolve um valor booleano que indica se o cliente foi buscado com sucesso;

salvar() As Boolean: salva objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso. Este método atualiza o objeto atual caso ele já exista ou então o inclui no banco de dados caso seja um novo objeto;

excluir() As Boolean: exclui o objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso;

calculaClasse() As String: calcula a classe social do objeto atual baseado na renda informada e devolve uma letra correspondente à sua classificação dentro das faixas salariais.

Classe Produto

Objetivo: oferecer funcionalidades de consulta e atualização dos objetos do tipo produto.

Atributos:

codProduto (Long);
unidade (String);
descricao (String);
valorUnitario (Currency);
estoqueMinimo (Double);
qtdEstoque (Double).

Funções:

existe(argCodProduto As Long) As Boolean: recebe como argumento um código de um produto, utiliza a classe de conexão para consultar e devolve um valor booleano que indica se o produto existe ou não no banco de dados;

incluir() As Boolean: persiste o objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso. Este é um método privado, somente sendo acessível pelos métodos internos da classe;

obter(argCodProduto As Long) As Boolean: recebe como argumento um código de um produto, utiliza a classe de conexão para consultar, atualiza o objeto com os dados e devolve um valor booleano que indica se o produto foi buscado com sucesso;

salvar() As Boolean: salva objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso. Este método atualiza o objeto atual caso ele já exista ou então o inclui no banco de dados caso seja um novo objeto;

excluir() As Boolean: exclui o objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso;

baixarEstoque(argQtd As Double) As Boolean: atualiza o estoque diminuindo a quantidade informada como parâmetro e devolve um valor booleano que indica o sucesso da operação;

subirEstoque(argQtd As Double) As Boolean: atualiza o estoque acrescentando a quantidade informada como parâmetro e devolve um valor booleano que indica o sucesso da operação;

estoqueBaixo() As Boolean: verifica o estoque atual e compara com o valor de estoque mínimo cadastrado para produto e devolve um valor booleano que indica se o valor atual está abaixo do previsto.

Classe Venda

Objetivo: oferecer funcionalidades de consulta e atualização dos objetos do tipo venda.

Atributos:

codVenda (Long);
codCliente (Long);
dataVenda (Date);

Funções:

existe(argCodVenda As Long) As Boolean: recebe como argumento um código de uma venda, utiliza a classe de conexão para consultar e devolve um valor booleano que indica se o venda existe ou não no banco de dados;

incluir() As Boolean: persiste o objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso. Este é um método privado, somente sendo acessível pelos métodos internos da classe;

obter(argCodVenda As Long) As Boolean: recebe como argumento um código de uma venda, utiliza a classe de conexão para consultar, atualiza o objeto com os dados e devolve um valor booleano que indica se o venda foi buscada com sucesso;

salvar() As Boolean: salva objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso. Este método atualiza o objeto atual caso ele já exista ou então o inclui no banco de dados caso seja um novo objeto;

excluir() As Boolean: exclui o objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso;

getValorTotal() As Currency: Calcula o valor total da venda atual e devolve o valor como resultado.

Classe DetalheVenda

Objetivo: oferecer funcionalidades de consulta e atualização dos objetos de ligação entre a venda e os produtos componentes.

Atributos:

codVenda (Long);
codProduto (Long);
qtdProduto (Double);

Funções:

existe(argCodVenda As Long, argCodProduto As Long) As Boolean: recebe como argumento um código de uma venda e de um produto, utiliza a classe de conexão para consultar e devolve um valor booleano que indica se objeto existe ou não no banco de dados;

incluir() As Boolean: persiste o objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso. Este é um método privado, somente sendo acessível pelos métodos internos da classe;

obter(argCodVenda As Long, argCodProduto As Long) As Boolean: recebe como argumento um código de uma venda e de um produto, utiliza a classe de conexão para consultar, atualiza o objeto com os dados e devolve um valor booleano que indica se o objeto foi buscado com sucesso;

salvar() As Boolean: salva objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso. Este método atualiza o objeto atual caso ele já exista ou então o inclui no banco de dados caso seja um novo objeto;

excluir() As Boolean: exclui o objeto atual no banco de dados, utilizando a classe de conexão, e devolve um valor booleano que indica se a operação ocorreu com sucesso;

getSubTotal() As Currency: Calcula o subtotal do produto vendido para a venda atual e devolve o valor como resultado;

getListaProduto(argCodVenda As Long) As Recordset: recebe como parâmetro um código de uma venda e devolve um conjunto de registros contendo os códigos dos produtos relativos à venda informada.

Diagrama de Alto Nível

Organizando as relações entre todas as classes do sistema chegamos a este modelo de alto nível, ainda sem informações de atributos e métodos, para melhor visualização do contexto do sistema:

Classe no Access 2007/2010

 

Diagrama de Classes Detalhado

Incluindo agora o restante das informações de atributos e métodos chegamos a este diagrama detalhado:

Classe no Access 2007/2010

 

A fim de evitar sobrecarregar o modelo com informações foram omitidos os métodos de acesso aos atributos, os Get / Let / Set, que serão incluídos apenas na implementação das classes, nos próximos artigos. Além disso atributos auxiliares também não foram descritos nesta etapa, mas serão incluídos no momento da implementação das classes.

Modelo de Dados

Para que um objeto seja persistente, ou seja, possa ser recuperado posteriormente, ele deverá ser gravado em algum meio permanente. Neste caso vamos persistir nossos objetos em um gerenciador de banco de dados bastante conhecido de todos: o próprio Access.

Realizando o mapeamento das classes para o formato de banco dados do Access temos então o dicionário de dados, com as informações sobre cada tabela e seus campos, além dos relacionamentos entre elas, necessários para manter a integridade dos dados. Temos também o diagrama de entidade-relacionamento, que é a apresentação gráfica do dicionário. Ressalto que do nosso DER foram suprimidas as informações detalhadas dos campos para evitar sobrecarregar o modelo, já que este também não é o foco do presente trabalho.

Dicionário de Dados

No dicionário de dados de um modelo de dados estão descritas as informações detalhadas sobre as tabelas, seus campos, tipos de dados, tamanho dos campos, chaves primárias e estrangeiras, além das respectivas referências estrangeiras.

Em nosso sistema teremos as seguintes tabelas mapeadas e seus campos:

Cliente

Armazena os dados cadastrais dos clientes.

Campo Descrição Tipo
codCliente PK - Código que identifica o cliente Long(campo chave)
cpf CPF do cliente String(11)
nomeCliente Nome completo do cliente String(50)
email E-mail do cliente String(50)
renda Renda mensal do cliente, em Reais Currency
classe Classe social do cliente, calculada de acordo com arenda String(1)

 

Produto

Armazena as informações sobre os produtos.

Campo Descrição Tipo
codProduto PK - Código que identifica o produto Long(campo chave)
descricao Descrição do produto String(30)
unidade Unidade de comercialização do produto String(5)
valorUnitario Valor unitário do produto, em Reais Currency
estoqueMinimo Quantidade mínima desejada no estoque Double
qtdEstoque Quantidade atual do estoque Double

 

Venda

Armazena informações sobre as vendas realizadas.

Campo Descrição Tipo
codVenda PK - Código que identifica a venda Long(campo chave)
codCliente FK - Código que indica o cliente relativo à venda Long
dataVenda Data de realização da venda Date/Time

 

DetalheVenda

Armazena informação de ligação entre a Venda e os seus Produtos integrantes.

Campo Descrição Tipo
codProduto PK - FK - Código que indica o produto relacionado Long(campo chave)
FK: Produto(codPoduto)
codVenda PK - FK - Código que indica a venda relacionada Long(campo chave)
FK: Venda(codvenda)
qtdProduto Quantidade do produto relacionado Double

 

Obs: PK: Primary Key (chave primária) / FK: Foreign Key (chave estrangeira)

 

Diagrama de Entidade-Relacionamento

Para facilitar a visualização e permitir que o modelo de dados seja melhor compreendido o dicionário de dados é convertido em um desenho que apresenta as tabelas e seus campos de forma gráfica. Desta maneira a percepção das relações fica bem mais simples.

Este é o Diagrama de Entidade-Relacionamento (DER) do nosso sistema de vendas:

Classe no Access 2007/2010

Assim como a modelagem de classes utilizando a UML, a modelagem do diagrama de entidade-relacionamento não será abordado em detalhes neste curso. Então mais uma vez para se aprofundar no assunto procure material especializado em livros ou na Internet, ou aguarde outro artigo em um futuro próximo.

Conclusão

Este artigo teve o objetivo de iniciar realmente a construção do sistema que será objeto de estudo desta série, através da definição de quais serão as partes componentes do projeto.

Apesar de não nos aprofundarmos no assunto foi possível termos uma noção de utilização de padrões de nomenclatura e da modelagem com a UML, conhecendo o diagrama de classes e percebendo a diferença entre os níveis de visualização do sistema pelo detalhamento das informações nos modelos.

Além disso conhecemos um pouco sobre o mapeamento das classes para o modelo relacional, utilizando o dicionário de dados e o diagrama de entidade-relacionamento como ferramentas.

Mesmo não abrangendo todas as etapas do desenvolvimento de um software ficou clara a importância de se planejar bem o que deverá ser construído, através da modelagem e da descrição dos itens, tarefa esta que faz parte da fase de análise do sistema.

Bem, como tudo já está definido a nossa etapa seguinte será colocar a mão na massa, iniciando pela codificação das classes auxiliares, que serão úteis para o funcionamento das restantes.

Encontro você no próximo artigo...


 

 


9 comentários

Torres Forte - PA   09/06/2010 17:55:59

só tem uma coisa a declarar!.

ESTOU LOUCO PRA QUE SAIA OS OUTROS ARTIGOS.... rsrsr

abraços...

meus cumprimentos!

Jessé Ferreira   17/06/2010 18:45:10

É impressionante.
Só quero ver os proximos tutoriais.

Parabens.

Márcio Melo - Rio de Janeiro/RJ   17/06/2010 23:02:19

Trabalhando com access como profissional, esse é o ponto de partida para tudo, planejamento organização, uma equipe competente e que fala a mesma língua. Modelagem e relacionamento, uma visão clara e bem abordada... Cada vez procuramos nos apeifeçoar e aqui estou tendo muitos conteúdos de como temos que estar de mente aberta para buscar e aceitar novos conhecimentos... eu também estarei acompanhando...

Sou mais Brasil!

Anderson Ferreira   17/08/2010 17:01:28

Sou iniciante em access , ja desenvolvir alguns projetos simples no access .Gosto muito do access,
e so tenho a dizer que esse material e otimo ...e um conteudo bem elaborado e de claro entendimento.

Parabens.

Marcelo Muniz de Alencar   21/10/2011 17:49:23

Parábens pelo material. Levando o Access a níveis profissionais: daqui em diante essa é a organização dos meus sistemas em Access. O que complica é o legado que ficou para trás !!!

Messias Gomes   02/08/2012 08:41:44

TENHO UMA TABELA DE PRODUTO, UMA TAB DE GRUPO DE PRODUTO E UMA TAB CLASSE DE PRODUTO..Um produto pertence a um único grupo e a uma unica classe: Produto A pertence o Grupo a e pertence a Classe A1

fernando latino   12/05/2013 17:01:15

Parabéns pelo site, está a me ajudar muito, ñ pare de postar

Gilailson   13/02/2014 23:20:00

Muito bom! Muito bom mesmo! Sou fã do UsandoAccess a mais de 3 anos.
Parei de aprender e a exercitar no access... mas cá estou aprendendo de novo!


Sucesso!

Batista   20/07/2014 21:14:30

Excelente artigo!


Envie seu comentário: