Artigo Clube Delphi Edição 2 - Sistema de Biblioteca

Continuaremos o artigo, agora com o Cadastro de Livros.

Esse artigo faz parte da revista Clube Delphi edição 2. Clique aqui para ler todos os artigos desta edição



Atenção: por essa edição ser muito antiga não há arquivo PDF para download. Os artigos dessa edição estão disponíveis somente através do formato HTML. 

 

Sistema de Biblioteca

Parte II do Sistema de Controle de Biblioteca

 

Continuaremos agora com o Cadastro de Livros. Lembrando: nossa biblioteca armazena as informações dos livros, como título e autor, e seus respectivos exemplares, como número

de série e data de compra. Este formulário é muito parecido com o de cadastro de leitores. Geralmente em sistemas que envolvem cadastros e consultas a tabelas, teremos características que serão comum aos formulários.

Nossos formulários de cadastro, por exemplo, sempre serão do tipo modal e terão os botões de inclusão, alteração e exclusão. Baseado neste fato, veremos nesta II etapa uma novidade em nosso

sistema: a criação de um formulário modelo, Usaremos herança de um formulário pré-definido.

Será um formulário com todos os objetos e procedimentos em comum. Quando criarmos uma nova tela de cadastro, ao invés de construirmos o Form do zero, criaremos a partir do nosso formulário

modelo, ou da nossa classe de formulário.

Vamos ver como criar o nosso primeiro modelo de formulário  no Delphi:

Crie um novo formulário, em

File à New à Form e salve-o com nome de “Cadastro”. Este Form será o nosso modelo .

Agora criaremos um Form com tudo que será comum em nossas telas de cadastro. Começaremos mudando as propriedades do novo formulário:

Coloque agora os seis botões que estarão presentes na parte inferior do formulário (como visto na tela de leitores), e mude suas respectivas propriedades, como descrito na tabela abaixo:

 

 

Insira um objeto TTable, um TDatasource e um TPanel. Altere o nome do objeto TPanel para

PanelDados, e posicioneo ao centro da tela.

Pronto! O Form de modelo está Terminado conforme abaixo.

 

Figura 1. Formulário de Cadastro

 

Iremos agora colocá-lo no Repositório de Objetos, para que possamos usálo futuramente.

Clique com o botão inverso do mouse no formulário, e no menu flutuante, selecione a opção “Add To Repository...”, como mostra a figura2:

 

figura 2: add to Repository

 

O Form FrmCadastro já aparece selecionado na lista a esquerda, bastando apenas preenchermos as informações a direita da janela:

Agora clique em OK para definir este form como modelo. Caso você não tenha salvo a Unit, a janela Save Unit será mostrada.

 

Figura 3: salvar unit

 

Utilizando o modelo FrmCadastro

Iremos agora iniciar a construção do cadastro de livros, e é claro, usaremos o nosso modelo de cadastro.

Abra o repositório de objetos (menu File à New à Other...) e clique na página

Forms.

 

Figura 4: new items

 

Repare que há três formas de usar um objeto do repositório, posicionadas na parte inferior da tela:

Copy, Inherited, e Use.

Eis a descrição:

 

 

A opção inherited cria um formulário vinculado ao formulário modelo.

Se alterarmos o form pai (se incluirmos um botão, ou uma procedure, etc) estas alterações se refletirão em todos os forms criados com a opção inherited marcada. Não usarei a opção

inherited neste exemplo, pois muito do código feito na classe pai será modificado (o nome dos objetos por exemplo, serão alterados). Neste caso, selecione a opção copy, e dê um clique duplo sobre o ícone “formulário de cadastro”, para criar um novo form baseado no nosso modelo.

Nota: A herança só acontece do form pai para o filho. As alterações feitas no formulário filho não são refletidas no modelo, nem em qualquer outro form do projeto. Salve o novo formulário criado

com o nome de Cadlivro.pas, e altere a propriedade Name deste formulário para ‘FrmCadLivro’ e o Caption para “Cadastro de Livros” OK! Todo o código necessário para o início do form já está

feito, bastando apenas incluir os campose personalizar os eventos para que a tela fique pronta. Começaremos alterando as propriedades do objeto Table1 e

depois do DataSource1, conforme

descrevem as duas tabelas abaixo :

 

 

Esta janela servirá também para incluir os exemplares do livro cadastrado. Os exemplares significam a cópia física do livro na biblioteca, contendo o número de série (de controle da Biblioteca) e a data de aquisição. Para representar esta tabela, insira mais um componente TTable e um

TDataSource, e altere suas propriedades:

 

 

O objeto tbExemplar irá estar sempre posicionado de acordo com o objeto tbLivro. Por exemplo, quando tbLivro estiver posicionado no livro de código 1, o ideal é que somente apareçam os exemplares cujo código tambem seja igual a 1. As propriedades

MasterSource e MasterFields fazem justamente isto: linkam uma tabela filho a uma tabela pai (para os saudosistas, é o equivalente ao Set Relation, do clipper). Há também uma outra característica

interessante neste link: Quando um registro é inserido na tabela filho, o campo chave é automaticamente preenchido com seu respectivo campo na tabela pai. Isto quer dizer que quando o livro de número 2 estiver na tela, se incluirmos um exemplar, automaticamente o campo codlivro será preenchido com o valor 2.

Para definir este link, primeiramente selecione a tabela pai (Tbexemplar) na propriedade

MasterSource. Repare que o objeto datasource é quem deve ser selecionado, que no caso, é DsLivro.

E agora, dê um clique duplo na propriedade MasterFields, para que a janela Field Link Design seja mostrada:

 

Figura 5: field link design

 

A lista a esquerda exibe os campos da tabela selecionada, ou seja, da tabela exemplar. Selecione o campo Codlivro, e na lista a direita, que exibe os campos da tabela pai, selecione o campo código. Clique no botão Add e repare que o link entre as duas tabelas, feito pelos campos codlivro e código, é exibido na lista na parte inferior da janela.

Seguindo a figura 1, vamos agora colocar os objetos para edição dos dados da tabela de livros. Segue abaixo a descrição dos objetos e de suas propriedades:

E para edição das infomações da tabela de exemplares, usaremos objeto DBGrid, como mostra a figura 1. adicione um objeto DbGrid e mais dois objetos Tbutton ao form,  e mude suas propriedades de acordo com a tabela vista abaixo.

 

 

Objetos Tlabel do Form – Paleta Standard

Label1.Caption Código

Label2.Caption Título

Label3.Caption Autor

Label4.Caption Editora

Dbedits da paleta DataControls 

Name dbTitulo

DataSource dsLivro

DataField Titulo

 

Name dbAutor

DataSource dsLivro

DataField Autor

jeto: DBEdit1

Name dbEditora

DataSource dsLivro

DataField Editora

DBGrid da paleta DataControls

Name GridExemplar

DataSource dsExemplar

TButtons da plaheta Standard

Name BTincluirExemplar

Caption Incluir Exemplar

 

Name BTexcluirExemplar

Caption Excluir Exemplar

 

Veremos agora as alterações necessárias aos eventos click dos botões:

 

procedure TfrmCadastro.btIncluirClick(Sender:TObject);

begin

  opc:=‘I’;

  tbLivro.Append;

  dbTitulo.SetFocus;

  ControlaBotoes(False);

end;

 

As únicas alterações no botão incluir são as mudanças no nome do objeto table – que passou a se chamar tbLivro – e no nome do objeto DbEdit1 que passou para DbTitulo

 

procedure TfrmCadastro.btAlterarClick(Sender:TObject);

begin

  codigo:=-1;

  FrmConsulta.ShowModal;

  if codigo>0 then begin

opc:=‘A’;

ControlaBotoes(False);

tbLivro.FindKey([Codigo]);

tbLivro.Edit;

dbTitulo.SetFocus;

end;

end;

 

No botão alterar também foi atualizado o nome do objeto table. O formulário de consulta será construído mais adiante. Ainda nesta edição.

 

procedure TfrmCadastro.btconfirmarClick(Sender:TObject);

begin

if ((opc='I') or(opc='A')) and ((tblivro.State = DsInsert) or (tblivro.State = Dsedit)) then

tbLivro.post

else  if opc=’E’ then begin

tbExemplar.Last;

while not tbExemplar.Eof do

tbExemplar.Delete;

tbLivro.Delete;

end;

ControlaBotoes(True);

end;

 

No botão confirmar temos uma novidade: caso a confirmação seja de uma exclusão, primeiro a aplicação deleta todos os registros da tabela exemplares, para depois deletar o registro atual da tabela livro. Lembre que a tabela exemplar está linkada com tblivro, e o sistema só navegará entre os registros de exemplares que estão relacionados com o registro atual. Isto na verdade é uma implementação manual de uma regra de integridade em Cascata, na qual preferi não definir na tabela,

por estar usando o Paradox e não considerar confiável.

 

procedure TfrmCadastro.btCancelarClick(Sender:TObject);

begin

if opc=‘I’ then begin

tbExemplar.Last;

while not tbExemplar.Eof do

TbExemplar.Delete;

end;

tbLivro.Cancel;

ControlaBotoes(True);

end;

 

Também há uma alteração no botão cancelar: caso seja o cancelameto de uma inclusão, os registros incluídos na tabela exemplares são eliminados.

Nota: Todas as verificações de regras de integridade e relacionamento com as outras tabelas, serão feitas ao final do sistema.

Restanos ainda os botões para inclusão e exclusão de exemplares.

Eis o código:

 

procedure TfrmCadLivro.BtIncluirExemplar(Sender:Tobject);

begin

  tbExemplar.Append;

  tbExemplar.FieldbyName(‘Datacompra’).asDateTime:=now;

  GridExemplar.SetFocus;

end;

 

procedure TFrmCadLivro.btExcluirExemplar(Sender:TObject);

begin

  tbExemplar.Delete;

end;

 

Temos ainda um detalhe: O campo série da tabela Exemplar, será um campo numérico incrementável. Ou seja, o usuário não irá digitar o número de série, o próprio sistema irá

fornecê-lo. O primeiro passo então é fazer com que a coluna referente ao campo NroSerie seja ReadOnly. Abra a tabela, setando a propriedade Active de TbExemplar para True, e dê um clique duplo sobre o objeto TDbGrid, para que a janela Editing Columns seja mostrada. Clique no botão Add All Fields, e selecione a coluna CodLivro. Repare que estamos apenas instanciando objetos que representam as colunas do DBGrid. Com a coluna Serie selecionada, altere a propriedade ReadOnly para True, e o campo NroSerie será alterável apenas pela aplicação.

Vamos agora fazer com que este campo seja autoincrementável. Para isto, teremos uma variável global ao formulário, chamada NroSerie, declarada da seguinte forma:

Var

 

FrmCadastro: TFrmCadastro;

NroSerie: LongInteger;

Implementation

 

Precisamos alterar o botão incluir, para que inicialize a variável:

 

procedure TfrmCadastro.btIncluirClick(Sender:TObject);

begin

  opc:=‘I’;

  tbLivro.Append;

  NroSerie:=0;

  dbTitulo.SetFocus;

  ControlaBotoes(False);

end;

 

O botão alterar também precisa de uma modificação, a fim de que a variável NroSerie contenha o valor do último exemplar cadastrado:

 

procedure TfrmCadastro.btAlterarClick(Sender:TObject);

begin

  codigo:=-1;

  FrmConsulta.ShowModal;

if codigo>0 then

begin

  opc:=’A’;

  ControlaBotoes(False);

  tbLivro.FindKey([Codigo]);

  tbLivro.Edit;

  DbTitulo.SetFocus;

  if TbExemplar.RecordCount>0 then

  begin

tbExemplar.Last;

NroSerie:=TbExemplar.Fieldbyname(‘Serie’).AsInteger;

  end

else

NroSerie:=0;

end;

end;

 

E agora precisamos inicializar o campo serie com a variável NroSerie, toda vez que a tabela for appendada. Poderiamos utilizar o evento OnClick do botão Incluir Exemplar, mas isto seria falho, pois o usuário poderia incluir um exemplar simplesmente indo para o último registro no DbGrid e pressionando a tecla seta para baixo. Podemos então, utilizar o evento OnNewRecord do objeto TTable, que ocorre ao ser inserido um registro na tabela, independente de qual método foi utilizado:

 

procedure TFrmCadastro.TbExemplarNewRecord(DataSet:TdataSet);

begin

  NroSerie:=NroSerie+1;

  tbExemplar.Fieldbyname(‘Serie’).asInteger := NroSerie;

end;

 

É interessante também decrementarmos a variável quando o usuário cancelar a inclusão (pressionando ESC). O evento correspondente é OnBeforeCancel, que como o nome

já diz, ocorre antes de um cancelamento na tabela. O evento “before” foi o escolhido, pois neste momento, temos como saber se a tabela está em modo de inclusão ou alteração:

 

procedure TfrmCadLivro.TbExemplarBeforeCancel(dataSet: TdataSet);

begin

  if TbExemplar.State=dsInsert then

  NroSerie := NroSerie - 1;

end;

 

Ok! Resta apenas criar a tela de consulta, para que os botões alterar e excluir funcionem corretamente.

 

Tela de Consulta

Veremos agora a construção da tela de pesquisa para os livros. Diferente da edição anterior, este form de consulta utilizará o objeto TQuery. A tela de pesquisa ficará como a figura 6.

Inicie criando um novo form. Salve e chame-o de ConsLivro.Pas. Suas propriedades seguem abaixo:

 

Name FrmConsulta

BorderStyle bsDialog

Position poScreenCenter

Caption Consulta de Livros

 

Figura 6: form de consulta

abel1

Object Label

Name Label1

Caption Digite o nome do livro a pesquisar

Object Dbgrid1Objeto: DBGrid1

Name dbGrid1

DataSource dsLivro

Object Edit1

Name Edit1

Text “Deixe em Branco"

 

Object BitBtn

Name BtOK

Kind BKOK

Caption OK

 

Object BitBtn

Name BtCancelar

Kind BKCancel

Caption Cancelar

 

Object SpeedButton1

Name BtPesquisar

Caption “Deixe em Branco”

Tabela1: Propriedades do Fo

Object Query

Name QryLivro

DataBaseName Biblio

Rm

Object DataSource

Name DSLivro

DataSet QryLivro

 

Para utilizar o objeto Tquery, basicamente basta definirmos sua propriedade

DatabaseName para biblio, e na propriedade sql, digitarmos a cláusula de consulta. No caso, a nossa primeira consulta utilizando o objeto Tquery será bem simples, ela apenas irá selecionar os livros pelo campo título.

Uma instrução sql básica é usada para isto:

 

Select *

From livro

Where titulo like :p_titulo

 

Caso você não conheça ou não tenha muita intimidade com a linguagem sql, confira a nossa seção de dicas, pois lá damos um overview sobre o assunto.

Para criar um parâmetro, basta colocar o nome da variável, antecedida de dois pontos, como vemos na variável p_titulo.

E no evento OnClick do botão pesquisar, basta colocarmos o código que executará a instrução SQL:

 

procedure TForm1.BtPesquisarClick(Sender: TObject);

begin

  screen.cursor:=crHourGlass;

  QryLivro.close;

  QryLivro.ParamByName('p_titulo').asString:='%'+Edit1.Text+ '%';

  QryLivro.Open;

  screen.cursor:=crDefault;

end;

 

Na primeira linha alteramos o cursor para a ampulheta de espera. Repare que o objeto screen é usado, e dessa forma, o cursor permanecerá como ampulheta por toda a área da aplicação. Em seguida fecho a consulta e passo o valor digitado no objeto edit1 para o parâmetro p_titulo. Os parâmetros de uma query podem ser acessados através da propriedade ParamByName do objeto tquery. A sintaxe desta propriedade é a mesma de FieldByName, vista anteriormente. Note que entre a cláusula edit1.text, é adicionado o caracter %:

 

(‘%’ + edit1.text + ‘%’)

 

O caracter ‘%’, indica ao TQuery que o valor deverá ser pesquisado em qualquer parte do campo, ou seja, é equivalente ao caracter * no DOS. Por exemplo, se utilizássemos a cláusula:

 

Edit1.text + ‘%’

 

O valor seria pesquisado apenas na parte inicial do campo. O uso do caracter % deve ser usado com critério, pois quanto maior a faixa de pesquisa, mais lento será a pesquisa. Após, abro a consulta com o método open, e restauro o cursor para default novamente.

O form deverá ser iniciado com todos os registros na grade. Para isto, basta passarmos ‘’ (vazio) para o parâmtro p_titulo, no evento OnShow do formulário:

 

procedure TFrmConsultaLivros.FormShow(Sender: TObject);

begin

  edit1.clear;

  edit1.setfocus;

end;

Agora vamos à rotina do botão OK(btOK):

procedure TFrmConsulta.btOKClick(Sender: TObject);

begin

   if not QryLivro.IsEmpty then

   begin

Codigo := QryLivro.fieldByName('codigo').AsInteger;

opc:='A';

FrmCadLivro.TBlivro.edit;

close;

   end;

end;

 

Conforme você pode notar, btPesquisarClick nada mais é do que o evento OnClick do botão pesquisar, sendo executado a partir de outro evento. O valor nil, passado para o parâmetro Sender do evento OnCLick, serve apenas para cumprimento de regras de sintaxe. O parâmetro Sender identifica quem, e no nosso caso, não tem utilidade.

 

Ok! Nosso formulário de consulta, baseado na linguagem sql, estáterminado. No próximo formulário, o de cadastro de empréstimos e devoluções, veremos uma outra consulta com

mais alguns recursos de seleção. Para finalizar esta parte de nosso projeto, basta alterarmos os eventos click dos botões alterar e excluir no cadastro de livros.

 

Conclusão

Neste capítulo vimos como linkar duas tabelas através das propriedades MasterSource e MasterFields, além de como inserir um formulário no repositório de objetos. Vimos ainda uma introdução ao uso do objeto Tquery, e a linguagem SQL. O nossa tela de cadastro de livros apresentou ainda uma introdução a construção de formulários um para n. Na seção dicas, você pode encontrar vários exemplos comentados de instruções SQL. Tanto os exemplos da seçãp dicas como o sistema descrito neste curso, podem ser encontrados em nossa Home Page, no endereço: www.clubedelphi.com.br. Dúvidas, críticas ou sugestões podem ser enviadas para admin@clubedelphi.com.br

Artigos relacionados