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; {else}
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