0% acharam este documento útil (0 voto)
55 visualizações131 páginas

Desenvolvimento de Aplicações com Lazarus

O documento aborda o desenvolvimento de aplicações comerciais utilizando Lazarus, focando na criação de um sistema que gerencia pedidos, estoques e relatórios. Ele introduz conceitos de banco de dados, especificamente o Interbase e Firebird, e detalha o processo de criação de tabelas e gerenciamento de dados. Além disso, apresenta duas tecnologias para conexão com bancos de dados: SQLdb e Zeos Access.
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
55 visualizações131 páginas

Desenvolvimento de Aplicações com Lazarus

O documento aborda o desenvolvimento de aplicações comerciais utilizando Lazarus, focando na criação de um sistema que gerencia pedidos, estoques e relatórios. Ele introduz conceitos de banco de dados, especificamente o Interbase e Firebird, e detalha o processo de criação de tabelas e gerenciamento de dados. Além disso, apresenta duas tecnologias para conexão com bancos de dados: SQLdb e Zeos Access.
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

1

LAZARUS

DESENVOLVIMENTO DE APLICAÇÕES COMERCIAIS

1 – INTRODUÇÃO

Diferente da primeira apostila do Lazarus, embora tenha sido trabalhado com progra-
mação orientada a objeto, e que o objetivo da disciplina era familiarizá-lo com o ambiente
Lazarus, trabalhando com eventos, mostrando o que são eventos, propriedades, tratamento de
erros, banco de dados, criando um cadastro, manipulando imagens, etc... O objetivo da segun-
da apostila de Lazarus (Lazarus II) é o Desenvolvimento de Aplicações, criando um aplicativo
comercial que funcione. Então o que orienta essa disciplina?

A maioria das pessoas que estão fazendo o curso serão programadores. Essa disciplina
é a base para o desenvolvimento para montar um Sistema Comercial. O tipo de sistema que
permita fazer pedidos, fazer baixa em estoques, fazer créditos, fazer débitos, gerar relatórios
comerciais, tudo automaticamente pelo computador.

Absolutamente tudo em Sistemas Comerciais, e até mesmo Sistemas não Comerciais


se resumem a essa maneira de trabalhar com mais de uma tabela ao mesmo tempo, você faz a
consulta na base de dados e gera alguma informação.
2

2 – BANCO DE DADOS
2.1– Introdução

Um Banco de Dados consiste em uma forma organizada de armazenamento de infor-


mações, e ainda utiliza muito dos conceitos dos antigos arquivos de aço. Embora não utilizem
meios magnéticos especiais, esses arquivos também contêm fichas, que passaram a ser deno-
minados registros, e em cada registro existem diversos campos. A Informatização trouxe uma
impressionante redução do espaço necessário ao armazenamento dessas informações e maior
rapidez em consultas e pesquisas.

Neste curso será relembrado como criar as tabelas no Interbase6, que serão acessadas
através da aplicação LCL Forms. Será utilizado o Interbase6 como sistema de gerenciamento
pelo fato dele acompanhar o pacote de instalação do Delphi. Em nosso caso o InterBase não
vem incluso ao Lazarus, sendo assim será necessário fazer o download ou adquirir através do
CD incluso na apostila.

2.2– Criando o Banco de Dados

Porque usar o Interbase e não usar outra ferramenta qualquer? O Custo dos Bancos de
Dados como o Axis e o Oracle são muito elevados, e neste caso será utilizado um sistema
gatuito.

Um exemplo de sistema gratuito é o Firebird que é uma cópia do Interbase e pode ser
usado em múltiplas máquinas e não se paga nada por isso, outro sistema é o Interbase que já
vem incorporado no Delphi ou mesmo baixando apenas o aplicativo Interbase.

Se você sabe trabalhar com o Interbase, sabe também trabalhar com o Oracle e outros
bancos de dados. Nesse curso vai ser mostrado como colocar qualquer outro Banco de Dados.

Exemplo de Banco de Dados:

 Paradox
 Axis
 SQL
 Interbase
 Firebird

E ainda existem Banco de Dados melhores:

 Oracle
 DBII
 SQLServer
3

2.3– Criando a Tabela no Banco de Dados

O Interbase tem que estar instalado e rodando no sistema e, para saber se ele está ins-
talado verifique:

Botão Iniciar > Todos os Programas > Interbase > IBConsole.

Clique em IBConsole, será mostrado o formulário abaixo:

Figura 1- Janela inicial do banco de dados Interbase

2.4– Características Básicas do InterBase

O Interbase trabalha com um único arquivo e dentro desse arquivo estão às tabelas a-
cessando um único arquivo pelo DOS. Se for verificado pelo Windows e olhar a pasta dados,
você verá um único arquivo e dentro dele são armazenados os dados criados. É um gerencia-
dor de Banco de Dados da mesma forma que o Oracle e o SQL. Cria uma única área e cons-
trói tudo lá dentro.

Dentro desse arquivo estarão as tabelas e se existir alguma trigger, ou alguma outra
programação, também estará armazenada neste arquivo, assim como os dados, permissões e
restrições vão estar dentro de um único arquivo.

O primeiro passo para trabalhar com o Interbase é criar o arquivo base.

Crie as 4 pastas necessárias (formulários, dados, imagens e relatórios) dentro da


pasta Vendas

 De um duplo clique em cima de InterBase Servers, ou clique no botão Register a


new InterBase Server.
4

Figura 2 - Acessando a tela de Register Server.

Na area Server Information deixe selecionada a opção Local Server e na área Login
Information, nos campos coloque:

UserName: SYSDBA
Password: masterkey

Figura 3 – Janela de login do Interbase

Depois disso clique em OK.

Agora clique no sinal de mais (+) do Local Server ...


5

Figura 4 - Selecionando o caminho Local Server

2.5 – DataBase

O DataBase não é a tabela mas sim o espaço onde tudo será gravado. O espaço onde
será guardada a tabela, o usuário, a programação, os dados. Então tem que criar esse espaço,
que por enquanto não existe ainda, e geralmente esse arquivo contem 500 Kbytes.

2.5.1 - Criando o arquivo

Clique com o botão direito no mouse em cima de DataBases e escolha a opção Create
Database...
6

Figura 5 – Selecionando o registro do Database

Aparecerá a seguinte Janela:

Figura 6 - Configurando o nome e caminho do banco

2.6 - O Alias

É o que vai aparecer no IBConsole quando clicar no DataBase. Vai aparecer vários
bancos porque o InterBase não precisa estar restrito a um único Banco de Dados, mas pode
gerenciar vários bancos. Poderia mais tarde colocar uma CPU em outro local com o Banco de
Dados de sistema de Vendas, outro banco com sistema de Impostos, um outro com sistema
7

de contabilidade fiscal, isto é, vários bancos de dados instalados numa única máquina em ou-
tro local e acessar remotamente.
O nome que ira colocar no banco de dados é o mesmo que vai aparecer no arquivo.
Tem que ser um nome Único, não pode existir dois arquivos com o mesmo Alias, não é um
arquivo físico, mas sim um nome lógico, é o nome que vai aparecer na Listagem.

2.7 - Criando o Espaço Físico

O espaço Físico tem que indicar o local que será criado o Banco de Dados. Tem que
ser digitado o nome do Arquivo no campo FileName(s) na caixa de diálogos

2.7.1 – Adicionando o caminho da pasta

No campo FileName(s), no primeiro quadrado coloque o caminho para onde vai ser
salvo e o nome do banco com sua extensão, por exemplo: C:\Vendas\Dados\Vendas.gdb.

O nome para o banco no exemplo é \Vendas.gdb ou colocar qualquer outro nome, co-
mo por exemplo BASEDADOS. Ficando da seguinte maneira:

Figura 7 – Adicionando a extensão do arquivo


8

GDB (Gerenciador de Banco de Dados) é a extensão padrão


para um bando de dados do Interbase.

A extensão pode ser retirada, então ficará um arquivo sem


extensão, mas convencionou-se a extensão gdb.

Se o Campo PageSize não for preenchido, o sistema coloca o mínimo automaticamen-


te. Também é verificada a maneira que vai ser manipulado os dados, observando se o SQL-
Dialect é igual a 3 .

No Campo Alias digite Vendas:

Figura 8 – Especificando a extensão, a manipulação de dados e o Alias de um Banco


9

Depois de tudo preenchido basta clicar do botão OK.

Foi criado o Banco Vendas e também uma pasta chamada Table onde foram criadas as
tabelas.

Figura 9 – Visualizando a estrutura do DataBase.

O sistema criou um arquivo de 578 Kbytes para reservar espaço.

Exemplo: Uma pessoa comprou um servidor com 10 Gbytes de HD para instalar o


Lazarus, o Sistema Operacional e um Sistema de Banco de Dados. Com isso sobrou 8Gbytes.
Com um banco de dados Paradox e não o InterBase essa pessoa começa a cadastrar os dados
de seus clientes em uma loja. Foi cadastrado 5 clientes e foi consumida no máximo 10 kBytes
da tabela. Depois de um mês, foi para 100 K até 500 k. O usuário verifica no HD que ainda
tem muito espaço, faz uma cópia de um DVD e depois de um tempo ele esquece que copiou o
filme para o servidor. Apartir de algumas semanas e com a entrada de mais cadastros o HD
vai encher e no meio desse cadastramento vai dar erro, porque não existe mais espaço sufici-
ente. Como não foi reservado espaço para o banco de dados, outros arquivos ocuparam esse
espaço.

2.8 - Porque o Interbase é mais rápido que o Paradox

2.8.1 - O InterBase diferente do Paradox reserva um espaço.

Fisicamente o HD é como se fosse um CD com uma cabeça de leitura que faz o traba-
lho de busca, chamado de tempo de acesso, quanto menor esse tempo melhor o desempenho
do micro.

A parte mais lenta do HD é a sua velocidade de transferência de dados (tempo de bus-


ca). O tempo de deslocamento que a cabeça de leitura gasta para chegar até os dados no HD é
limitada devido aos limites impostos ao motor de passe. Quanto mais vezes são realizadas as
buscas num HD, mais lento é o sistema. Então o ideal é desfragmentar o HD para organizar os
arquivos.
10

No caso de uma Table no Paradox, como não há reserva de espaço, os arquivos são
praticamente colocados em diversos pontos do HD. Na desfragmentação, os arquivos do
mesmo tipo são juntados. Tudo que era por exemplo Clientes, é colocado um próximo do ou-
tro. Os arquivos do Word podem ser colocados próximos, mas em um outro campo do HD. O
sistema não sabe que os tipos de arquivos fazem parte do arquivo de um Banco de Dados.
Um arquivo cliente pode estar no começo do HD e o arquivo fornecedor pode estar no final.
Quando o sistema precisar fazer uma consulta em SQL, primeiramente faz uma leitura, depois
faz a busca, vai para outro ponto no HD, para continuar. Mesmo fazendo a desfragmentação,
ele junta tudo que era cliente num campo e tudo que era fornecedor em outro lugar, mas não
juntou a pasta dados num único espaço.

Um único arquivo. De começo já é reservado um espaço físico no HD. Quando em


uma tabela for cadastrado clientes, ocupa um espaço, depois cadastra fornecedores, ocupa
outro espaço. Ao realizar uma busca, o sistema não vai procurar no final do HD ou em partes
diferentes, mas os dados estarão todos num mesmo espaço reservado. O desempenho do sis-
tema vai ser mais rápido. O Oracle e o SQL, são exemplos de Bancos de Dados que trabalham
com espaço reservado. Com isso, a vantagem de ter um único arquivo é o desempenho.

2.9 - Criando as Tabelas com o Interbase 6

Com as configurações prontas, basta clicar no botão SQL no menu rápido ou atraves
do menu TOOL > INTERACTIVE SQL.

Figura 10 – Editor de SQL

Os nomes são CaseSensitive, portanto é necessário


padroniza-los senão vai dar erros.

Importante: Not Null – Todos os campos que forem


do tipo chave tem o Not Null, não importando o tipo. É in-
formado ao Interbase que não pode aceitar espaço, não pode
dois clientes ter o código espaço. Tem que ser preenchido os
códigos como código 1, código 2 e assim por diante.
11

Na tela do editor de SQL digite assim:

Create table tb_clientes (


cod_cli number(10,0) not null primary key,
nome_cli varchar(40),
ender_cli varchar(50),
cidade_cli varchar(40),
uf_cli char(2)

);

Quando terminar de digitar clique no botão Execute Query(CRTL + E):

Figura 11 – Criando a tabela de clientes no Interbase

Se o código sumir, significa que a programação esta certa, caso contrário aparecerá
uma mensagem de que não pode ser executado, e na onde esta o erro, corrija e execute nova-
mente.

Para que possa ser salvo esse código digite COMMIT e de


pois execute.

Feche o editor de SQL e note que dentro da Table foi criada


a Tabela “tb_cliente SYSDBA”
12

Na estrutura do DataBase, de um duplo clique na tabela de clientes, para que possa ver
os campos criados na tabela:

Figura 12 – Tb_clientes

Ao fazer isso, o Interbase retorna uma janela na qual disponibiliza ao usuário escolher
uma das tabelas salva no banco, e navegar nas abas de Properties, Metadata, Permissions,
Data, Dependencies.

Properties: São os campos de cada Tabela.

Figura 13 - Tela Properties


13

Metadata: É o SQL usado para criar a Tabela.

Figura 14 - Tela Metadata

Permissions: São permissões para usuários, o que cada um pode fazer.

Figura 15 - Tela Permissions


14

Data: Para fazer inserção de dados utilizando o próprio Interbase.

Figura 16 - Tela Data

Para efetuar o cadastro por exemplo da tabela de clientes, é necessário preencher os


campos da tabela, e assim, ao terminar de cadastrar o primeiro cliente, clique no sinal de +
(insert record), para adicionar uma nova linha de cadastro, quando terminar de inserir todos
os cadastros clique no botão Post Edit para salvar e logo em seguida clique no botão Commit
& Refresh para salvar os dados incluídos na tabela no arquivo físico.

Figura 17 - Tela com todos os usuários cadastrados


15

Crie uma tabela para produtos com os seguintes campos:

Create table tb_produtos (


cod_prod number(10,0) not null primary key,
desc_prod varchar(40),
qtd_prod, qtd_min numeric(10,0),
valor_prod numeric(10,0),
estoque_prod integer
);

Qtde – se uma empresa trabalha com vendas por


gramas, teoricamente deveria ter casas depois da vírgula, se
fosse açougue, então permitiria casas depois da vírgula, no
caso de uma loja de roupas, ninguém vende uma camiseta e
meia, não tem fração, então o número vai ser zero(0), sem
casas decimais.

A quantidade mínima de estoque tem que ser do


mesmo tipo da quantidade de estoque.

Resumo: Foi criado um DataBase, que é um espaço no disco, um registro. Inserido


neste espaço estão as tabelas, procedimentos, trigger, regras, contas de usuários, isso tudo em
um único espaço físico criado com extensão .gdb, podendo ser colocado qualquer outra
extensão, mas geralmente utiliza a extensão .gdb para identificar que essa é do Interbase.

A vantagem de se utilizar um único arquivo é o desempenho. Quando o arquivo está


em seqüência, não é necessário fazer um CIC, uma busca será pequena. Foi criado um único
arquivo para desempenho e segurança.

Também foi criado uma tabela simples de clientes com os campos código, nome
cidade e UF, sendo colocado poucos dados porque a idéia e que você faça depois de acordo
com o projeto escolhido para testes.
16

3 – CONEXÃO SQLDB OU ZEOS?

Será apresentada duas tecnologias para a conexão com o banco. A paleta SQLdb e a
paleta Zeos Access

3.1 - Paleta SQLdb

Figura 18 – paleta SQLdb

Essa paleta é responsável para acessar bancos de dados no Lazarus. Com essa paleta
pode-se conectar ao PostgreSQL, Oracle, MySQL, Firebird ou Interbase, SQLite e ODBC.
Para cada um desses existe um componente TXXXConnection. Para conectar ao Interbase, por
exemplo, existe o componente TIBConnection. Para executar as operações sobre tabelas existe
o componente TSQLQuery e o TSQLTransaction.

Componentes mais conhecidos que formam a paleta SQLdb

TSQLQuery Usada para executar comandos SQL no servidor. Os dados podem ser
obtidos atribuindo-se à propriedade SQL algum comando SELECT e
chamando o método Open. Também é possível manipular os dados
executando-se comandos INSERT, DELETE ou UPDATE. No último
caso, não deve ser usado o método Open, mas sim o método
ExecSQL.
TSQLTransaction A SQLTransaction é necessária por motivos internos de
gerenciamento (corresponde ao conceito de transação em banco de
dados). A SQLTransaction é automaticamente ativada quando um
banco de dados é aberto através dela. Para fechar a SQLConnection,
no entanto, certifique-se de que a SQLTransaction não está ativa.
TXXXConnection Responsável pela conexão entre o Projeto e o arquivo físico que esta
no HD. É usada para armazenar parâmetros de conexão ao servidor de
banco de dados. Os componentes são:
 TIBConnection (Conectar ao Interbase e Firebird)
 TODBCConnection (Conectar ao bando MsAcess)
 TOracleConnection (Conectar ao banco Oracle)
 TMySQL50Connection(Conectar ao banco MySql)

3.2 - Paleta Zeos

Figura 19 – paleta Zeos Access


17

Componentes mas conhecidos que formam a paleta Zeos.

TZConnection É o componente que estabelece a conexão com o banco de


dados e possui a capacidade de manipular ou controlar transações.
Todo acesso ao banco é sempre feito sob a execução de uma transa-
ção. Ou seja, qualquer que seja a conexão estabelecida, o acesso ao
banco de dados é automaticamente realizado dentro de um contexto
de uma transação. O então chamado modo “AutoCommit” está sem-
pre ativo, setado como “True”. Como o modo AutoCommit está
sempre ativo então toda alteração efetuada por um comando SQL
será confirmada no banco de dados pelo COMMIT, em caso de su-
cesso. Se este comportamento for desabilitado, uma transação deve
ser iniciada explicitamente, através do método StartTransaction. Den-
tro desta transação explícita é possível executar um conjunto de co-
mandos SQL que efetuem, em seqüência, modificações no banco de
dados. Este grupo de comandos podem ser confirmados por um
COMMIT. Se uma transação explícita é ativada o modo AutoCom-
mit é sempre passado para o estado desativado (“False”). A chamada
ao método Commit faz com que todas as modificações efetuadas
dentro deste contexto explícito de transação sejam confirmadas. Ao
contrário, a chamada ao método Rollback libera (cancela) estas mo-
dificações. Em ambos os casos o modo AutoCommit será setado para
True, quando o método chamado (Commit ou Rollback) for concluí-
do e a transação explícita ser então finalizada.

tiRepeatableRead Corresponde ao TIL "SNAPSHOT” que é o padrão de servidores


Firebird. É uma combinação dos parâmetros de transação “concur-
rency” e “nowait”. Um “snapshot” (instantâneo) do banco de dados é
feito. Usuários sofrerão influência se duas transações trabalharem
simultaneamente sobre um mesmo registro. Se conflitos surgem
quando dados estão sendo acessados, uma mensagem de erro é retor-
nada. Atualizações dentro de outras transações não serão nofificadas.
Este TIL atende amplamente aos requisitos do SQL padrão (SERIA-
LIZABLE).
tiReadCommitted Corresponde ao TIL “READ COMMITTED”. É uma combinação
dos parâmetros de transação “read_committed”, “rec_version” e
“nowait”. Este TIL reconhece todas as atualizações efetuadas por
outra transação e confirmadas através do COMMIT. O parâmetro
“rec_version” é responsável pelo comportamento de que os valores
mais atuais que foram “commitados” por outros usuários serão con-
siderados. O parâmetro “nowait” é responsável pelo comportamento
de que não há espera pela liberação de um registro bloqueado. Neste
nível o servidor é mais sobrecarregado que no TIL tiRepeatableRead,
porque tem que fazer todos os “refreshs” para adquirir estes valores
novamente e iterativamente.
tiSerializable Corresponde ao TIL “SNAPSHOT TABLE STABILITY”. É usado
para obter um acesso exclusivo ao conjunto de dados retornado. Rea-
lizado pelo parâmetro de transação “consistency” que previne que
uma outra transação possa ter acesso aos dados gravados. Só a tran-
18

sação que está editando os dados pode ter acesso aos mesmos. Isto
também previne, num ambiente multi-usuário, que outro usuário te-
nha acesso aos dados que estão sendo editados. Como este TIL é
muito restritivo no que se refere ao acesso dr dados que estão sendo
editados, deve ser aplicado comcautela.
tiNone Nenhum TIL é usado para isolar a transação
tiReadUncommitted O TIL tiReadUncommitted não é suportado pelo Firebird. Se este
TIL for usado, um erro será disparado e a transação não será isolada
(de uso semelhante ao TIL tiNone).
TZQuery É recomendado o uso do TZQuery no modo RequestLive associado
com o componente TZUpdateSQL. Se um conjunto de dados for atua-
lizado, então RequestLive deve ser setado como True e usado com o
componente TZUpdateSQL, a fim de se usar os comandos SQL de
ação (update, insert, delete). Para retornar um conjunto de dados de-
ve-se chamar o método Open. Caso queira executar uma Query de
ação (que não retorna um recordset) chame o método ExecSQL, para
os comandos update, delete, insert.
TZTable O componente TZTable deve ser utilizado apenas em aplicações cli-
ente-servidor que manipulam pequenas tabelas, uma vez que todos
os registros da tabela serão transferidos para a memória da máquina
cliente. É equivalente ao comando SQL “SELECT * FROM
TB_CLIENTES”.
TZStoredProc O componente TZStoredProc fornece a possibilidade de executar um
procedimento armazenado (stored procedure) de um banco de dados.
Existem dois tipos de procedimentos armazenados. O que retorna um
conjunto de dados e o outro que não retorna. Não é necessário cha-
mar o método Prepare antes de executar o método ExecProc.
TZReadOnlyQuery Este componente é similar ao TZQuery, porém com a diferença de
que recordset retornado é somente leitura. Conseqüentemente não é
possível o uso associado do TZUpdateSQL.
TZUpdateSQL O TZUpdateSQL fornece comandos SQL de atualização (update,
insert, delete) para um conjunto de dados, recuperados por um TZ-
Query.

Exemplo de uso do TZUpdateSQL:

ZQuery1.Sql:

SELECT * FROM Tb_clientes

UpdateSQL1.InsertSql:

INSERT INTO Tb_clientes (cod_cli, nome_cli)


VALUES (1,‟Cleiton‟)
19

UpdateSQL1.ModifySql:

UPDATE Tb_clientes
SET nome_cli = :nome_cli
WHERE cod_cli = :cod_cli

UpdateSQL1.DeleteSql:

DELETE FROM Tb_clientes WHERE cod_cli = :cod_cli

O componente de TZConnection provê quatro tipos predefinidos


de Níveis de Isolamento de Transação (TIL):

É aconselhável isolar transações com o nível de iso-


lamento de transação tiRepeatableRead (o padrão de Fire-
bird). Este TIL atende amplamente aos requisitos do SQL
padrão (SERIALIZABLE). Previne todos os problemas rela-
tivos a consistência que pode surgir usando transações. Uma
segunda escolha seria o tiReadCommitted, mas isto depende
da aplicação e da necessidade se o conjunto de dados sempre
tem que ser o mais atual. OBS.: Um TIL poder personaliza-
do em tempo de execução.
20

Algumas propriedades dos componentes TZConnection:

Protocol (Protocolo) Esta propriedade define qual o banco de dados a ser acessado.

Read-Only Connection A conexão com o banco de dados mantida pelo TZConnection é


setada, por padrão, como somente leitura (ReadOnly = True).
Isto significa que a gravação de dados não é permitida. Para
poder gravar dados, você deve setar esta propriedade para False
(ReadOnly = False).
HostName Normalmente o nome do servidor ou o endereço IP é atribuído a
esta propriedade. Se o banco se encontrar na máquina local atri-
bua-lhe o valor “localhost”.
Connected Esta propriedade ao ser setada como True, estabelece a conexão
com o banco de dados, se tudo ocorrer bem. Evite ativar esta
propriedade em tempo de projeto, principalmente antes de com-
pilação.

Nem todos os componentes serão utilizados.


21

4 – INICIANDO A CONEXÃO

Na apostila de Lazarus 1 (Linguagem de Programação Visual) foi utilizado a conexão


com a paleta SQLdb, nessa apostila será utilizado a paleta Zeos Access para conexão.

4.1 – Instalando o componente ZEOS

Para poder trabalhar com os componentes da paleta ZEOS é necessário instalar o


mesmo, pois essa paleta não é nativa do Lazarus.

Baixe o zeos no sourceforge ou no link abaixo:

http://www.jpsoft.com.br/downloads/ZEOSDBO-6.6.5-stable.zip

Primeiramente copie a pasta ZEOSDBO-6.6.5-stable para o diretório


C:\lazarus\components, logo em seguida abra o Lazarus e no menu File clique em Close all
editors Files (caso pergunte se quer salvar, clique no botão NO), logo em seguida entre no
menu Package e clique em Open package file (.lpk) como mostra a imagem abaixo:

Figura 20 – Abrindo pacotes de arquivos

Procure pelo arquivo zcomponent.lpk, que se encontra dentro da pasta:


C:\lazarus\componenets\ZEOSDBO-6.6.5-stable\packages\lazarus\zcomponent.lpk

Os pacotes de componentes para o Lazarus tem a extenção


lpk. Assim, quando baixar um pacote da web, basta
localizar o lpk para instalar.
22

Ira surgir a tela de instalação de componente do Lazarus :

Figura 21 - Tela de Compilação e Instalação

Clique no botão Compilar e aguarde até que a compilação seja feita, logo em seguida
clique no botão Instalar, ira aparecer à seguinte mensagem:

Figura 22 - Pacotes que serão instalados

Basta clicar em OK.

Na tela seguinte clique no botão YES, e aguarde a compilação do Lazarus, ou seja, o


Lazarus vai fechar e abrir automaticamente com a nova paleta do ZeosAccess instalada.
23

Figura 23 - Confirmação de instalação

Todos os componentes podem ser encontrados dentro do CD


que acompanha essa apostila

.
24

5 – INICIANDO UMA APLICAÇÃO – VENDAS 1

É criada uma pasta raiz em um local adequado com o nome de Vendas e dentro desta
pasta crie quatro pastas com os nomes: formularios, imagens, relatorios, dados.

Abra o Lazarus crie um novo PROJETO(caso não esteja ) e salve a unit dentro da pas-
ta formulários com o nome u_principal, e o projeto com o nome de p_vendas dentro da pasta
raiz (pasta Vendas).

O formulário deverá conter as seguintes propriedades:

Name Caption
Frm_principal Vendas

Não se esqueça de especificar o caminho de onde as units


estão salvas através do menu Project/Compiler Option..., caso
contrario na execução o projeto não encontrará as units.

5.1 – Adicionando o componente de conexão

Adicione o componente TZConnection que esta dentro da paleta Zeos Access no for-
mulário principal e mude suas propriedades para:

Name DataBase HostName Password User Protocol Connected


Z_conexao Procure pelo localhost masterkey sysdba Interbase-6 true
Banco de dados
Vendas.gdb que
está dentro da
pasta DADOS

Adicione Menus e SubMenus com os seguintes nomes:

Arquivo Movimentações Cadastros


Sair Pedidos Funcionários
Clientes
Produtos
25

A conexão foi criada, falta agora criar outro formulário para adicionar o componente
ZTable

5.2 – Adicionando o componente TZTABLE

Crie um novo formulário e mude as suas propriedades para:

Name Caption
Frm_cadcli Cadastro de Clien-
tes

Salve esse projeto na pasta formulários com o nome de u_cadcli.

Volte para formulário principal (frm_principal) e entre no modulo de programação.


Logo a baixo da linha de programação Implemation coloque as units que ira chamar. Neste
caso u_cadcli.

implemation
uses u_cadcli;

Volte para o formulário cadastro de clientes (frm_cadcli) e adicione o componente


TZTable que se encontra dentro da paleta Zeos Access, com as propriedades:

Name TableName Connection Active


Tb_cli Tb_clientes Frm_principal.z_conexao True

Adicione também o componente DataSource com as seguinte propriedades:

Name DataSet
DS_Cli Tbl_cadcli

Adicione também Label e DBEdits para cada campo da tabela(cod_cli, nome_cli, en-
der_cli, cidade_cli, UF_cli) e mude as propriedades do componente DBEdit para:

DataSourse DataField
DS_Cli <Nome do campo>

Adicione uma DBNavigator que se encontra na aba DataControls com a seguinte


propriedade:

DataSourse
DS_Cli

No evento OnActivate do formulário de clientes(frm_cadcli) entre em seu modulo de


programação e adicione a seguinte linha:

Tbl_cadcli.open;
26

Novamente volte para o formulário principal clique no menu CADASTRO e logo em


seguida clique no submenu CLIENTES para entrar em seu modulo de programação. Digite a
seguinte linha:

Frm_cadprod.showmodal;

Deixe a propriedade ACTIVE da tabela (tbl_cadcli) True a-


penas na criação do projeto, quando for executar passe para
False, pois se isso não for feito acontecera um erro de banco.

Salve e teste sua aplicação.

Figura 24 - Tela de cadastro de clientes


27

5.3 – Adicionando o componente TZQuery

Esse componente trabalha igual ao componente SQLQuery da paleta SQLdb.

Crie um novo formulário com as seguintes propriedades:

Name Caption
Frm_cadprod Cadastro de Produtos

Salve esse projeto na pasta formulários com o nome de u_cadprod.

Volte para formulário principal (frm_principal) e entre no modulo de programação.


Logo a baixo da linha de programação Implemation coloque a outra unit que será utilizada.
Neste caso u_cadcli, u_cadprod.

implemation
uses u_cadcli, u_cadprod;

Volte para o formulário de produtos (frm_cadprod) e adicione o componente TZ-


Query que se encontra dentro da paleta Zeos Access e mude suas propriedades:

Name DataBase SQL Active


tbl_cadprod Frm_principal.z_conexao clique nos três pontinhos, aparecera True
o editor de SQL, digite: select *
from Tb_produtos (Tb_produtos é
o nome da tabela que criamos)

Adicione também o componente DataSource com as seguinte propriedades:

Name DataSet
DS_Prod Tbl_cadprod

Adicione também Label e DBEdits para cada campo da tabela(cod_prod, desc_prod,


qtd_prod, valor_prod, estoque_prod) e mude as propriedades do componente DBEdit para:

DataSourse DataField
DS_Prod <Nome do campo>

Adicione uma DBNavigator que se encontra na aba DataControls com a seguinte


propriedade:

DataSourse
DS_Prod

No evento OnActivate do formulário de produtos(frm_cadprod) entre em seu modulo


de programação e adicione a seguinte linha:
28

Tbl_cadprod.open;

Novamente volte para o formulário principal clique no menu CADASTRO e logo em


seguida clique no submenu PRODUTOS para entrar em seu modulo de programação. Digite
a seguinte linha:

Frm_cadprod.showmodal;

A propriedade ACTIVATE do componente tbl_cadprod de-


ve estar TRUE somente na criação do projeto, quando for
testar o projeto o mesmo devera ser passado para FALSE
evitando assim erro de banco de dados

Salve e teste sua aplicação

Figura 25 - Tela de cadastro de produtos


29

6 – Canais

6.1 –Primeiro Canal

Programar todos os botões na unha usando comandos na programação SQL. Para cada
um dos botões teria que ser programado o SQL.

6.2 - Outra Solução

TZUpdateSQL fornece comandos SQL de atualização (update, insert, delete) para


um conjunto de dados, recuperados por um TZQuery.

Na paleta Zeos Access adicione o componente TZUpdateSQL no formulário de pro-


dutos(frm_cadprod) e mude a propriedade name para:

Name
Up_prod

Selecione o componente tbl_cadprod e mude a propriedade para:

UpdateObject
Up_prod

UpdateObject: Quando for preciso fazer uma atualização, incluir um novo elemento
ou salvar, o UPDateObject vai gerar o SQL automaticamente.

Abra o editor de SQL do componente TZUpdateSQL(up_prod) dando um duplo cli-


que sobre o mesmo.

Figura 26 – UPDateSQL - Options


30

Clicando na aba SQL, é verificado os tipos de SQL (Modify, Insert e Delet) se estão
todos em branco, como mostra um dos tipos abaixo, então como fazer para programá-los?

Figura 27 – UPDateSQL - SQL

Clique na aba Options e logo em seguida na área KEY FIELD selecione o campo
COD_PROD e na área UPDATE FIELD selecione todos os campos e clique no botão Gene-
rate SQL.

Figura 28 – UPDateSQL – Generate SQL

O código SQL do modify, Insert e Delet serão preenchidos automaticamente no banco


de dados, como mostra figura abaixo:
31

Figura 29 – UPDateSQL – SQL inseridos

Execute o programa e chame a tela. Observe que o botão insert (+) está ativo, então o
sistema poderá inserir e salvar quando executado essa função.

Figura 30 – UPDateSQL Tela de cadastro de produtos


32

7 - INICIANDO UMA NOVA APLICAÇÃO – VENDAS 2

É criada uma pasta raiz em um local adequado com o nome de Vendas2 e dentro desta
pasta crie quatro pastas com os nomes: formularios, imagens, relatorios, dados.

Abra o Lazarus crie um novo PROJETO(caso não esteja ) e salve a unit dentro da pas-
ta formulários com o nome u_principal, e o projeto com o nome de p_vendas dentro da pasta
raiz (pasta Vendas2).

O formulário principal devera conter as seguintes propriedades:

Name Caption
Frm_principal Vendas 2.0

Não se esqueça de especificar o caminho de onde as units es-


tão salvas através do menu Project/Compiler Option..., caso
contraio na execução o projeto não encontrará as units.

Adicione o componente TZConnection que esta dentro da paleta Zeos Access no for-
mulário principal e mude suas propriedades para:

Name DataBase HostName Password User Protocol Connected


Z_conexao Procure pelo localhost masterkey sysdba Interbase-6 true
Banco de dados
Vendas.gdb que
entra dentro da
pasta DADOS
33

Para poupar tempo será utilizado o arquivo de banco de da-


dos do projeto anterior. Copie-o para dentro do diretório
Vendas2/Dados.

Adicione Menus e SubMenus com os seguintes nomes:

Arquivo Movimentações Cadastros


Sair Pedidos Funcionários
Clientes
Produtos

7.1 – Formulário Cadastro de Clientes

Crie um novo formulário com as seguintes propriedades:

Name Caption
Frm_cadcli Cadastro de Clien-
tes

Salve esse projeto na pasta formulários com o nome de u_cadcli.

Volte para formulário principal (frm_principal) e entre no modulo de programação.


Logo a baixo da Linha de programação Implemation coloque as units que ira chamar. Neste
caso u_cadcli.

implemation
uses u_cadcli, u_cadprod;

Volte para o formulário de clientes (frm_cadcli) e adicione o componente TZQuery


que se encontra dentro da paleta Zeos Access e mude suas propriedades:

Name DataBase SQL Active


tbl_cadcli Frm_principal.z_conexao clique nos três pontinhos, aparecera o True
editor de SQL, digite: select * from
Tb_clientes (Tb_clientess é o nome
da tabela que foi criada)
34

Adicione também o componente DataSource que esta na aba Data Access com as se-
guinte propriedades:

Name DataSet
DS_Cli Tbl_cadcli

Adicione também Label e DBEdits para cada campo da tabela(cod_cli, no-


me_cli,ender_cli, cidade_cli, uf_cli) e mude as propriedades do componente DBEdit para:

DataSourse DataField
DS_Cli <Nome do campo>

Adicione uma DBNavigator que se encontra na aba DataControls com a seguinte


propriedade:

DataSourse
DS_Cli

No evento OnActivate do formulário de clientes(frm_cadcli) entre em seu modulo de


programação e adicione a seguinte linha:

Tbl_cadcli.open;

Novamente volte para o formulário principal clique no menu CADASTRO e logo em


seguida clique no submenu CLIENTES para entrar em seu modulo de programação. Digite a
seguinte linha:

Frm_cadcli.showmodal;

A propriedade ACTIVATE do componente tbl_cadprod de-


ve estar TRUE somente na criação do projeto, quando for
executar o projeto, essa propriedade devera ser passado pa-
ra FALSE evitando assim erro de banco de dados

Salve e teste o programa.


35

Figura 31 – Programa em execução

Cadastre alguns dados para testar o sistema.

Onde estão os dados após você cadastrar e salvar? O sistema


não salvou, porque?

Entre o formulário e o Banco de Dados, quando se utiliza o TZQuery, ele cria uma
cópia do banco e guarda no Cash. Quando está digitando os dados, na verdade, não esta
guardando no banco de dados, mas sim guardando no Cash. Quando clicar em Post, os dados
digitados são salvos no Cash. Isso é executado para diminuir o trafego de dados na rede.

Se fosse uma rotina muito grande dentro do banco de dados, poderia ficar
manipulando os dados. Quando a resposta estiver pronta, pode guardá-la no servidor, porque
por enquanto não foi feita a transação. Na hora que começa a fazer a leitura, inicia a
transação, mas não finaliza. Se você fechar do jeito que está à transação não tendo sido
confirmada, volta tudo como estava antes, então perdeu tudo.

Como fazer para confirmar a transação?


36

Quando após um Post der o seguinte comando: <Nome da Tabela>.After


ApplyUPDate.

AfterApplyUPDate: Salva os dados (commit) na sua transação, ou seja, se antes de


dar um Post tiver uma programação do evento AfterApplyUPDate, o sistema salva os dados.

Qualquer alteração, qualquer edição ou outro evento, não salvos automaticamente, só


serão confirmados após o ApplyUPDate, é a hora que os dados do Cash são salvos
(atualizados) no banco de dados.

Figura 32 – AfterApplyUPDate

7.2 - Programação para salvar dados do Cash no Banco de Dados.

Entre no formulário Cadastro de Clientes(frm_cadcli) e selecione o componente


TZQuery(tbl_cadcli). Mude a propriedade

CachedUpdates
TRUE

Agora acesse o guia Events e de um duplo clique no evento AfterPost para abrir o seu
modulo de programação.

procedure Tfrm_cadcli.tbl_cadcliAfterPost(DataSet: TDataSet);


begin
tbl_cadcli.ApplyUpdates;
end;.
37

Para trabalhar com essa transação coloque um comando Try , após comandar o
ApplyUpdates, se tudo der certo, salva. Se der Exeption, coloque uma mensagem para o
usuário.

Qualquer erro que retornar sem o tratamento, pode travar a


programação.

Após colocar todos os comandos anteriores, execute o programa e teste novamente


cadastrando dados no banco e salve para testar. Na hora que for executado o comando para
salvar, o sistema envia o SQL para o Banco de Dados automaticamente. Quando o programa
for fechado e reaberto os dados permaneceram.

Figura 33 – Programa em execução AfterPost

Diferentemente da execução anterior, agora quando clicar um Post, salva e envia o


que esta no Cash para o Banco de Dados.

Essa programação no evento AfterPost é importante, porque se estiver trabalhando


com uma grande base de dados e após muito tempo de digitação acontece algum problema no
38

sistema ou no próprio computador antes de efetuar o UPData, acaba perdendo tudo, porque
não foi feito o evento After Post o comando ApplyUpData.

Se existem duas máquinas, cada uma com seu Cash, se nessas duas máquinas forem
ao mesmo tempo cadastrados dois clientes com o mesmo número. O primeiro que salvar com
o AfterPost, conseguirá êxito, o segundo dará erro, porque já existe o código, então terá que
efetuar o tratamento com o comando Try...Exeption, para dizer que já existe o código.

O que pode ser feito para evitar esse tipo de coisa?

Pode efetuar um comando generation no banco de dados. Se for tentar gravar um


código que já existe no banco de dados, o sistema verifica que já existe, então coloca outro
código e grava, retornando o resultado.

Se for feito um tratamento pelo Lazarus, não tem como o sistema saber quantas
máquinas acessa o bando de dados. O Ideal é fazer o tratamento no local que for salvar. Cada
vez que for salvar, gera uma chave. Essa programação (generation) é feita no banco de
dados.

Neste ponto já está funcionando o cadastro de clientes.


39

8 – LIGAÇÕES ENTRE AS TABELAS

Independente da tecnologia usada, SQLdb ou ZeosAccess, ambas permitem a mesma


coisa, é o mesmo componente, a mesma propriedade.

Trabalhando com tabelas do tipo mostrado abaixo, ligada uma com a outra, delas
nascendo um relacionamento N para N – uma tabela intermediaria. Por exemplo: um cliente
pode fazer N pedidos. Um pedido pode ter vários produtos e um produto pode pertencer a
vários pedidos. Nesta tabela N para N nasce uma intermediaria “ITENS”.

1 N N N
CLIENTE PEDIDO TEM PRODUTO

1 N 1 N N 1
CLIENTE PEDIDO ITENS PRODUTO

8.1 – Tipos de ligações.

Existem dois tipos de ligações: O DBLooKupCombobox e outra chamada


MasterSource/MasterField.

8.1.1 – DbLookupComboBox

Ligação do tipo consulta. São exemplos os componentes do tipo combo, onde tem
várias opções para escolher, mas não pode cadastrar.

DBLooKupCombobox: é usada quando a tabela relacionada não permitir inclusão,


somente a consulta. Ex: Se tiver fazendo um pedido, não é possível incluir um novo cliente,
mas selecionar um cliente já cadastrado em tabela especifica.

O produto é a mesma coisa, já está previamente cadastrado e você seleciona, faz uma
consulta. Então toda ligação que faz uma escolha vai ser a tabela com um
DbLooKupComboBox.

Para as ligações do tipo Combobox – O Master será quem tem N e o Detail quem tem
o 1.
40

8.1.2 - MasterSource/MasterField

MasterSource/MasterFields: esta é utilizada se tiver que incluir um produto, um


item, por exemplo. No caso do pedido, terão que incluir os itens, eles não vão ser consultados,
mas sim inseridos na tabela. Tudo que for inserido, usa esse comando.

MasterSource: Essa propriedade é declarada como uma variável do tipo


TdataSource e especifica a tabela-mestre ao qual o componente será ligado.

MasterFieds: Essa propriedade é declarada como uma variável do tipo String que
define os campos que farão a ligação entre duas tabelas. Os nomes devem ser separados por
ponto-e-vírgula.

Como descobrir que é Master e quem é Detail?

Para ligações do tipo MasterSource/MasterField, o Master será quem tem 1 e o


Detail será quem tem o N.

8.2 - Ligação entre tabela de pedido e tabela de cliente

Teoricamente o cliente só pode ser consultado, porque já existe uma tabela especifica
para cadastrar clientes. Ex: O cliente CLEITON é o cliente que aparece para comprar
pequenos itens, quando vai ao supermercado. Pode ser cadastrado como cliente 999- venda ao
consumidor. Mas o cliente que sempre compra, geralmente tem um cadastro já feito e tem seu
próprio código, como o cliente de uma farmácia que paga mensalmente.

Quando for cadastrado um item num pedido, o cliente pré-cadastrado é selecionado na


tela. Em itens, aparecem vários códigos de produtos, que são selecionados e inseridos no
pedido. O que está sendo feito? Inserção de itens de produtos que estão previamente
cadastrados. Se o produto estiver cadastrado, você pode selecioná-lo para inserir o item.

É possível fazer a ligação entre as tabelas em qualquer banco de dados. Exemplo:


Tabela de clientes:

Código Nome
1 Cleiton
2 Anderson

Já existe a chave primaria. Ao fazer o pedido, teria o numero desse pedido

N° Pedido Nome do Cliente Data


1 Anderson 14.09.2010

E os itens do pedido que estão sendo incluídos.

CodProd Descrição Valor Qtde Total (uma espécie de matriz)


1 Mouse 15,50 2 31,00
41

2 WebCam 40,00 3 120,00


TOTAL 151,00

Imagine se não houvesse uma modelagem, então como deveríamos guardar esses
dados. Seria necessário guardar todos os dados no pedido. Exemplo:

Nº Pedido Data Cliente Endereço


1 12.05.2010 Cleiton Rua Antonio

Ou em cada linha gravar um item

Cod Cliente Descrição Valor


1 WebCam 40,00

Se o cliente quiser mais um item, teoricamente teria referência de tudo que for comum.
Esses dados se repetem para cada item colocado, então se deve aplicar a normalização (1FN,
2FN, 3FN). Reparem que essa parte tem uma coisa comum, linhas que se repetem várias
vezes.

8.3 - A primeira forma normal (1FN)

Tudo que se repete no banco de dados, exclua e coloque numa tabela separada. Tem
que dividir a tabela em duas partes. Uma que se repete várias vezes e a outra que é diferente
nos seus campos. Divida em duas Tabelas Uma com o nome Pedido e outra com o nome
Itens.

A tabela de pedido vai ter uma única vez os campos: n_pedido, data, nome, rua, etc.

Na outra tabela Itens vai ficar com os seguintes campos: cod_item, descrição, valor,
qtde, total. Exemplo:

PEDIDO ITENS
Numero Data Nome Cliente Endereço Cód.Item Descricao Valor
01 23/08/05 Cleiton Rua Antonio 01 Mouse 15,50
01 23/08/05 Cleiton Rua Antonio 02 WebCam 40,00

Se o banco de dados ficar exatamente assim, se for inserido um outro pedido, esse
outro pedido pode também comprar o caderno. A chave sendo só o código do item ou o
código do caderno daria para descobrir qual pedido ele pertence? Não.

Então tem que fazer uma ligação entre uma tabela e outra. Um pedido pode ter N itens
e um produto podem estar em N itens. A chave migra do lugar que tem 1 para o lugar que tem
N. A chave do pedido vai para itens. Se não for feita essa migração, você não saberá de que
pedido pertence o item.
42

8.4 - A chave estrangeira (Foreign Key).

A idéia é não repetir os dados muitas vezes, essa repetição foi substituída pelo código.
Tudo que se repete várias vezes foi separado em outra tabela.

PEDIDO ITENS
Numero Data Nome Cliente Endereço Cód.Item Descricao Valor
01 23/08/05 Cleiton Rua Antonio 01 Mouse 15,50
01 23/08/05 Cleiton Rua Antonio 02 Webcam 40,00

ITENS
Código Pedido Código Itens Descrição Valor Qtde Total
01 01 Mouse 15,50 02 31,00
01 02 Webcam 40,00 03 121,00

8.5 - A Segunda Forma Normal (2FN)

Existe informação gravada em outra tabela. Por exemplo: o nome Cleiton. Cada vez
que o Cleiton fizesse um pedido, seria preciso digitar o nome e o endereço do Cleiton. Se
fizesse muitos pedidos, seria preciso armazenar muitas vezes o nome e o endereço, ou pode
digitar uma única vez um código pré-cadastrado quando quiser buscar um campo. Esse código
(do cliente) sai de uma classe e vai para outra classe (a chave estrangeira). No diagrama, a
chave sai da classe que tem 1 e vai para a classe que tem N. A chave do código do cliente sai
da classe cliente e vai para a classe pedido. A chave substitui todos os campos que seriam
preenchidos e que são repetidos.

O item Mouse vem da tabela produto. Se a pessoa digitar o item errado ou pode
vender o item como se fosse outro produto, na verdade não pode permitir que o usuário digite
o nome do produto. A descrição pode ser importada da tabela produto, então não é necessário
um banco de dados, essa descrição pode vir da tabela de produtos, colocando apenas o código.

Exemplo:

Num pedido são descritos – Código Produto Unidades


1 2
2 1 53
2 3

A chave vai sair da tabela de produtos e vai para a tabela de itens.

Veja o Diagrama. A chave da classe produtos (1) vai para a classe itens (N) – código
do produto vai para a classe itens.

1 N 1 N N 1
CLIENTE PEDIDO ITENS PRODUTO
43

O que está sendo feito? Sendo minimizados os dados que tem na tabela, ao invés de
guardar a descrição repetida vezes, assim podendo acessar dados repetidos através de chaves.

ITENS
Código Pedido Código Produto Qtde Total
01 01 2 15,50
01 02 3 40,00

8.6 - A Terceira Forma Normal (3FN)

Todos os campos que são calculados podem ser retirados da tabela. Ex. Num pedido
pode ter o total desse pedido somando todos os itens. Se a chave for Foreign Key ele vai da
tabela que tem 1 para a tabela que tem N.

Na tabela de pedido tem que ser guardado o valor, porque o valor de um item, hoje
pode ser um preço, amanhã pode subir, e se o cliente quiser devolver um produto, o valor da
compra tem que estar armazenado (o valor do dia da venda).

8.7 - Quem manda em quem

Quem é o Master e quem é o Detail, quem está mandando nas tabelas?

Na tabela de pedidos. Em uma venda, o vendedor seleciona o cliente e o sistema


mostra o pedido ou entra na tela pedido e o sistema mostra o cliente para ser selecionado.
Entra na tela pedido, então quem manda é o pedido (Máster). O item vai ser o Detail. Quando
tiver uma ligação do tipo Máster/Detail.

- O Máster é sempre quem tem o 1.

- O Detail é sempre quem tem o N.

Na ligação Cliente/Pedido – A ligação é Combo.

Consulta Inserir Consulta

1 N 1 N N 1
CLIENTE PEDIDO ITENS PRODUTO
Detail Master Detail

Combobox Máster Combobox


Máster Detail

A chave do Pedido vai para Itens (1..N)


44

Em que tabela ira ser chamada o Máster? Na Combobox as coisas se invertem.

Na tabela de Pedidos, quem manda é quem tem N, sendo assim o Master vai
continuar sendo pedidos e o Detail vai ser o cliente. Se a ligação for do tipo combobox, quem
manda é quem tem o N, quem tem bastante é o Máster. Quem tem pouco é o Detail – é
mandado.

O MasterSource/MasterFields tem uma ligação tipo patrão e empregado.

No caso do campo entre produtos e itens, quem vai mandar é o itens (vai ser o
Master) e o produto vai ser o Detail.
45

9 - CRIANDO AS TABELAS

No InterBase, abra o banco da aplicação 2 (VENDAS 2) e crie as seguintes tabelas

Tabela de Funcionarios

Create table tb_funcionarios


(
cod_func numeric (10,0) not null primary key,
nome_func varchar (30),
end_func numeric (10,2),
cid_func varchar(30),
uf_func char(2)
);

Qtde – se uma empresa trabalha com vendas por


gramas, teoricamente deveria ter casas depois da vírgula, se
fosse açougue, então permitiria casas depois da vírgula, no
caso de uma loja de roupas, ninguém vende uma camiseta e
meia, não tem fração, então o número vai ser zero(0), sem
casas decimais.
A quantidade mínima de estoque tem que ser do
mesmo tipo da quantidade de estoque.

Tabela de Pedido

Create table tb_pedido


(
cod_ped numeric (10,0) not null primary key,
data_ped date,
cod_cli numeric (10,0) not null,
cod_func numeric (10,0),
status_ped numeric (5,0)
);
46

O total do pedido não precisa ser guardado na tabela de


pedido porque é um campo calculado.

A forma normal pede que todo campo calculado deva ser retirado do banco, mas em
uma grande empresa faz-se muitos cálculos para saber, por exemplo, quanto foi vendido do
final do ano, no mês. Na normalização, para cada pedido, abre a tabela e soma todos, um por
um, isso perde muito tempo quando existe muitos relatórios desse tipo. O ideal é colocar o
total no mesmo banco, para não precisar fazer o calculo de novo, isso agiliza a busca em SQL.

Então quando não obedecer a 3FN? Quando precisar otimizar, isto é, de muita
velocidade no banco, faz-se o calculo e deixa gravado no próprio banco.

Se tivesse um cadastro de funcionários. Exemplo: foi feita uma venda e foi cobrado
um preço errado, tem que cobrar de alguém, o código do funcionário que efetuou a venda
estará registrado. Para isso tem que ser criada a tabela de funcionários.

A chave primária é o código do pedido, só ela é NOT NULL, mas se for obrigatório o
código do cliente, então acrescente também NOT NULL nesse código. Quando o código do
cliente for obrigatório, tem que selecionar primeiro o cliente para depois inserir os itens.

Status do Pedido – Se está fazendo uma venda, vai chegar num ponto em que cada vez
que passar por um setor da empresa, essa venda muda de status. Exemplo: Pedido não
concluído, pedido encaminhado para o setor de crédito, pedido aprovado, pedido sem emissão
de nota fiscal, pedido entregue.

Para que é necessário este Status? Para saber a situação atual da sua venda até a
entrega e conclusão definitiva da venda.

Tabela de itens

Create table tb_itens


(
cod_ped numeric (10,0) not null,
cod_prod numeric (10,0) not null,
valor_prod numeric (10,2) not null,
qtd_prod numeric (10,0),
primary key (cod_ped, cod_prod)
);
47

Na tabela de itens é necessário ter as chaves estrangeiras (código do pedido e código


do produto).

9.1 - Referencias entre as tabelas (os foreign keys)

Para adicionar as referências o Lazarus tem que estar fechado.

No IbConsole

Alter table tb_pedido Add foreign key (cod_cli) references tb_clientes (cod_cli);
Alter table tb_itens Add foreign key (cod_ped) references tb_pedido (cod_ped);
Alter table tb_itens Add foreign key (cod_prod) references tb_produto (cod_prod);

Quanto às chaves.

1 - A chave primaria migra da tabela que tem 1 para a tabela que tem N.

2 - Tem que descobrir quem é Master e quem é Detail.

Ligação do tipo consulta – Dblookupcombobox

Ligação do tipo inserir – MasterSource/MasterFields - permite a inclusão de novos


registros

3 - Como descobrir quem é Master e quem é Detail

Para as ligações do tipo MasterSource/MasterField – o Master será quem tem 1 e o


Detail será quem tem o N

Para as ligações do tipo Combobox o Master será quem tem N e o Detail quem tem 1

Quais as ligações?

Entre a tabela de pedido e a tabela do cliente foi criado uma referência entre código do
cliente e código do pedido, porque se a pessoa deletar o pedido não deleta também o cliente.
Exemplo: Se estiver no pedido e deletar esse pedido, quando for consultado o cliente, este
não existirá mais, então o sistema não deixa apagar se tiver alguma referência.

Porque não foi criado os Foreign Key quando foram criadas as tabelas?

Se fizer referências na criação das tabelas, pode haver alguma tabela ainda não criada.
Exemplo: Você criou a tabela de itens, mas ainda não criou a tabela de produtos, se tentar
colocar um Foreign Key, vai dar erro, porque a tabela de produtos ainda não existe.

Portando crie todas as tabelas, depois faça as referencias.


48

Essas regras têm que guardar, deve conhecer essa analise.


49

10 – FORMULÁRIO DE VENDAS AO CLIENTE

10.1 – Introdução

No tópico anterior foi criado o Cadastro de clientes, e foi criada a tabela (o


componente TZQuery). Foi programado no evento da tabela (AfterPost) – Após o salvar ira
salvar as atualizações.

Quando salvar um banco, e não salvar o gdb ou deixar em


formato diferente do GDB, basta executar novamente o
script dentro do IBConsole.

10.2 - Criando a Tela de Vendas

Depois que as telas de cadastro de clientes, de produtos, fornecedores etc., estiverem


prontas é hora de criar a tela de pedidos (vendas).

Crie um novo formulário (File >New Form) e de as seguintes propriedades:

Name Caption
Frm_vendas Venda de Produtos

E salve essa UNIT dentro da pasta vendas2\formularios, com o nome u_vendas

10.3 - Relembrando capítulo anterior

Consulta Inserir Consulta

1 N 1 N N 1
CLIENTE PEDIDO ITENS PRODUTO
Detail Master Detail
Combobox Máster Combobox

Máster Detail
50

- Entre Pedido e Itens o Máster está em Pedido e Detail está no Itens.

- Entre Itens e Produto, o Máster está em Itens e Detail está em Produtos

10.3.1 - A Chave

Entre Cliente e Pedido

- Um cliente pode ter N pedidos.

- Cada pedido tem um único cliente.

A chave então vai da classe que tem 1 para a classe que tem N.

Entre Pedido e Itens

- Um pedido pode ter N itens.

- Cada item pertence a um único pedido.

- Um produto pode aparecer em N itens.

- Cada item está em um único pedido.

Quando a ligação é do tipo MasterSource/MasterFields, quem tem 1 é o “Patrão”


(Máster), para um monte de “empregados” (Detail).

Quando a ligação é do tipo Combobox, no lugar que tem 1 é o Detail e onde tem N é o
Master.

MasterSource – quando permite inserção.

Combo – quando permite consulta.

10.4 - Construindo as bases de dados

Para poder pegar os dados que estão no bando de dados através da TABLE é
necessário declarar no Form principal.

Entre no modulo de programação pressionando a tecla F12 com o form principal


aberto e em baixo da linha de programação IMPLEMENTATION, complete digitando
u_vendas:

implementation
uses u_cadcli, u_prod, u_func u_vendas;

E necessário adicionar todas as tabelas que vamos trabalhar.


51

O que compõe um pedido?

O pedido tem a própria tabela de pedido, os itens, os produtos e para quem está
vendendo (o cliente), além disso, você pode ter opcionalmente algumas tabelas do tipo:
funcionário, forma de pagamento, porque na venda pode ser escolhido a forma de pagamento,
se é a prazo ou à vista e outras tabelas que podem ser agregadas depois, como: contas a
pagar, a receber, fornecedores, etc.

Insira varias TZTABLE que se encontra na paleta Zeos Access com as seguintes
propriedades:

TABELA CLIENTES

Name TableName Conection AutoCalcField CachedUpdates


Frm_vendas Tb_clientes Frm_principal.z_conexao TRUE TRUE

TABELA PRODUTOS

Name TableName Conection AutoCalcField CachedUpdates


Tbl_prod Tb_produtos Frm_principal.z_conexao TRUE TRUE

TABELA PEDIDO

Name TableName Conection AutoCalcField CachedUpdates


Tbl_pedido Tb_pedido Frm_principal.z_conexao TRUE TRUE

TABELA ITENS

Name TableName Conection AutoCalcField CachedUpdates


Tbl_itens Tbl_itens Frm_principal.z_conexao TRUE TRUE

A propriedade Active de cada TZTable, deve estar


TRUE, quando for testar o programa, devera passar para
FALSE todas as TZTable

Agora insira um DataSource para cada tabela:


52

TABELA CLIENTES

Name DataSet
DS_cli Tbl_cli

TABELA PRODUTOS

Name DataSet
DS_prod Tbl_prod

TABELA PEDIDO

Name DataSet
DS_ped Tbl_ped

TABELA ITENS

Name DataSet
DS_itens Tbl_itens

A etapa a seguir é para simples demonstração de uso dos componentes.

10.4.1 - Colocando duas grids para demonstração:

Coloque duas DBGrids no form, através da paleta Data Controls

Figura 34 – Salvando a tela de Vendas


53

Estas grids vão ser retiradas depois

A Primeira Grid, ligar com o DataSource Pedido – DS_Ped:


Propriedade DataSource > DS_Ped.

A segunda Grid ligar com o DataSource Itens – DS_Itens:


Propriedade DataSource > DS_Itens

Antes, cadastrar alguns dados na tabela pedido do Interbase, só para verificar como
funciona. No interbase na tabela de pedidos – cadastrar dois pedidos para exemplo para o
mesmo cliente. Clicar em Commit para salvar.

Figura 35 – Cadastrando Pedidos no InterBase

Alterar para a tabela de produtos para cadastrar dados conforme abaixo:


54

Figura 36 – Cadastrando Produtos no InterBase

Na tabela de Itens. No pedido numero 1, o cliente compra o primeiro produto, vai


pagar R$40,00 e comprou duas unidades. O pedido numero 2, o cliente comprou também o
produto numero 1, pagando R40,00 reais e comprou no mesmo pedido o produto numero 2
pagando R$90,00 a promoção de Monitor.

Figura 37 – Cadastrando Itens no InterBase


55

O pedido 1 tem um item, o pedido 2 tem dois itens. Salve clicando Commit e volte
para o Lazarus.

Na tela de Vendas (frm_vendas), mude todas as propriedades ACTIVE das tabelas


para TRUE.

As Grids informam os seguintes resultados, conforme figura abaixo:

Figura 38 – Tela de Vendas (TRUE)

O que está acontecendo? A pessoa está mostrando o pedido número um na tela, mas
estão sendo exibidos os itens do pedido um e também do 2.

Neste sistema, se você vai comprar algum produto, quando exibido o pedido na tela,
você consegue ver a lista de compras do ultimo cliente.

O Ideal é quando estiver na tela o pedido 1, seja mostrados os itens somente deste
pedido. Se do pedido 2, somente devem ser mostrados os itens do pedido 2.

Estas são as propriedades das ligações MasterSourse/MasterField ou MasterDetail,


quando tem vários itens, só aparecem só o equivalente, só a referência correta.

Ex: Se for uma compra num supermercado, aparecerá todos os itens comprados por
esse cliente, tudo que estiver registrado.
56

Quem é o Master e quem é o Detail na Tabela? Pedido é o Master e Itens é o Detail.

Quando a ligação for do tipo MasterSourse/MasterField, então vá ao Detail e


indique quem manda nele.

Na tabela de Itens que é o Detail – indique quem é o Master. Selecione a Tabela de


Itens(o componente TZTable).

No Object Inspector mude as seguintes propriedades:

MasterSource MasterFields LinkedFields


DS_Ped Cod_Ped Cod_Ped

Ao fazer todas as propriedades anteriores, automaticamente se conecta uma tabela com


outra, a chave do pedido vai para o Itens . O elo de ligação entre uma tabela e outra é
Cod_Ped (foreign key).

Veja o que acontece agora. Para o pedido numero 1 mostra is itens respectivos, assim
como para o pedido numero 2 mostra os itens do pedido 2.

Figura 39 – Ligação MasterDetail

Tudo que for permitir inclusão na mesma tela você liga através de
MasterSourse/MasterFields. Tudo que for para consultar DBLookupcombobox.
57

10.5 - Ligando a Tabelas de pedido e cliente.

A tela de clientes com pedidos é ComboBox. A tabela que você foi quando estava
fazendo o Master-Detail entre as tabelas de pedido e itens, foi no Itens (Detail) e indicou
que o Master é o pedido, isso para ligação Master Detail.

A ligação entre as tabelas de clientes e pedidos é ComboBox. Em relação a


MasterSourse/MasterField, quem tem 1 é Master e então inverteu a ligação.

O tipo desta conexão vai inverter-se. Agora você vai no Master para informar quem é
o Detail.

Para as ligações do tipo DBLookupComboBox, Vamos até a tabela Master (a que


tem N) e informamos o campo Detail.

Na tabela Pedido (Combo - Master)

De um duplo clique na tabela Pedido > no painel de diálogo abaixo:

Figura 40 – Edit Fields

Clique com o botão direito do mouse dentro da caixa(Edit Fields) e escolha a


opção Add Fields . Aparecera um caixa para escolher quais campos devera ser add.
Selecione todos os campos e clique no botão CREATE.
58

Figura 41 – Add fields

Para conseguir adicionar os campos e criar o lookup é


preciso que as tabelas estejam com a propriedades ACTIVE
tudo em FALSE

Assim a tela ficara como mostrado abaixo:

Figura 42 – Edit Fields com os campos adicionados


59

Clique com o botão direito em qualquer parte da janela(Edit Field) e escolha a opção
NEW, aparecerá a caixa de diálogos (New Field) abaixo:

Figura 43 – New Field

Crie um novo campo na tabela de cliente: Quando a tabela for aberta, como exemplo
aparecerá o nome do cliente. Diferente do Delphi, não é preciso especificar o Name, Type e
Size, pois o Lazarus pega o nome, tipo e tamanho do próprio campo da tabela.

Selecione a opção Lookup na área Fild Type na área Lokup Definition preencha os
campos:

Key Field: Cod_cli


Dataset: Tbl_cli
Lookup Keys: Cod_cli
Result Fields: Nome_Cli

Figura 44 – Tela de Dialog Pronto Ligações


60

Após o termino clique no botão Ok. Ira aparecer o campo NomeCli.

Figura 45 – Campo Nome_Cli (lookup)

10.6 - Usando o Campo Criado.

Remova a Primeira Grid e adicione 5 DBEdit que se encontra dentro da paleta Data
Controls, com as seguintes propriedades:

DBEdit DataSource DataField


1 DS_Ped COD_PED
2 DS_Ped DATA_PED
3 DS_Ped COD_FUNC
4 DS_Ped STATUS_PED

Para o campo Nome do Cliente adicione o componente DBLOOKUPCOMBOBOX


que se encontra dentro da paleta DATA CONTROLS, com o componente selecionado mude
as seguintes propriedades:

DataSorce DataField ListSorce ListField KeyField


DS_ped Nome_cli COD_PED

Agora para cada DBEdit adicione os Label(Paleta Standart) que esta no formulario

Campo(DBEdit) Caption
1 Código do Produto
2 Data
3 Código do Funcionario
61

4 Status do Pedido
5 Nome do Cliente

Ao invés de colocar o Código do Cliente (Cod_Cli) coloque o campo (Nome_Cli) para


mostrar o nome do cliente. O ideal para criar um novo campo, quando for feita a ligação com
o New é ter a tabela com o Active = false.

Após inserir os campos ative TODAS as tabela.

Posicione os campos da seguinte maneira

Figura 46 – Visualizando o Formulário com Lookup

Quando for escolher um pedido, geralmente quer que os demais dados sejam
apresentados, porque pode ter dois clientes com mesmo nome residindo em locais diferentes.

Da tabela de cliente, coloque os demais campos que estão faltando tipo: endereço,
cidade e Unidade Federativa.

Desative todas as tabelas, ou seja, passar a propriedade ACTIVE de todas as tabelas


para FALSE.

De um duplo clique na Tabela de Clientes(Tbl_cli) e na janela que surgi clique com o


botão direito e escolho a opção NEW, selecione todos os campos e clique no botão create, e
logo em seguida feche a pequena janela
62

Novamente no formulário entre na paleta Data Controls e adicione 3 DBEdit para


endereço, cidade e UF com as seguintes propriedades

DBEdit DataSource DataField


1 DS_Cli ENDER_CLI
2 DS_Cli CIDADE_CLI
3 DS_Cli UF_CLI

E para cada campo adicione um Label que se encontra dentro da paleta Standart:

Campo(DBEdit) Campo
1 Endereço
2 Cidade
3 UF

Não coloque os campos que irão se repetir.

No lugar da primeira Grid, ficou os campos da tabela de Pedido: Código, Data,


Funcionário, Status e Nome do Cliente. Da tabela de Cliente ficaram os campos: Endereço,
Cidade e UF.

Ligue todas as tabelas novamente (Active = TRUE) e veja como ficou a tela do
formulário:

Figura 47 – Visualizando o Formulário com os todos os campos


63

10.7 - Campos não ativos

Para indicar que os campos da tabela de clientes não estão ativos, coloque outra cor
para destacá-los.

10.7.1 - Para selecionar vários campos da tabela de cliente:

Com a tecla Shift pressionada clique nos campos da tabela de clientes: Endereço,
Cidade e UF.

Troque a cor para indicar que os campos estão desabilitados.

Color ReadOnly
Escolha a cor TRUE

ReadOnly: Isto quer dizer que os campos estão desabilitados. Mesmo que o usuário
clicar em cima de qualquer destes campos, não vai modificar, é só para consultar.

Figura 48 – Propriedade ReadOnly


64

O formulário ficará assim:

Figura 49 – Visualizando o Formulário com ReadOnly Pronto

Volte no formulário principal e acesse o Menu Movimentações->Pedido para que


entre no modulo de programação, e digite a seguinte linha:

procedure Tfrm_principal.MenuItem3Click(Sender: TObject);


begin
frm_vendas.ShowModal;
end;

Antes de executar o projeto todas as tabelas devem estar


com a propriedade ACTIVE em FALSE
65

Não se esquece que no Evento OnActive do formulário


Vendas(frm_vendas) tem que conter as linhas de
programação para abrir todas as tabelas, ou seja:
Tbl_cli.Open;
Tbl_prod.Open;
Tbl_ped.Open;
Tbl_itens.Open;
Assim toda vez que a tela de formulário for carregada, as
tabelas serão abertas

Ao executar o programa se a pessoa tentar alterar os dados, como nome do cliente,


endereço e outros campos da tabela de cliente, não ira conseguir. Se escolher outro cliente os
dados irão aparecer apenas para consulta do cliente selecionado. (Os dados do cliente estão
apenas sendo exibidos, mas não podem ser modificados.)

Quando fizer a busca sem usar o mouse, se digitar o J, por exemplo, mostra o nome
começado com J em ordem alfabética. Se pressionar outra letra inicial, o sistema busca o
nome começado com aquela letra. O sistema já está com busca de Locate ativada por padrão.

10.8 - Adicionando Campos na Grid.

Para adicionar outros campos na descrição de itens

Desative todas as tabelas e de um duplo clique na Tbl_Itens (TZTable) e clique com o


botão direito depois escolha a opção Add Fields na próxima janela que aparece(FieldDefs)
selecione todos as campos e clique no botão CREATE, voltando para a janela EDIT FIELD
clique com o botão direito na parte branco e escola a opção NEW

Nas propriedades:

Lookup - do tipo Cod_Prod da tabela de Itens com Cod_Prod da tabela de Produtos


e mostra a descrição.

Definições:

Key Fields: COD_PROD


Dataset: Tbl_Prod
Lookup Keys: COD_PROD
Result Field: DESC_PROD
66

Figura 50 – Lookup tabela Itens

Foi ligado o Código do Produto com Código do Produto. Um da tabela de Itens e outro
da tabela de Produto. No resultado mostra a descrição: DESC_PROD.

Clique no botão OK.

Para colocar o campo DESC_PROD após o campo código do produto, de um duplo


clique na tbl_itens(TZTable), clique com o botão direito em cima do campo DESC_PROD, e
escolha a opção MOVE UP (PARA CIMA), faça isso até chegar onde deseja ou seja em
baixo do campo COD_PROD

Para renomear o campo DESC_PROD basta selecionar o mesmo e no Object Inspector


mudar a propriedade DisplayLabel para Descrição. (Se preferir mude os campos para um
nome mais coerente).

Figura 51 – Selecionando o campo descrição da tabela de Itens


67

Com o campo DESCRIÇÃO selecionado altere a propriedade LookupCache para


True, no Objet Inspector

Ative Todas as tabelas começado pela tbl_cli, tbl_prod, tbl_ped, tbl_itens.

O formulário ficara da seguinte maneira:

Figura 52 – Formulário pronto com Lookup na Grid Itens

Na execução do sistema, se o cliente não quiser a pilha, clicando uma vez no canto da
descrição, o sistema abre um Lookup e você pode escolher outro produto. Por enquanto foi
colocado um lookup cliente, colocamos os demais campos da tabela cliente que eram
necessários, foi criado lookup da tabela itens, foram colocados os campos na ordem certa
com um lookup nos itens.

10.9 - Criando o campo total (Campo calculado).

Duplo clique na Tabela de Itens > New - para criar o campo total

No campo “Field Type” selecione a opção Calculated.

Name Type
Total Float
68

Figura 53 – Fazendo o Calculated

Clique no botão OK

Se reativar a todas as tabelas agora o total não ira aparecer


porque o campo precisa ser programado.

Ainda na tabela de Itens.

Events > OnCalcfields > duplo clique para entrar no modo de programação.
69

Figura 54– fazendo a programação no Evento OnCalcFields

10.10 - Programação:

Evento OnCalcFields: Ao ter um campo calculado. Toda vez que tiver um campo do
tipo calculado a programação é feita neste evento.
70

procedure TFrm_Venda.Tbl_ItensCalcFields(DataSet: TDataSet);


begin
{Todas as vezes que temos um campo do tipo calculado
(3 forma normal), devemos programar a propriedade
OnCalcFields da tabela com o calculo a ser
realizado}

Tbl_itens.FieldByName('total').asfloat:=
Tbl_itens.FieldByName('valor_prod').asfloat*
Tbl_itens.FieldByName('qtd_prod').asinteger;

end;
end.

De duplo clique novamente na tabela de Itens para colocar o tipo dos campos Valor e
Total como moeda e duas casas decimais.

Clique sobre o campo valor.

 Propriedade > Currency > coloque true.

Faça o mesmo para o campo Total.

Essa propriedade funciona apenas para campos do tipo


real (Float).

O que falta: Programar todos os botões de inclusão e fazer todo o tratamento, porque
quando incluir o número do pedido, o sistema vai ter que gerar este número automaticamente.
Falta o tratamento dos campos. Fazer o tratamento do campo valor do produto para aparecer
automaticamente, quando escolher o produto. Não foi feita a baixa de estoque.
71

11 - Tratamento dos Componentes Programação

11.1 - Fazendo o Tratamento

O pedido ainda não está trazendo o valor do produto automaticamente, não está
numerando os itens.

Existem duas formas de fazer: através de uma Store Procedure no Banco de Dados
ou através de programação. A melhor é a Store Procedure. Como ainda não foi vista a Store
Procedure, vamos executar a programação no Lazarus.

11.1.1 - Como criar um campo auto-numerado.

Para inserir um novo pedido, temos que gerar um código automaticamente. Como
fazer? Quando for clicado no botão inserir novo item, é chamado o evento Insert da tabela.
Só que antes de inserir é necessário efetuar um cálculo.

O Evento Insert

Antes de começar inserir, é percorrido todos os campos no banco até encontrar o


último campo. É gravado em uma variável auxiliar o código do último campo, então é
aplicado o Insert. Antes de inserir, o auxiliar recebe o último código do pedido, depois é
inserido. Depois de inserir grava-se o último + 1 (código do pedido = aux + 1).

Para implementar é necessário criar uma variável. Crie a variável aux do tipo inteiro.

Uma parte da programação será feita em BeforeInsert e outra parte no AfterInsert.

BeforeInsert – evento antes de inserir.

AfterInsert - evento após inserir.

Criando a variável.

Pressione F12 para entrar no módulo de programação e procure pela clausula


IMPLEMATION. Digite a linha que representa a variável.

var
frm_vendas: Tfrm_vendas;

implementation

{ Tfrm_vendas }

var aux: integer;{variavel criada para armazenar o ultimo pedido realizado.


Devemos lembrar que este nao e o melhor metodo. O ideal e usar triggers ou
storedprocedure}
72

Devemos lembrar que quando for feito um sistema


profissional não usar variável aux, isto é feito no banco
porque é mais seguro. Só que como não foi visto ainda, por
enquanto será feito assim.

11.2 - Como fazer para a tabela chegar no último campo.

A tabela Pedido é a que tem o código de inserir.

Tabela Pedido(TZTable) > Events > BeforeInsert.

Programação:

procedure TFrm_Venda.Tbl_PedBeforeInsert(DataSet: TDataSet);


begin
{devemos gravar o ultimo codigo usado em aux}
Tbl_Ped.Last;
aux:= Tbl_Ped.fieldbyname('cod_ped').asinteger;

end;

O que está sendo feito: O último valor do código do pedido da Tabela de Pedido é
armazenado dentro da variável aux.

Tabela Pedido(TZTable) > Events > AfterInsert.

A programação é basicamente a inversa da anterior. Esta mesma programação pode ser


feita em todos os cadastros: de clientes, de produtos, etc.

procedure TFrm_Venda.Tbl_PedAfterInsert(DataSet: TDataSet);


begin
{gerar codigo automaticamente: gravar o ultimo codigo + 1}
Tbl_Ped.fieldbyname('cod_ped').asinteger:=aux+1;
end;
73

11.3 - A hora e a data do sistema

Não só o código do sistema, mas também a data deve ser colocada automaticamente.
A hora do sistema – a única diferença é que não precisa de conversão, porque o tipo dele já é
tipo DataTime.

Programação:

procedure TFrm_Venda.Tbl_PedAfterInsert(DataSet: TDataSet);


begin
{gerar codigo automaticamente: gravar o ultimo codigo + 1}
Tbl_Ped.fieldbyname('cod_ped').asinteger:=aux+1;

{adicionar a data}
Tbl_ped.FieldByName('data_ped').asdatetime:= now;
end;

A execução do sistema.

Apenas para verificar a execução, pode ser usado um DBNavigator (DS_PED). Ao


executar, clicando no mais, o sistema insere o último pedido + 1 e já coloca a data. Falta
colocar a tabela de funcionários e o cliente. Foi programada, por enquanto, só a tabela de
pedido.

11.4 – Antes de Inserir um Item

Para adicionar um novo item no banco, só é possível inserir um registro se existir uma
chave estrangeira (Foreign Key). Se adicionar os dados e enquanto não for executado um
„Post’, os dados não são salvos porque a programação Aplly UpDates está no evento After
Post. Se não clicar em Post para salvar e mandar inserir um item, vai dar erro.

Se não tem pedido, não dá para incluir um item. Não existindo a chave estrangeira (do
pedido), não da para inserir item nenhum. Então para clicar e inserir um novo item, é
necessário verificar se o pedido já foi salvo, se não, salve primeiro e depois aplique o Inserir.

Programação

 Tabela Item(TZTable) > Events > BeforeInsert.

procedure TFrm_Venda.Tbl_ItensBeforeInsert(DataSet: TDataSet);


begin
{Devido à existência de uma chave estrangeira, só
podemos incluir um novo item se o pedido já estiver salvo.}
if tbl_ped.state in [dsInsert] then
try
tbl_ped.Post;
except
showmessage('verifique os dados do pedido!');
74

TbL_itens.Cancel;
end;
{para incluir um novo item, devemos verificar se já
não existe um item que ainda não foi salvo.
Se existir, devemos salva-lo antes}
if tbl_ped.state in [dsInsert] then
try
tbl_itens.Post;
except
showmessage('verifique os dados do item da venda!');

end;

end;

Tabela Itens(TZTable) > Events > AfterInsert.

Aqui é gerado automaticamente o código de item:

procedure TFrm_Venda.Tbl_itensAfterInsert(DataSet: TDataSet);


begin
{gerar codigo automaticamente: gravar o ultimo codigo + 1}
Tbl_Ped.fieldbyname('cod_item').asinteger:=aux+1;
end;

Em primeiro lugar, verifique se o pedido está no modo de inserção.

O comando Try...Exeption – Pode ser que tenha algum campo obrigatório que foi
esquecido de preencher. Se der algum problema na tabela, enviar mensagem para verificar os
dados do Pedido e cancelar a inclusão através do comando TbL_itens.Cancel;, porque se
deixar incluir e der erro é porque algum campo está faltando na tabela de Pedido.

Na tela – Pode ter um botão para incluir um novo item e um botão para cancelar. Nos
Itens – Pode ser permitido digitar os dados, escolher o produto. No Lookup tem a seta para
escolher o produto.
Cada vez que inserir um novo item, é necessário verificar se o item anterior já foi
salvo, se não foi, então salva.

11.5 – Adicionando campos na GRID

Duplo clique na Grid e na caixa de diálogos clique 5 vezes no botão ADD


75

Figura 55 – Adicionando Campos na Grid

Agora para cada campo mude a seguinte propriedade.

CAMPO FIELDNAME
0 – Title COD_PROD
1 – Title DESC_PROD
2 – Title QTD_PROD
3 - Title VALOR_PROD
4 – Title Total

Assim todos os campos que deseja será inserido na Grid.

Figura 56 – Grid com os campos já prontos


76

É necessário programar o Código do Pedido?


Atribuir no código o Insert?
Teoricamente sim mas como foi usado o
Máster/Detail, o Lazarus assume que você esta usando uma
ligação para inclusão. A chave que liga uma tabela com
outra é o cód_ped de uma com cód_ped de outra. Se esta
fazendo inclusão, então o cód_ped é copiado para a tabela
itens, então já faz a programação automaticamente, não é
necessário pegar a tabela de itens recebendo o Cód_Ped. Isto
porque é uma ligação do tipo Máster/Detail.

11.6- Colocando o valor na Tabela de Produto.

Para atribuir o valor automaticamente quando incluir um novo item.

Se tivesse trabalhando com supermercado, teríamos


que ter um campo a mais na tabela. Na tabela de itens, temos
o Cód_Ped, Cód_Prod, Qtde e valor. As chaves é Cód_Ped e
Cód_ Prod.

Numa compra em um supermercado, quando passamos os itens, praticamente é


passado item por item de forma desordenada, então se for passado um item pela segunda vez,
o sistema acusaria que a chave já existe. Quando passa os itens, o sistema vai imprimindo o
cupom fiscal. Para resolver o problema é necessário uma terceira chave, o código do Item.

Se tivesse o código do Item no Evento BeforeInsert é necessário pegar o último


código e fazer a mesma programação ao Inserir um novo Item, igual ao inserir um novo
pedido.
77

Então é necessário uma variável auxiliar para o evento BeforeInsert) e na Tabela de


Itens no evento AfterInsert o código do item é igual a Aux + 1. Qualquer sistema que
trabalha com itens repetidos fora de seqüência tem que ter um código de Itens.

O que acontece quando escolhemos um novo item?

Quando é adicionado um novo item, é necessário atualizar o totalparcial do pedido,


para isso é necessário gravar o valor da tabela Produto dentro do valor da tabela pedido. Para
fazer isso é necessário programar o evento After Scroll, que é um evento de navegação.
Scroll é o evento que faz modificações entre os campos. Você vai ficar modificando entre os
campos, escolhendo valores. Se a tabela de itens estiver no modo de Insert e acabou de
navegar (acabou de escolher um novo produto). Quando achar o produto (após parar de
navegar) o valor que estiver no produto é copiado no valor do item.

Essa programação é feita na tabela de Pedido, o evento então é o AfterScroll da tabela


de Pedido. Se a tabela de Itens está no modo de Insert é copiado o valor na tabela.

Programação:
Na tabela de Pedido > OI > Eventos > AfterScroll

procedure TFrm_Venda.Tbl_PedidoAfterScroll(DataSet: TDataSet);


begin
{quando o usuario escolhe um produto atraves de um
dblookupcombobox, ele esta navegando (scroll) na
tabela de produto. Apos parar de navegar, devemos
verificar se a tabela de itens esta em modo de insert,
e sendo verdadeiro, copiar o valor do produto para o item}
if tbl_itens.State in [dsinsert, dsedit] then
Tbl_Itens.FieldByName('valor_prod').AsFloat:=
Tbl_Prod.FieldByName('valor_prod').AsFloat;
end;

end.

Na execução, após clicar com o mouse sobre a descrição do produto para incluir um
novo item, só de passar a seta em cima da descrição, o valor do produto aparece do lado.

Agora é preciso digitar só a quantidade.


78

Uma das condições de um bom sistema é o usuário


digitar o mínimo possível.

Salvando os dados do Pedido

Os itens gravados no Pedido, ainda não estão sendo salvos. Para gravar tem que ser
efetuado o comando AplyUpdate.

No evento ApterPost da tabela de Itens é feita essa programação.

Na tabela de Itens > OI > Eventos > AfterPost

Programação:

Tbl_Itens. ApplyUpdates;

Se não for colocado ApplyUpDate, o sistema não salva diretamente no banco, fica só
na memória, e na hora que for encerrado o aplicativo os dados se perdem.

Na tabela de Pedido, antes de Inserir um novo Pedido, fazer a seguinte


modificação.

OI > Events > Before Insert

Programação:

procedure TFrm_Venda.Tbl_PedBeforeInsert(DataSet: TDataSet);


begin
if tbl_itens.state in [dsedit, dsinsert] then
begin
Tbl_itens.Post;
Tbl_Itens.ApplyUpdates;
end;
{devemos gravar o ultimo codigo usado em aux}
Tbl_Ped.Last;
79

aux:= Tbl_Ped.fieldbyname('cod_ped').asinteger;

end;

Na programação do AfterScroll só tínhamos colocado dsinsert(só quando estivesse


inserindo e estivesse escolhendo Scroll iria colocar automaticamente o valor) mas se estivesse
editando, não iria responder. Se quiser colocar quando editar é só colocar o comando dsEdit.

Na execução do programa.

Insere um novo pedido, escolhe o cliente, o item do produto, o valor é colocado


automaticamente, a quantidade é digitada. Quando clicar num novo pedido, o sistema salva o
anterior e começa um terceiro pedido.

Esta faltando Fazer o total e a baixa em estoque.

11.7 - Colocando os botões de comandos

Até agora já foi tratado o total, o valor do produto que tem que aparecer
automaticamente, o código auto-incremental do pedido que gerava o ultimo código + 1, já
preenche automaticamente a data e traz automaticamente os dados do cliente. O que falta?
Substituir o Navigator por botões

Figura 57 – Tela de Vendas com DBNavigator

Retirar o Navigator
80

Na Paleta Additional > SpeedButton > Colocar cinco botões no Form.

11.7.1 - Propriedades dos Botões

Botão Name Caption


Primeiro Btn_NovoPedido Novo Pedido
Segundo Btn_CancelaPedido Cancelar Pedido
Terceiro Btn_ConfirmaPedido Confirmar Pedido
Quarto Btn_InserirItens Inserir Produtos
Quinto Btn_ExcluirItens Excluir Produtos

Nos botões de Inserir e Excluir Itens, foi colocado no


Caption os nomes de Inserir Produto e Excluir Produto, porque
é para a interface do usuário. O usuário não conhecendo nada de
modelagem, não sabe que tem que criar itens, não é obrigado
conhecer que tem que ter uma ligação N para N. Pelo menos ele
sabe o que é produto.
81

Figura 58 – Tela de Vendas com botões

11.8 - A Programação dos botões

11.8.1 - Botão Novo Pedido

Como fazer para chamar um novo pedido? Tbl_Ped.Insert

Já foi feito o tratamento, se não estiver salvo, então


salva o último e insere um novo pedido. É só colocar o
comando Insert, automaticamente já salva e já cria um novo
pedido.

procedure TFrm_Venda.Btn_NovopedidoClick(Sender: TObject);


82

begin
{deve chamar o evento de inserir pedido}
Tbl_Ped.Insert;
end;

11.8.2 - Botão Cancelar Pedido

A melhor maneira seria alterar o status do pedido para cancelado, para empresa
estimar o numero de pedidos cancelados.
A programação ficaria – Tbl_Ped.Edit; - Porque Edit? Você vai alterar o valor do
campo, se a tabela não estiver em modo de edição, vai dar erro. Aqui nós temos um campo
que armazena o Status. Procure o campo Status_Ped que é do tipo inteiro para fazer o
restante da programação.
Porem neste caso, será apenas deletado o pedido e seus respectivos itens.
procedure TFrm_Venda.Btn_CancelaPedidoClick(Sender: TObject);
begin
{Deletando o pedido junto aos seus itens
Posiciona a tabela no primeiro item
Enquanto a tabela não está no ultimo arquivo
Apaga o registro da tabela de item
Apaga o registro da tabela de pedido}
tbl_itens.First;
While not (tbl_itens.Eof) do
Tbl_itens.delete;
Tbl_pedido.delete;

end;

11.8.3 - Botão Inserir Produto

procedure TFrm_Venda.Btn_InserirItemClick(Sender: TObject);


begin
{ o mesmo evento é realizado ou apertar a seta para baixo
do teclado. Para fins de interface, foi colocado este
botão.}
TBL_itens.Insert;
end;

11.8.4 - Botão Excluir Produto

procedure TFrm_Venda.Btn_ExcluirItemClick(Sender: TObject);


begin
{para excluir um item na grid, podemos apertar ctrl + del.
como não é um comando trivial para o usuário, colocamos
um botão para excluir um item}
TBL_itens.Delete;
end;
83

Não tem programação tanto no Inserir como no


Deletar, não precisa fazer a filtragem, porque já está feita a
programação nos eventos BeforeInsert, After Insert, então é
possível colocar uma programação simples.

Até neste ponto terminou na verdade o pedido. A única coisa que ainda não ficou
pronto é o total que será feita depois. Conseguimos Inserir, Excluir. Na hora que busca o
produto, já aparece o valor, já calcula o total parcial. Se clicar para inserir um novo pedido, o
sistema verifica se ainda não salvou e salva para abrir um novo. Se digitar dado invalido, com
o Try...Except, o sistema avisa para digitar novamente. Está tudo filtrado.

Falta imprimir nota e gerar contas a receber. No Interbase ainda não tem a base de
notas e contas a receber.

Salve o Programa.

11.8.5 - Construindo a Base de Dados para gerar Nota e contas a receber.

Feche o Lazarus para entrar no Interbase.

Basicamente o Pedido já está pronto, agora já


entramos para a próxima fase.

Na tabela de pedidos adicionar o código da forma de pagamento:

Alter table tb_pedido add cod_formpag numeric (10,0);


84

11.8.6 - Criando a Tabela de Forma de Pagamento (Form_Pag).

Create table tb_form_pag


(
cod_formpag numeric (10, 0) not null,
descr_formpag varchar (30),
num_par_formpag numeric (5, 0),
data_prim_formpag numeric(5, 0),
interv_formpag numeric (5, 0),
juros_formpag numeric(6, 3),
primary key (cod_formpag)
);

As parcelas:

Imagine que o cliente escolha pagar em 3 vezes do tipo 30, 60 e 90 dias ou 60, 90 e
120 dias. As duas formas. A primeira forma com numero de 3 parcelas. Para calcular a data
da primeira parcela, a partir do dia de hoje a primeira data é somada mais trinta dias. A
segunda data soma sessenta dias a partir de hoje. Isso é um intervalo entre as parcelas. Entre
uma parcela e outra são trinta dias. Em cima disso tem os juros. Quanto de juros vai calcular
(a taxa de juros multiplicado pelo total e dividindo depois pelo numero de parcelas). Então o
que é necessário armazenar? Não é a data. A data da primeira parcela é o numero para guardar
a referencia. O intervalo é uma data que gravamos para saber o quanto vai colocar a mais em
cada uma das parcelas, e por último os juros.

Tem que fazer mais duas tabelas uma de Nota Fiscal e outra de Itens de Nota Fiscal.
O pedido não é nota. O pedido pode ser cancelado. Nota fiscal paga imposto e para cancelar
tem que ter a nota original.

11.8.7 - Criando a Tabela de Nota Fiscal

A nota fiscal tem dois campos: O numero da nota e o


numero de série. O numero de série serve para que a nota
não tenha um número gigantesco. Por exemplo: se você
quiser trocar um formulário de uma nota fiscal, é só trocar o
numero de série e reinicia a numeração.

Então a chave da nota será o numero e a série da nota.


85

Create table nota


(
num_nota numeric(10,0) not null,
serie_nota char (4) not null,
numero_ped numeric (10,0),
data_emi_nota date,
data_saída_nota date,
cfop_nota numeric (10,0),
total_nota numeric (10, 2),
obs_nota varchar (30),
primary key (num_nota,serie_nota)
);

CFOP – código fiscal de operação - toda operação fiscal tem um código (código de
entrada, código de transferência, etc.). Código que a receita cria, para fiscalização. Por
exemplo: se quiser transferir um estoque para outro lugar, tem-se que gerar uma nota de
transferência.

Existem mais campos na nota, quem vai transportar, a placa do carro que vai
transportar, a pessoa responsável pelo transporte, só que tem que gerar mais tabelas. Para o
exemplo é suficiente.

11.8.8 - Criando a tabela de Itens da nota

Quando usar uma impressora fiscal, temos que colocar um campo item, e na tabela de
produtos e tabela de nota fiscal, teremos que guardar o numero de serie da impressora fiscal e
o numero de nota, porque para cada impressora tem um numero de nota. É lacrado pela
receita inserindo o numero da nota. A chave quando se usa mais de uma impressora fiscal
é numero da nota mais o numero de série da impressora.

Como nosso exemplo só tem uma impressora então não usaremos o numero de serie
da impressora.

create table tb_itemnota


(
num_nota numeric (10,0) not null,
serie_nota char (4) not null,
cod_prod numeric (10,0) not null,
qtd_item numeric(10,0),
valor_item numeric(10,2),
primary key (num_nota,serie_nota,cod_prod)
);
86

12 - Nota Fiscal e Contas a Receber


.
A tabela de forma de pagamento para determinar quantas vezes uma determinada
compra vai ser paga. Isso interfere porque se for escolhido a forma de pagamento em
prestações tem que ser gerado o campo de contas a receber. Se escolher pagamento a vista
tem que gerar que a conta já foi paga.

As tabelas de Forma de Pagamento, Nota Fiscal e Itens da Nota, já foram criadas.

Temos a tabela de Nota Fiscal, mas esta faltando Gerar Contas a Receber, que no
momento não será criada, porque a prioridade é fazer a Nota Fiscal.

Foi feita a parte de salvar o Pedido e salvar Itens. Falta gerar a Nota, depois gerar
Contas a receber.

12.1 - Gerando a Nota Fiscal

Pegamos todos os dados da tabela de pedido e copiamos esses dados numa Nota
Fiscal. Para isso é preciso ter os componentes SimpleDataSet (as Tbls Form_Pag, ItensNota e
Nota).

12.2 - Adicionando os Componentes

Zeos Access > TZTable > adicionar três tabelas ao Form

Data Access> DataSource> Adicionar um Componente DataSource para cada Tabela,


com as seguintes propriedades:

Name Connection TableName AutoCalcFields CachedUpdates


Tbl_nota Frm_principal.z_conexao Tb_nota TRUE TRUE
Tbl_itens_nota Frm_principal.z_conexao Tb_itemnota TRUE TRUE
Tbl_form_pag Frm_principal.z_conexao Tb_form_pag TRUE TRUE

Agora mude as propriedades do DataSource para:

Name DataSet
DS_nota Tbl_nota
DS_ItensNota Tbl_itens_nota
DS_form_pag Tbl_form_pag
87

Figura 59 – Tabelas inseridas

Agora no evento onActive do formulário Vendas(frm_vendas) complete com a


seguinte programação:

procedure Tfrm_vendas.FormActivate(Sender: TObject);


begin
tbl_cli.open;
tbl_prod.Open;
tbl_ped.Open;
tbl_itens.Open;

tbl_nota.open;
tbl_itens_nota.open;
tbl_form_pag.open;

end;

Fazendo com que as tabelas sejam carregadas quando o formulário for chamado.

12.3 - Ligando as Tabelas

Ligar a tabela de Nota com a Tabela Itens da Nota. Da mesma forma que pedidos foi
ligado com itens do pedido, faremos aqui a mesma ligação Master/Detail.
88

A Nota também tem os Itens da Nota, é como se fosse um pedido. A tabela Nota é a
Máster.

Na tabela de Itens indicar o Máster da Tabela.

Clique na Tabela Itens da Nota (Tbl_ItensNota) e no OI mude as seguintes


propriedades:

MasterSource MasterFields LinkedFields


DS_Nota Num_Nota;Serie_Nota Num_Nota;Serie_Nota

Figura 60 – MasterSource Tabela Nota

Entre a tabela de Forma de Pagamento e a Tabela de Pedido. Você cadastra a Forma


de Pagamento ou escolhe uma Forma de Pagamento previamente Cadastrada? Você escolhe.
Então a ligação vai ser (DbLookUpComboBox).

Essa ligação é feita através da Tabela de Pedido para adicionar o LookUp...da Tabela
de Forma de Pagamento.
89

De duplo clique na Tabela de Pedidos depois clique com o botão direito do mouse e
escolha a opção New. Na janela que surgi escolha a opção lookup e de as seguintes
propriedades:

Figura 61 – Lookup Forma de pagamento

Clique em Ok.

Foi criada a Forma de Pagamento.

Agora na paleta Data Controls adicione o componente DBLookupComboBox e no OI


mude as seguintes propriedades:

DataSorce DataField ListSorce ListField KeyField


DS_PED Cod_formpag DS_PED Descr_formpag Cod_formpag

Agora o cliente tem como escolher a forma de pagamento, se a vista ou a prestação.

- Temos a ligação da Tabela de Forma de pagamento, já temos a tabela de Notas e


temos a ligação da Tabela de Itens de Nota.

- Agora temos que transportar os dados do pedido e copiar para a Nota e do itens da
Nota.

- Isso será feito no Botão de Confirmar Pedido.

12.4 – Programação

De duplo clique no Botão de Confirmar Pedido para entrar no modulo de


programação.

Foi criada a variável a AUXNOTA, dentro do Btn_ConfirmaPedido.


90

procedure TFrm_Venda.Btn_ConfirmaPedidoClick(Sender: TObject);

var

auxnota: integer;

Comentario
{inicia o processo para gerar a nota.
Basicamente, temos que copiar os dados da tabela de pedido e gravar na nota.

Algoritmo:

Posicionar no ultimo item da nota gravar o numero em um aux cria um novo re-
gistro para a nota gravar os dados gravar os items (atraves de um laco semelhante a
baixa)}

Criar um arquivo de configuração e pegar o último número da nota deste arquivo. Em


vez de ficar posicionando a tabela no último + um...último + um, o ideal é criar uma tabela
para fazer um único registro, que vai ter o número da última nota, último número de série e
último número do pedido, para não tem que ficar toda hora posicionando no último registro
para armazenar num campo auxiliar. Se tiver uma tabela você abre essa tabela, já grava mais
um lá dentro, já tendo o valor da última nota.

Imagine como ficaria um banco com cem mil registros. Toda vês que for inserir um
novo pedido, o algoritmo indicaria que tem que posicionar no último número para depois
incluir o próximo. Então, toda vez seria percorrida toda a tabela para inserir um novo pedido.

Por enquanto esta sendo usando o algoritmo por facilidade, mas ira ser criado uma
tabela de configuração, uma tabela que indicará os últimos números usados. Cada vez que
precisarmos de um número, iremos pesquisar nessa tabela para saber qual foi o último número
criado e indicar o próximo. O comentário acima é para esse propósito.

Como posicionar o último item na nota?

Criar uma variável chamada auxnota dentro do procedimento. Note que essa variável
é do tipo local, só funciona dentro desse procedimento para não ficar ocupando memória.

Cole a programação no final da programação do botão Confirmar Pedido

Tbl_Nota.Last;
auxnota:=Tbl_Nota.fieldbyname('num_nota').AsInteger;
Tbl_Nota.Insert; {Tbl_nota.Append;}
Tbl_Nota.FieldByName('num_nota').Asinteger:=auxnota + 1;
Tbl_Nota.FieldByName('serie_nota').Asstring:='A1';
Tbl_Nota.FieldByName('numero_ped').AsInteger:=
Tbl_Nota.fieldByname('ncod_ped').AsInteger;
Tbl_Nota.FieldByName('dat_emi_nota').AsDateTime:= now;
Tbl_Nota.FieldByName('data_saida_nota').AsDateTime:=now;
91

Tbl_Nota.FieldByName('cfop_nota').AsInteger:= 512;
{falta obs e total nota}
Tbl_Nota.Post;

O campo dfop_nota é para cada movimentação (vendas, transferência, etc) usada no


código de receita do governo. A programação abaixo é semelhante à baixa em estoque, então
cole a programação e depois mude os campos.

Tbl_Itens.First;
while not (TBL_Itens.Eof) do
begin
{não existe a necessidade do locate do produto, pois
como as tabelas de itens e produto estão conectadas
por um dblookupcombobox, isto é feito automaticamente}
Tbl_ItemNota.Append;
Tbl_ItemNota.FieldByName('Num_Nota').asinteger:=
Tbl_Nota.FieldByName('num_nota').AsInteger;
TBL_ItemNota.FieldByName('serie_nota').asstring:=
TBL_Nota.FieldByName('serie_nota').asstring;
Tbl_ItemNota.FieldByName('Cod_Prod').asinteger:=
Tbl_Nota.FieldByName('Cod_Prod').AsInteger;
TBL_ItemNota.FieldByName('qtd_item').asinteger:=
TBL_Nota.FieldByName('qtd_prod').asinteger;
Tbl_ItemNota.FieldByName('Valor_item').asfloat:=
Tbl_Nota.FieldByName('valor_prod').Asfloat;
Tbl_itemnota.Post;
TBL_itens.Next;
end;

Tbl_Nota.ApplyUpdates;
Tbl_ItemNota.ApplyUpdates;

end;

12.4.1 - Explicação da Programação:

Foi posicionada a tabela no último elemento, foi guardado numa variável o último
número da nota ,armazenando esse valor no número da nota. Um auto-incremental.

Tbl_Nota.Last;
auxnota:=Tbl_Nota.fieldbyname('num_nota').AsInteger;
Tbl_Nota.Insert; {Tbl_nota.Append;}
Tbl_Nota.FieldByName('num_nota').Asinteger:=auxnota + 1;

Por enquanto não está sendo feito no banco mas feito direto na programação do
Delphi.

Depois é armazenado o Número de Série da nota, que por enquanto não temos campo
de configuração.

Tbl_Nota.FieldByName('serie_nota').Asstring:='A1';
92

Também é armazenado o último número do Pedido (é associado a tabela de pedido


com a tabela de nota). Note que não foi preciso posicionar , porque a tabela de pedido já está
posicionada no último número, então basta copiar o código que aparece para dentro da tabela
Nota.

Tbl_Nota.FieldByName('numero_ped').AsInteger:=
Tbl_Nota.fieldByname('ncod_ped').AsInteger;

Temos que preencher a data emissão e a data de saída. Esse preenchimento é feito com
a data atual.

Tbl_Nota.FieldByName('dat_emi_nota').AsDateTime:= now;
Tbl_Nota.FieldByName('data_saida_nota').AsDateTime:=now;

Depois o código cfop que é o código do serviço que está sendo feito é armazenado no
campo cfop_nota da Tbl_Nota.

Tbl_Nota.FieldByName('cfop_nota').AsInteger:= 512;

Salva a nota.

Tbl_Nota.Post;

Salvar cada Item. Posicione a tabela de Itens no Inicio. Enquanto não for final da
tabela de Itens. Coloque Append. Esse Append é igual ao Insert – a única diferença é que
insere no final da tabela, para não ter que ficar percorrendo a tabela toda hora. O ideal para
fazer um sistema com velocidade é usar o Append e não o Insert.

Tbl_Itens.First;
while not (TBL_Itens.Eof) do
begin
Tbl_ItemNota.Append;

Salvar o Número da Nota, o Número de Série, o Código do Produto, a quantidade e o


valor na tabela de Itens (Tbl_ItemNota).

Tbl_ItemNota.FieldByName('Num_Nota').asinteger:=
Tbl_Nota.FieldByName('num_nota').AsInteger;

TBL_ItemNota.FieldByName('serie_nota').asstring:=
TBL_Nota.FieldByName('serie_nota').asstring;

Tbl_ItemNota.FieldByName('Cod_Prod').asinteger:=
Tbl_Nota.FieldByName('Cod_Prod').AsInteger;

TBL_ItemNota.FieldByName('qtd_item').asinteger:=
TBL_Nota.FieldByName('qtd_prod').asinteger;

Tbl_ItemNota.FieldByName('Valor_item').asfloat:=
Tbl_Nota.FieldByName('valor_prod').Asfloat;

Salvar a Tabela de Itens de Nota e ir para o próximo Item.


93

Tbl_itemnota.Post;
TBL_itens.Next;

O sistema fica nesse laço enquanto existir um item na Tabela de Itens.

Grave esses dados no sistema e salve os itens da nota.


Note que primeiro temos que salvar a Nota para depois salvar os Itens da Nota senão
dá erro de chave.

Tbl_Nota.ApplyUpdates;
Tbl_ItemNota.ApplyUpdates;

end;

12.5 - Criando a Nota Fiscal.

Alem do total da nota e observação, falta imprimir essa nota.

12.5.1 - Instalando componente LazReport(Relatório).

Primeiramente precisa ser instalo o LazReport para criação da Nota Fiscal.

O componente LazReport mesmo sendo um componente nativo do Lazarus não vem


instalado por padrão no programa, por isso antes de começar a desenvolver o seu relatório
deve se primeiramente instalar o componente como veremos agora.

Na barra de menus clicar em:

Package > Open package file (.lpk)... > Abrindo em seguida uma janela para se
localizar o componente.
94

Figura 62– Procurando Componente

Tendo como base que a instalação do programa foi feita no Windows e sem a
alteração dos parâmetros de diretórios, para localizar o componente “lazreport.lpk”, segue se
o caminho:

C: > lazarus > components > lazreport > source

Figura 63 – Procurando Componente


95

Após clicar no botão abrir será apresentado essa outra janela, que é a janela de
instalação de componentes do Lazarus.

Figura 64 – Instalando Componente

Ao clicar no botão Install( ), será exibida uma mensagem informando qual


componente esta sendo instalado e também uma informação dizendo que o Lazarus será
recompilado e também será reinicializado para a conclusão da instalação do componente.

Figura 65 – Confirmando Componente

Clique no botão YES, o progresso de instalação do componente será exibido.

Figura 66 – Processo de Instalação de Componente

Quando o processo estiver completo o Lazarus será reinicializado como informado na


mensagem e já estará disponível a aba LazReport.
96

12.5.2 – Programando os componentes

De acordo com o siste (http://professorcarlos.blogspot.com/2010/07/lazarus-mestre-


detalhe-lazreport.html) no formulário de Vendas(frm_vendas) adicione o componente
ReadyOnlyQuery que esta na paleta Zeos Access e mude para seguinte propriedades:

ReadyOnlyQuery Name SQL


1 ROQ_ped select Num_Nota, Serie_nota, Cod_prod, Qtd_item,
valor_item, desc_prod

FROM
tb_itemnota, tb_produtos

WHERE
tb_itemnota.cod_prod = tb_produtos.cod_prod

and tb_itemnota.num_nota = :num_nota


and tb_itemnota.serie_nota = :serie_nota

De um duplo clique no componente ReadOnlyQuery, no pequeno editor que ira


surgir clique com o botão direito dentro e escolha a opção Add Fields, ira surgir uma outra
janela contendo todas as variáveis, selecione tudo e clique no botão CREATE, ira voltar para
primeira janela, logo em seguida feche essa janela

Adicione também o componente DataSource e mude a seguinte propriedade:

Name DataSet
DS_Rqped ROQ_ped

Adicione os componente frReport e frDbDataSet que se encontra dentro da paleta


LazReport e mude seus propriedades para

frDBDataSet

Name DataSource
DBD_ped DS_Rqped

frReport

Name DataSet
Rel_ped DBD_ped

Agora de um duplo clique sobre o componente frReport para abrir o seu editor.
97

Figura 67 – Editor de relatório

Adicione uma banda e escolha a opção Page Header. Nessa banda adicione o texto
como mostra abaixo, atravez do botão Insert Retangle Object (Poderá digitar qualquer coisa
nessa banda):

Figura 68 – Editor de relatório com Dados inseridos

Insira nova banda e escolha o tipo Master Data. Ele vai abrir uma janela solicitando a
escolha de um DataSource. Escolha a opção DBD_ped como mostra a figura abaixo e clique
em OK.
98

Figura 69 – MasterData – Escolhendo o Data Source

Agora insira os texto Nome Endereço e Numero Nota, clicando no botão Insert Re-
tangle Object.

Quando cliclar, no botão Insert Retangle Object ira aparecer a seguinte janela

Figura 70 – Retangle Object

Clique no botão DB Field e escolha a opção tbl_cli, para que possa pegar todos os
componentes da tabela cliente
99

Figura 71 – Escolhendo campo da tabela Clientes

Faça a mesma coisa com o campo Endereço.

Agora para campo Numero da Nota clique no botão Insert Retangle Object logo em
seguida clique no botão DB Field, na área Available DB’s escolha a opção ROQ_ped e no
campo de baixo escolha a opção Num_Nota. Ficando da seguinte maneira

Figura 72 – Banda MasterData com os campos inseridos

Insira uma banda e escolha o tipo Detail Data. Escolha o DataSource DBD_ped.
100

Coloque os campos Num_nota, Num_Serie, Desc_prod, Qtd_item. Ficando da se-


guinte maneira:

Figura 73 – Banda DetailData com os campos inseridos

Insira nova banda e selecione o tipo Detail Footer. Escreva o texto Total Venda
e logo na frente insira um texto e na janela que surgiu clique em FUNCTION

Figura 74 – Insert Retangle Object


101

Novamente clique em FUNCTION

Figura 75 – Tela de expressão

Agora escolha o opção SUM

Figura 76 – Escolhendo a expressão SUM

Clique em OK.
102

Automaticamente ira cair na seguinte tela, no Argument 1 clique no quadro em ver-


melho:

Figura 77 – Especificando o argumento

Novamente ira cair na janela de exopresão clique no botão DBfield:

Figura 78 – Escolhendo o campoda tabela

Escolha a tabela tb_itens e o campo TOTAL .

Clique 3 vezes no botão OK, até que fique nessa janela:


103

Figura 79 – Expressão quase pronta

Para poder formatar o campo valor Total, em estilo moeda basta completar a formula
como a seguir

[SUM([tbl_itens"TOTAL"]) #N##,##0.00]

Esse campo somará o total da venda e o mostrará formatado.

Salve o relatório dentro da pasta “Vendas2/Relatório/” com o nome de Rel_nota.lrf.

O relatório pronto ficara na seguinte maneira:


104

Figura 80 – Relatório Pronto

No Formulário de Vendas colar a programação do botão criado e copie no final da


programação do botão Confirmar Pedido.

procedure TFrm_Venda.Btn_ConfirmaPedidoClick(Sender: TObject);


var auxnota:integer;
begin
-
// impressão da nota: passar o valor por parametro

Tbl_Nota.DataSet.ParamByName('nota').AsInteger:=
Tbl_Nota.fieldbyname('num_nota').AsInteger;
Tbl_Nota.DataSet.ParamByName('serie').Asstring:=
Tbl_Nota.fieldbyname('serie_nota').Asstring;
Tbl_Nota.Active:=true;
Tbl_ItensNota.Active:=true;

REl_ped.ShowReport; {qr_nota.Print}

end;

No evento OnCreate do formulário Vendas (frm_vendas) coloque a seguinte


programação:

procedure Tfrm_vendas.FormCreate(Sender: TObject);


begin
RP_Rel.LoadFromFile('relatorios\real_nota.lrf');
end;

Essa programação ira carregar o relatório toda vez que abrir o formulário vendas
105

12.6 - Configurações da Nota Fiscal

Pelo fato de estar filtrando o relatório por uma única nota especifica, essa listagem
imprime uma única nota.

Quando impressa uma nota fiscal, seu visual tem que ser de outra forma, teria que ter
neste visual só alguns campos, porque uma nota fiscal é pré-impressa – então na impressão,
vai preencher só os valores.

Como dividir igualmente os Itens em mais de uma nota fiscal quando a quantidade de
itens for maior que o campo? No programa do Lazarus tem que fazer uma modificação. Se no
pedido tiver dezesseis itens e na nota fiscal couberem somente treze itens, temos que dividir
essa nota fiscal em duas, senão o programa imprimirá os restantes dos itens fora da área. O
ideal nesta divisão da nota é ter metade dos itens em cada nota. Para implementar essa
condição, verifique o RecordCount (contador de itens) .

 Tbl_PedItens.RecordCount – retorna o numero dos itens do pedido.

Se esse valor for maior que o tamanho do formulário. Ex.: No formulário cabendo no
máximo treze itens, se esse valor for maior que 13, dividimos em mais de uma nota.

Para descobrir quantas notas são necessárias para impressão dos itens, temos que
dividir o total de itens da nota pelo campo (espaço da nota). Se a nota tem 13 espaços e os
itens são 20, dividimos 20 por 13 e descobrimos quantos formulários serão necessários.

Um pedido com 40 itens:

Algoritmo:

Se o numero de itens do pedido for maior que o espaço da nota, então: Numero
necessário de Formulários = Numero de Itens dividido pelo espaço (Arredondando para o
numero inteiro abaixo).

Coloque os itens no inicio de arquivo. Para i variando de 1 até o numero de


formulários.

A nota fiscal recebe Nota fiscal mais 1,


A serie recebe serie + 1,
-
-
-
Preenche a data.

Se após esses campos for colocado o comando Itens.First dentro do laço, nunca vai
terminar a primeira nota, então colocamos esse comando antes do laço for.

Agora temos que descobrir quantos itens serão colocados por nota. A condição para
impressão não vai ser feita enquanto não for final dos itens, mas sim até o final do numero de
106

notas. Se fosse um algoritmo que não dividisse nada então a nota seria impressa ate que os
itens fossem iguais a treze.

12.7 - Fazendo a Programação

Quando for impressa uma nota fiscal precisamos lembrar que nem sempre é possível
colocar todos os itens da nota, se isso acontecer temos que gerar mais de uma nota.

procedure TFrm_Venda.Btn_ConfirmaPedidoClick(Sender: TObject);


var
i, j, nin, auxnota:integer;
begin
-
-
-
{gerar um arquivo de configuração e pegar o ultimo numero da nota
deste arquivo}

Antes de sair imprimindo a nota, temos que lembrar que nem sempre é
possível colocar todos os itens na nota. Se isto acontecer temos que gerar
mais de uma notafiscal}

TBL_itens.First;
{NIN - numero de itens por nota}
NIN:= round(tbl_itens.RecordCount/(round(tbl_itens.RecordCount/13)));

Para os campos abaixo será feito um for variando de um até a quantidade de notas
necessárias. Os valores como data, código, pedido, serão os mesmos, mas os itens não podem
ser reinicializados, senão vai ser impressa duas notas com os mesmos itens – o Comando
Tbl_Itens.First tem que ser colocado antes do laço for.

{dividir em N notas}
for i:=1 to round(Tbl_itens.RecordCount/13) do
begin

Os campos abaixo foram retirados.


//Tbl_Nota.Last;
//auxnota:= Tbl_Nota.fieldbyname('num_nota').AsInteger;
//Tbl_Nota.Insert; {Tbl_nota.Append;}
//Tbl_Nota.fieldbyname('num_nota').AsInteger:=auxnota+1; }

Tbl_config.open;
Tbl_config.Edit;
Tbl_Config.Fieldbyname('numnota').Asinteger:=
Tbl_config.Fieldbyname('numnota').asinteger+1;
tbl_config.post;
Tbl_config.ApplyUpdates;
Tbl_Nota.Append;
Tbl_Nota.fieldbyname('num_nota').AsInteger:=
Tbl_config.Fieldbyname('numnota').asinteger;

Tbl_Nota.fieldbyname('serie_nota').Asstring:=
107

Tbl_config.fieldbyname('numserie').Asstring;
Tbl_config.close;

Tbl_Nota.fieldbyname('numero_ped').Asinteger:=
Tbl_ped.fieldbyname('cod_ped').AsInteger;

Tbl_Nota.fieldbyname('data_saida_nota').Asdatetime:=now;
Tbl_Nota.fieldbyname('cfop_nota').Asinteger:=512;
{falta obs e total nota}
Tbl_Nota.Post;

{TBL_itens.First;} foi colocado antes do FOR acima

O comando While abaixo não vai ser executado até chegar o final de arquivo, mas
vamos ter que imprimir até chegar na metade dos itens.

{while not (TBL_itens.Eof) do} foi retirado para dar


lugar ao comando for
108

Se tiver por exemplo quinze itens teria dois algoritmos possíveis: itens divididos
igualmente em mais de um formulário e outro quando chegar no final de campo, começa
outro formulário (nota).

Explicação:

Para um formulário para 13 itens. Como implementar a impressão para dividir meio a
meio? Temos que saber quantos itens serão impressos por nota. Pode-se criar uma variável
NIN(número de itens por nota).

O NIN (Numero de itens por nota) é o total de itens dividido pelo campo desta nota,
arredondado para um numero inteiro)

Tbl_Itens.First;
J=0;
NIN:= round(Tbl_Itens.RecordCount/(round(Tbl_Itens.RecordCount/13))),
-
-
-
While J mod NIN <> 0
a) quando for 8 itnes – 1 nota.
J mod Nim <> 0  8/13 = 0.62  8 mod 13 = 1
b) 9 itens – 1 nota
c) 13 itens – 1 nota
d) 16 itens – 2 notas tendo 8 itens cada
e) 17 itens – 2 notas – uma com 9 e outra com 8 itens.
J mod NIN <> 0  17/13 = 1,31  duas notas

Para os itens em cada nota  17/2 = 8,5 itens – arredondado para 9.

Para arredondar esse item tem que ter um comando round

NIN:= round(Tbl_Itens.RecordCount/(round(Tbl_Itens.RecordCount/13))),

A primeira ficará com nove itens e depois fara um tratamento para a segunda.

Se J começar por zero nem entra no laço J = 1;

Até chegar ao oitavo item será impresso o item na nota.

J recebe mais 1. ( contador)


Mas para o comando – While J mod NIN <> 0 – quando chegar no nono item o co-
mando interpretará que é igual a zero, então não fará a inclusão do nono item.

J Mod NIN <> 0  9 mod 9 <> 0 – não é verdadeiro, então o comando não ira ser
executado e o item 9 não será incluído.
109

Se for deixada essa condição, na hora que imprimir o oitavo item, fecha a nota, ai co-
meça a próxima começando do 10º item até o 17, imprime até o 16º item e fecha a segunda
nota – Faltou um item.

Neste algoritmo falta fazer com que o NIN vá até o décimo item - ao invés do laço
comparar com o nono item, irá ser comparado com o décimo, então o item 9 será impresso.
While J mod (NIN + 1) <> 0  Para contar até 9 quando os itens forem 13.

Na hora que chegar no décimo item, faz a comparação e sai do laço, começando tudo
de novo a partir do décimo item. O valor de J neste ponto é 10.

Na primeira nota a impressão for normal, mas no momento que entra no laço nova-
mente e faz a comparação com 10 – sendo a condição falsa – não imprimirá a segunda nota.
Criamos outro problema.

A conclusão é que o comando While para este caso não funciona, não é a solução.

Pode-se usar dois comandos – o Repeat ... Until, ou o For...do.

As diferenças entre esses comandos:

O comando While faz a comparação antes de executar.


O comando Repeat, executa o primeiro laço para depois fazer a comparação.
O comando For, entra obrigatoriamente no laço.

12.7.1 - Usando o For...do

Tbl_Itens.First;
J = 0;
NIN:= round(Tbl_Itens.record.count/(round(Tbl_Itens.recordcount/13)))
-
-
-
for j:= 1 to NIN do
if not (Tbl_Itens.Eof) then
Begin
Tbl_Nota.Item.Insert;
-
-
Tbl_Nota.Item.Post;
Tbl_Itens.Next;
End;
End;

Antes do laço, a tabela Tbl_Itens foi colocada em sua primeira posição. Após o ultimo
laço executado, os itens não serão impressos de novo. Isso dará a condição de ser impressa a
segunda nota continuando dos itens ainda não impressos na nota.
110

Para implementar o programa, declare as variáveis i, j, nin, no inicio do


procedimento

A linha de comando While not(Tbl_itens.Eof) do, dará lugar às duas linhas do


comando abaixo:

{imprimir os itens por nota}


for j:= 1 to NIN do
if not (Tbl_Itens.Eof) then

begin
{não existe a necessidade do locate do produto, pois como as tabelas
de itens e produto
estão conectadas por um dblookupcombobox, isto é feito
automaticamente}

Tbl_ItensNota.Append;
Tbl_ItensNota.FieldByName('Num_Nota').asinteger:=
Tbl_Nota.FieldbyName('num_nota').AsInteger;

Tbl_ItensNota.FieldByName('serie_nota').asstring:=
Tbl_Nota.fieldbyname('serie_nota').Asstring;

Tbl_ItensNota.FieldByName('Cod_Prod').asinteger:=
Tbl_Itens.FieldByName('Cod_Prod').asinteger;

Tbl_ItensNota.FieldByName('Qtd_item').asinteger:=
Tbl_Itens.FieldByName('Qtd_Prod').asinteger;

Tbl_ItensNota.FieldByName('valor_Item').asfloat:=
Tbl_Itens.FieldByName('valor_prod').asfloat;

TBL_itensnota.Post;
TBL_itens.Next;
end;

Depois que foram copiados os valores, salva esses valores, o comando ApplyUpdates,
continua na mesma posição. Depois que são geradas as notas, elas são salvas no Banco.

Tbl_ItensNota.ApplyUpdates(0);

Depois essas notas são impressas. A diferença agora é que a impressão era feita depois
que tinham sido gerada as duas notas. Agora tem um end no final. Esse end é do primeiro
comando for (que da a condição de verificar a quantidade de notas que são necessárias). É
gerada a primeira nota e impressa, depois gera a segunda nota, depois imprime.

// impressão da nota: passar o valor por parametro

Tbl_Nota.DataSet.ParamByName('nota').AsInteger:=
Tbl_Nota.fieldbyname('num_nota').AsInteger;
Tbl_Nota.DataSet.ParamByName('serie').Asstring:=
Tbl_Nota.fieldbyname('serie_nota').Asstring;
Tbl_Nota.Active:=true;
111

Tbl_ItensNota.Active:=true;
Rel_ped.ShowReport;

end; {for i - o primeiro for}

end;

12.8 - Criando a Tabela de Configuração

{gerar um arquivo de configuração e pegar o ultimo numero da nota deste arquivo}

Teoricamente deve-se ter um arquivo de configurações, este arquivo armazenaria a


ultima nota, o ultimo pedido, numero de serie – Toda vez que tem que usar uma nova nota,
neste arquivo teremos condições de encontrar o ultimo numero usado.

A vantagem é se tivermos que mudar uma numeração de nota, entra-se neste arquivo e
muda-se, não tendo que alterar o programa fonte inteiro. Se tiver uma impressora fiscal,
moeda, alguma configuração do sistema (por exemplo: numero de páginas de nota fiscal)
pode-se colocar nesta tabela. O próprio Path do arquivo poderia estar dentro desta tabela.

Note que não tem chave primaria, porque esse arquivo de configuração só tem uma
única linha

Abrir o Interbase e criar a Tabela

Create table tb_config


(
-
-
-
)

Execute para criar a tabela

Agora temos a tabela de configuração, falta incrementar e a forma de pagamento do


total. Para aparecer a tabela (atualizar).

Entre no Form Principal.

Componente TZConnection > Propriedades > Connect = False - depois Connnect


= True para atualizar o Banco de Dados porque tem um nova tabela.

Voltar no Formulário de Vendas e Adicione mais uma Tabela - Componente TZTable


e mude as propriedades para:

Name Connection TableName


Tbl_Config frm_principal.z_conexao Tb_config
112

Deixar em Active = False

Não há necessidade do componente DataSource porque os valores serão pela


programação, os dados não serão apresentados em nenhum componente interno, não estará
ligado a um MasterSourse ou MasterField.

Programação:

Tbl_config.open;
Tbl_config.Edit;
Tbl_Config.Fieldbyname('numnota').Asinteger:=
Tbl_config.Fieldbyname('numnota').asinteger+1;
tbl_config.post;
Tbl_config.ApplyUpdates;

Tbl_Nota.Append;
Tbl_Nota.fieldbyname('num_nota').AsInteger:=
Tbl_config.Fieldbyname('numnota').asinteger;

Tbl_Nota.fieldbyname('serie_nota').Asstring:=
Tbl_config.fieldbyname('numserie').Asstring;
Tbl_config.close;

Abrindo a tabela – sempre vai estar posicionada no ultimo registro que existe.
Tbl_config.open;

Antes de mais nada, somar no último número da nota mais um, para já incrementar o
valor da nota.

Salva a tabela e com o comando ApplyUpdate atualiza o Banco de Dados, para


quando for utilizado novamente já estar disponivel.

Tbl_Config.Fieldbyname('numnota').Asinteger:=
Tbl_Config.Fieldbyname('numnota').asinteger+1;
Tbl_Config.post;
Tbl_Config.ApplyUpdates;

Faz o comando Append que é o insert da tabela de nota. Tbl_Nota.Append;

Insere o numero da nota, copia o valor, copia o numero de série depois fecha a tabela.

Tbl_Nota.fieldbyname('num_nota').AsInteger:=
Tbl_config.Fieldbyname('numnota').asinteger;
Tbl_Nota.fieldbyname('serie_nota').Asstring:=
Tbl_config.fieldbyname('numserie').Asstring;
Tbl_config.close;

Cada vez que o programa for executado o sistema abre a tabela, porque enquanto
estiver rodando a primeira nota, outra pessoa pode imprimir outra nota também. Gerar uma
após a outra.

Falta criar a Forma de Pagamento e o Total da Nota.


113

12.9 -A forma de Pagamento

Em nenhum lugar esta armazenando a forma de pagamento, então tem que criar um
formulário (tela) forma de pagamento. O Banco já existe, então crie o Formulário.

File > New Form e de as seguintes propriedades

Name Caption
Frm_formpag Forma de Pagamento

Salve esse formulário na pasta Vendas2/Formulários com o nome u_formpag.

Adicione um componente TZTable dentro da paleta Zeos Access e mude suas


seguinte propriedades:

Connection Name TableName


frm_principal.z_conexao Tbl_formpag Tb_config

Adicione um componente DataSource que esta dentro da paleta Data Controls e


mude as propriedades para:

Connection Name TableName


frm_principal.z_conexao Tbl_formpag Tb_config

Para cada campo do banco de dados insira um DBEdit como feito nos projetos
anteriores e também adicione os Labels para poder especificar cada campo

Figura 81 – Tela Forma de pagamento

O campo Forma de Pagamento do formulário de Vendas ao Cliente é uma


dbLookUpComboBox que recupera os dados da Tabela Forma de Pagamento e insere no
114

Pedido. Este campo é um Combo porque só vai fazer consultas na Tela Forma de Pagamento.
A Forma de Pagamento foi criada em outra tela.

Depois que gerar a nota, falta gerar contas a receber. O próximo passo é fazer um
comando for ou While variando de 1 até o número de parcelas. O numero de parcelas está
cadastrado na tabela Forma de Pagamento, então para fazer um comando for ou While
variando de um até o numero de parcelas, pegamos o total da nota e dividi pelo numero de
parcelas.

Primeiramente é precisso criar algumas rotinas auxiliares, pois se não poderá dar
alguns problemas.

Um problema: Se um valor de R$ 100,00 for dividido em 3 parcelas - dará R$


33,33333. Então pode-se fazer que as parcelas sejam apenas R$ 33,33 – no total dará R$
99,99 – estão se perde R$ 0,01 por venda. Por exemplo: pode-se ter em um supermercado
aproximadamente 300 vendas por hora, funcionando umas dez horas por dia, são 3.000
vendas e cada venda perde um centavo – serão 3.000 centavos por dia, no total serão R$ 30,00
de prejuízo por dia.

É preciso fazer uma função que some um centavo na primeira nota, se houver esse
centavo. Quando for R$ 99,00 dividido por 3 parcelas, dará R$ 33,00 em cada parcela. Mas se
for R$ 100,00 dividido por 3 parcelas, terá que gerar uma parcela de R$ 33,34 e as demais
parcelas de R$ 33,33, então sempre terá que arredondar esse um centavo em alguma das
parcelas.

12.10 - A Programação

Os campos em com o fundo CINZA foram acrescentados.

procedure TFrm_Venda.Btn_ConfirmaPedidoClick(Sender: TObject);


var
i,j,nin,auxnota:integer;
begin
{o botão de confirmar, executa uma série de rotinas:
- salvar o pedido
- salvar o item
- Baixar o estoque
- Imprimir a nota
- Gerar o contas a receber }

{perguntar se deseja salvar o pedido (confirmar)}


Tbl_Ped.Edit;
Tbl_Ped.FieldByName('status_ped').asinteger:=2; {confirmado}
Tbl_Ped.Post ;
if TBL_itens.State in [dsedit,dsinsert] then
Tbl_Itens.Post;
{baixa no estoque - algoritmo:

posicionar no primeiro item desta venda.


enquanto não for final dos itens
115

busco o produto
qtd_prod = qtd_prod - qtd_itens
ir para o proximo item
fim enquanto}

TBL_itens.First;
{quando executamos o first na tabela de itens, estamos posicionando
o ponteiro no primeiro item deste pedido (e não da tabela inteira)
devido ao relacionamento master/detail }
while not (TBL_itens.Eof) do
begin
{não existe a necessidade do locate do produto, pois
como as tabelas de itens e produto estão conectadas
por um dblookupcombobox, isto é feito automaticamente}
Tbl_Prod.Edit;
TBL_Prod.FieldByName('qtd_prod').asinteger :=
TBL_Prod.FieldByName('qtd_prod').asinteger -
TBL_itens.FieldByName('qtd_prod').asinteger ;
Tbl_Prod.Post;
TBL_itens.Next;
end;
{inicia o processo para gerar a nota.
Basicamente, temos que copiar os dados da tabela de pedido e gravar na
nota.

Algoritmo:

Posicionar no ultimo item da nota


gravar o numero em um aux
cria um novo registro para a nota
gravar os dados
gravar os itens (através de um laço semelhante a baixa)}

{gerar um arquivo de configuração e pegar o ultimo numero


da nota deste arquivo}

{- antes de sair imprimindo a nota, temos que lembrar que nem sempre é
possivel colocar todos os itens na nota.Se isto acontecer temos que gerar
mais de uma nota fiscal}
TBL_itens.First;
{NIN - numero de itens por nota}
NIN:= round(tbl_itens.RecordCount/
(round(tbl_itens.RecordCount/13)));
{dividir em N notas}
for i:=1 to round(Tbl_itens.RecordCount/13) do
begin
Tbl_Config.open;
Tbl_Config.Edit;
Tbl_Config.Fieldbyname('numnota').Asinteger:=
Tbl_Config.Fieldbyname('numnota').asinteger+1;
Tbl_Config.post;
Tbl_Config.ApplyUpdates;
Tbl_Nota.Append;
Tbl_Nota.fieldbyname('num_nota').AsInteger:=
Tbl_Config.Fieldbyname('numnota').asinteger;
Tbl_Nota.fieldbyname('serie_nota').Asstring:=
Tbl_Config.fieldbyname('numserie').Asstring;
Tbl_config.close;
116

Tbl_Nota.fieldbyname('numero_ped').Asinteger:=
Tbl_ped.fieldbyname('cod_ped').AsInteger;

Tbl_Nota.fieldbyname('data_saida_nota').Asdatetime:=now;
Tbl_Nota.fieldbyname('cfop_nota').Asinteger:=512;
{falta obs e total nota}
Tbl_Nota.Post;

{TBL_itens.First;} // foi colocado antes do for acima


{while not (TBL_itens.Eof) do} //foi retirado para dar lugar ao
comando for abaixo:

{imprimir os itens por nota}


for j:= 1 to NIN do
if not (Tbl_Itens.Eof) then
begin
{não existe a necessidade do locate do produto, pois
como as tabelas de itens e produto estão conectadas
por um dblookupcombobox, isto é feito automaticamente}
Tbl_ItensNota.Append;
Tbl_ItensNota.FieldByName('Num_Nota').asinteger:=
Tbl_Nota.fieldbyname('num_nota').AsInteger;

Tbl_ItensNota.FieldByName('serie_nota').asstring:=
Tbl_Nota.fieldbyname('serie_nota').Asstring;

Tbl_ItensNota.FieldByName('Cod_Prod').asinteger:=
Tbl_Itens.FieldByName('Cod_Prod').asinteger;

Tbl_ItensNota.FieldByName('Qtd_item').asinteger:=
Tbl_Itens.FieldByName('Qtd_Prod').asinteger;

Tbl_ItensNota.FieldByName('valor_Item').asfloat:=
Tbl_Itens.FieldByName('valor_prod').asfloat;

TBL_itensnota.Post;
TBL_itens.Next;
end;

Tbl_Nota.ApplyUpdates(0);
Tbl_ItensNota.ApplyUpdates(0);

// impressão da nota: passar o valor por parametro

Tbl_Nota.DataSet.ParamByName('nota').AsInteger:=
Tbl_Nota.fieldbyname('num_nota').AsInteger;
Tbl_Nota.DataSet.ParamByName('serie').Asstring:=
Tbl_Nota.fieldbyname('serie_nota').Asstring;
Tbl_Nota.Active:=true;
Tbl_ItensNota.Active:=true;
Rel_ped.Showreport;
end; {for i - o primeiro for}
end;
117

No Evento OnActive não se esqueça de colocar a


programação para ligar a tabela (tbl_formpag.open;)
118

13 - O CÁLCULO DO TOTAL DO PEDIDO

Antes de gerar contas a receber tem que programar o total, para quando for inserindo
itens já aparece o total na conta do cliente.

Adicione um componente Edit (Categoria Standard) na parte de baixo do formulário


Vendas para mostrar o total. O Edit é padrão para nossa entrada de Dados e coloque as se-
guinte propriedades:

Name Fonte Color Text


Edt_Total size tamanho 14 Cinza Deixe sem nada

Adiciona também um Label.

Caption
Total

13.1 - Maneiras de calcular o total

Existem três maneiras de calcular o total

Primeira solução:

No evento AfterPost da tabela de Itens - Cada vez que um item for inserido e salvo -
após o post (salvar) fazemos um for do primeiro até o último item (for i variando de 1 até
recordcount) O total recebe qtde X valor n vezes até descobrir o total geral. Para fazer essa
forma só podemos usar um Edit comum para atribuir o valor.

Segunda Solução:

Ou criar mais uma tabela com SQL e toda vez que for feita alguma coisa, vamos nesta
tabela e fazemos um Refresh nesta tabela e teremos o total na hora.

Para testar será utilizado os dois tipos de programações e depois é so escolher uma.

A primeira Solução:

Edit – paleta Stantard

Name Fonte Color Text


Edt_Total size tamanho 14 Cinza Deixe sem nada

Label - paleta Stantard

Caption
119

Total

A segunda Solução

Name Fonte Color


Edt_Total2 size tamanho 12 Amarelo

Figura 82 – Calculado o Total

13.2 - Programação:

Clique na Tabela de Itens e no Obect Inspector > Eventos > After Post.

Após um Post. Após salvar um item fazemos a contagem do total. Porque após um Post?
Porque tem que ter certeza que o item já foi salvo. Se fizer a programação no evento before
post (antes de salvar) o programa fará a conta mas não tem o item ainda salvo. Então essa
conta ficará errada. Só pode fazer a conta depois de salvar
.
Depois que o pedido foi feito, o item foi salvo, foi percorrido toda a tabela e gravamos no
total.
120

13.2.1 - A programação no evento After Post:

Declare a variavel aux do tipo local, para não ficar ocupando espaço na memória, ela
será usada na programação.

procedure TFrm_Venda.TBL_itensAfterPost(DataSet: TDataSet);


var aux:real;
begin
{o mesmo evento é usado na tabela de pedidos, no evento
afterscroll (apos posicionar o registro)}
{neste evento iremos programar o total do pedido.
o algoritimo é o seguinte:
1) apos salvar o item, posicionar a tabela de itens no
primeiro registro.

Depois que estiver no primeiro registro, já foi possionado no primeiro item. Imagine
que uma tabela tenha dez mil itens e existe um pedido com dez itens e é o décimo produto que
esta sendo passado, após salvar, volta no primeiro item, percorre a tabela inteira dos dez itens
gravados e totaliza numa variável auxiliar e no final, apresenta o valor da variável auxiliar no
Edit Total da tela.

2)criar um laço para percorrer a tabela.


3) aux = aux + total do item
4) no final, atribuir o conteudo de aux no edit.
}

Esse algoritmo lembra o algoritmo da baixa em estoque, portanto são todos parecidos.

If tbl_Itens.State in [dsBrowse, dsEdit, dsInsert] then


Begin

Não é necessário fazer aux receber o zero. Quando foi criado a variavel aux, por
padrão no Pascal, é criada uma variável zerada, quando numeric e string. Na linguagem C
tería que fazer obrigatoriamente uma variável zerada, porque vem lixo dentro.

aux:=0;
TBL_itens.First; {o First vai para o primeiro registro}

Existe uma lista de pedido, então posiciona no primeiro registro, enquanto não for
final de arquivo, vai somando no total. Se tiver um pedido com muitos itens seria usado o
método com SQL que é mais rápido. Enquanto não chegar no final de arquivo na tabela de
itens, carrega o auxiliar aux. Aux recebe aux + valor do total.

while not (tbl_itens.Eof) do


begin
aux:=aux+ Tbl_itens.FieldByName('total').asfloat;
Tbl_Itens.Next;
end;
121

Esta pegando o total e armazenando na variável aux. No final do comando While, note
que esta fazendo a programação fora do laço se faz a programação abaixo:

O Edit_Total.Text recebe o conteúdo da variável aux. O tipo da variável aux é real,


então tem que converter para string, porque todo texto é uma string.

Convertemos então de float para str.

edt_total.Text:=formatfloat('R$ #,##0.00',aux);
end;
{ou}
{ Tbl_Itens.ApplyUpdates;
Tbl_Total.Close;
Tbl_Total.Open;
}
end;

Ao executar a compilação, o programa não mostra nada, porque só vai executar o


calculo, quando incluir um item. Tem que salvar um item ou alterar um valor.
Obrigatoriamente tem que ter uma modificação. Tem que fazer a programação em um único
local. Tem que fazer a mesma coisa após a navegação.

13.4 - Executando o programa:

O Calcula está sendo executado corretamente, mas só depois que alteramos algum
valor ou inserimos um novo item. Para alterar isso, tem que fazer a mesma programação
quando for mostrar o sistema.

A programação em si, funciona, mas falta mais um local para programar, quando abre
o formulário, quando aparece o pedido.O evento depois que o pedido aparece é o evento After
Scroll (após navegar). Após o pedido aparecer usa-se a tabela de pedidos.

A programação não é feita dentro do After Scroll. Faremos um teste:

No Evento After Scroll da tabela de pedidos(tbl_ped) NÃO de duplo clique na parte


branca do evento. Clique na Combo do evento After Scroll > procure Tbl_ItensAfterPost e
selecione
122

Figura 83 –Escolhendo o Evento AfterScroll

Esse propriedade vai executar a mesma coisa antes de chegar no final. A vantagem é
que se for feita a programação uma única vez e se precisar efetuar alguma alteração é feita
nesta propriedade e essa alteração também é efetuada nos dois eventos.
Coloque essa observação no começo da programação acima após o begin:

{o mesmo evento é usado na tabela de pedidos, no evento afterscroll (apos


posicionar o registro)}

Executando o Programa novamente:

Se ao tentar executar o programa e der uma mensagem de erro , dizendo que não se
pode executar uma operação com o banco de dados fechado, faça o seguinte:

O nosso sistema esta no evento Open da tabela pedido.

Fazendo uma linha do tempo tem o primeiro evento Open da Tabela de pedido. Esse
evento abre a tabela de pedido, depois abre a Tabela de Itens e assim por diante. O que
acontece? Quando abrir a tabela, antes de tudo, posicione no primeiro registro, fazendo o
123

evento Scroll. O que acontece é que temos o comando Tbl_itens.First, só que a tabela de
itens no tempo ainda não foi aberta. Por isso dá o erro de tabela fechada.

Para corrigir esse problema, tem que efetuar um tratamento para verificar se a tabela
de itens foi aberta ou não. Só pode executar esse algoritmo se a tabela de itens estiver aberta.
Para verificar se a tabela já está aberta coloca a linha de comando abaixo, antes de colocar a
tabela de itens no primeiro registro.

Esta programação já está colocada acima.

Toda essa programação vai existir se o status ds... for verdadeiro

If tbl_Itens.State in [dsBrowse, dsEdit, dsInsert] then

A tabela não estando em modo Insert, se não tiver nenhum desses status a tabela não
está aberta, não esta navegando, nem inserindo e nem editando, quer dizer que ela esta ou
inativa ou ainda está abrindo. Pode-se usa-la só depois que estiver aberta. Então pode tentar
estes três valores ou colocar um “not” (se a tabela não está abrindo ou inativa). É mais fácil
colocar: Se o status estiver em navegando (dsBrowser), editando(dsEdit) ou
inserindo(dsInsert), então o sistema fará alguma coisa.

Teste o programa!

Porque não mostrou o item se foi feita a programação? Porque não chamou esse
evento. Quando abriu a tabela o sistema posicionou no primeiro registro e não navegou para o
último. Então quando a tabela abriu, posicionou-se no primeiro registro e a tabela e a tabela
de itens não estava aberta ainda. Só que não foi para o último registro porque não tem
comando para fazer isso.
124

Exemplificando: Imagine um carro, quando damos a partida, engatamos a primeira


marcha e saímos andando, então podemos deslocar o carro depois que a primeira marcha
estiver engatada.

A rotina é: liga a chave (open na tabela). Ligou a tabela.

- Na hora que ligou, foi conferida a tabela, estava engatada? Ainda não, então não anda.
Em algum lugar oi mencionado que tinha que engatar a primeira, trocar de marcha, fa-
zer um force ou retry na tabela.

- Em nenhum momento foi engatada a marcha, foi dada a partida, não mandamos a ta-
bela para nenhum registro (não engatamos a marcha) então não da para sair andando.

- Falta algum passo para sais andando. Se o carro vai andar, temos que dar partida e de-
pois engatar. O que é engatar? É selecionar o que queremos fazer, sair na primeira,
engatar a segunda, terceira, quarta...

- O que isso representa em nosso exemplo? Os registros, temos que mandar a execução
para algum registro, para o primeiro, anterior ou próximo.

No caso de uma venda, quando abrirmos o sistema, o registro iria para a última venda.
Ao trazer o formulário, deveria mostrar a última venda, a partir dali, conseguimos colocar
novas vendas.

Não adianta mostrar a primeira venda. O interessante é mostrar a última venda. Então
ao abrir o formulário posicione na última venda.

 Abra o formulário de vendas.


 Clique uma única vez no formulário.
 No Object Inspector > Events > OnActivate (ao ativar/mostrar o formulário) >
entre no modo de programação clicando duas vezes neste evento.

Programação:
Quando mostrar o formulário na tela, jogo a tabela no último registro.

Ao Ativar o formulário, posicionar no último pedido.

procedure Tfrm_vendas.FormActivate(Sender: TObject);


begin
Tbl_Ped.Last;

tbl_cli.open;
tbl_prod.Open;
tbl_ped.Open;
tbl_itens.Open;

tbl_nota.open;
tbl_itens_nota.open;
tbl_form_pag.open;
end;
125

Execute o programa.

Ao fazer a operação de vendas, agora faz o calculo certo.

13.5 - Para colocar mascaras

Apague o componente Edit (Edt_total) e adicione o componente MaskEdit no lugar,


que se encontra dentro da paleata Additional. É igual ao outro, a diferença é que tem a
mascara.

Name
Edt_total

Na propriedade procure o EditMask e clique nos três pontinhos para entrar no Modulo de
Editor e deixe como mostra a figura abaixo:

Figura 84 – Editor de Mascara

Se não der para configurar o EditMask então cancele a operação.

Faça o formato na programação do evento AfterPost da Tbl_Itens, onde atribuímos o


total.

Coloque a seguinte programação:

edt_total.Text:=formatfloat('R$ #,##0.00',aux);
126

A vírgula deve ser colocaga obrigatoriamente representar


os centavos.

O formulário de pedidos agora já está completo.


127

14 - COMPARATIVO LAZARUS x DELPHI

Necessidade de salvar o projeto antes da compilação

Lazarus: não é possível executar o projeto antes de salvar, primeiramente tem que sal-
var o projeto para que possa ser executado,

Delphi: pode-se executar sem a necessidade de salvar;

Especificação dos diretórios que terão conteúdo do projeto;

Lazarus: Quando for salvo as units em pasta diferente é necessário especificar o diretó-
rio dessas units

Delphi: Não é preciso especificar o diretório, pois o mesmo reconhece as units;

Velocidade da compilação do projeto;

Lazarus: a compilação(execução) do projeto é muito demorada devido a vinculação


das units.

Delphi: se torna mas rápido;

Ligação do banco de dados;

Lazarus: É mais complicado, pois suas propriedades são feitas atravez do objectoIns-
pector e precisa-se de um outro compoenente (Transaction) para fazer a comunicação entre o
projeto e arquivo fisico

Delphi: Apenas um componente basta para fazer a ligação entre o projeto e o arquivo
físico;

Dificuldade ao utilizar campos de uma tabela nos formulários

Lazarus: não existe a opção de selecionar todos os campos da tabela e arrastar para
dentro do formulário, adicionando assim todos os campos da tabela no formulário, o único
modo é fazer um a um.

Delphi: existem duas opções para se os campos: 1º - Selecionar todos os campos da


tabela desejada e arrastar para dentro do formulário; ou 2º - Fazendo um a um (como o Laza-
rus);

Criação da barra de ferramentas

Lazarus: Apenas um componente adicionado no formulário (ToolBar), já é suficiende


para se fazer uma barra de ferramentas contendo botões, separadores.
128

Delphi: Precisa-se de dois componente, o primeiro (CoolBar) que cria o espaço onde a
barra d e ferramentas ira ficar, o segundo (ToolBar) é a barra de ferramenta;

Complexidade ao utilizar use unit

Lazarus: Para que se possa chamar uma outra tela, é necessário programar no próprio
código fonte, tornando assim um pouco mais complexo.

Delphi: pode-se ir no menu File, ou na programação para chamar o outro formulário o


Delphi nos pergunta se quer criar a uses unit desse formulário, tornando assim mais fácil;

Praticidade da ferramenta geração de relatórios;

Lazarus: Muito mas fácil, pois tudo que será utilizado na criação de relatório esta em
um único lugar

Delphi: Torna-se mais complicado, pois cada componente que precisa-se esta em luga-
res diferentes, fazendo assim que sua atenção redobre;

Falta de assistenéte de criação de gráficos.

Lazarus: É possível criar um gráfico, mas muito complicado, pois todas as suas pro-
priedades tem que ser programada no ObjectInspector

Delphi: Existe um assiste que facilita e muito na criação de gráficos.

Tamanho do executável (EXE)

Lazarus: Apesar do EXE ser maior que o do Delphi, não precisa de outras bibliotecas
instalado na maquina que vai rodar o EXE.

Delphi: Necessita de alguns aquivos extras


129

15 - REFERÊNCIAS BIBLIOGRÁFICAS

Sites:

http://blog.silvioprog.com.br/
DATA: Ultimo acesso em novembrode 2010

http://dicas4lazarus.blogspot.com/2010/03/fortes-report-for-lazarus-vs-0358.html
DATA: Ultimo acesso em novembro de 2010

http://lazarusbrasil.forumeiros.com/
DATA: Ultimo acesso em novembrode 2010

http://professorcarlos.blogspot.com/2010/02/lazarus-acessando-banco-de-dados-
com.html
DATA: Ultimo acesso em outubro de 2010

http://wiki.freepascal.org/SQLdb_Package
DATA: Ultimo acesso em outubro de 2010

http://www.baixaki.com.br/download/lazarus.htm
DATA: Ultimo acesso em outubro de 2010

Apostila:
Apostila Delphi 2 - DESENVOLVIMENTO DE APLICAÇÕES COMERCIAIS
130

16 - CONCLUSÃO

De acordo o conteúdo apresentado neste projeto, fica claro que o Lazarus pode ser
considerado uma poderosa ferramenta de desenvolvimento, e que através dele, é possível
executar a matéria implementada pelo professor Renato Barros na disciplina de Programação
Visual que utiliza o Delphi como ferramenta. E fica comprovado que o projeto apresentado
em Lazarus se equivale com a matéria apresentada em Delphi, mesmo existindo algumas
diferenças, nas quais foram resolvidas com estudo e auxilio do professor.
131

17 - CRONOGRAMA

No primeiro semestre deste ano, foi estabelecido como meta o desenvolvimento de


uma apostila referente à disciplina de Linguagem de Programação Visual, implementada pelo
professor Renato Barros, utilizando a ferramenta Lazarus.

No segundo semestre foi desenvolvida a segunda apostila referente a disciplina de


Desenvolvimento de Aplicações Comercias, assim dando continuidade na disciplina do
professor Renato Barros, utilizando a mesma ferramenta

AGOSTO
SETEMBRO
OUTUBRO
NOVEMBRO
DEZEMBRO

Você também pode gostar