apostila delphi e banco de dados local (excelente)

60
Aplicações para Banco de Dados Local _______________________________________________________________________________ D E L P H I A P L I C A Ç Õ E S P A R A B A N C O D E D A D O S L O C A L Prof. José Geraldo Orlandi FAVI – Instituto de Ensino Superior Versão 1.0 – Maio 2004 1

Upload: everton-michel

Post on 26-Jul-2015

193 views

Category:

Documents


10 download

TRANSCRIPT

Page 1: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

DELPHI

APLICAÇÕES PARA BANCO DE DADOS LOCAL

Prof. José Geraldo Orlandi FAVI – Instituto de Ensino Superior

Versão 1.0 – Maio 2004

1

Page 2: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

ÍNDICE

1. INTRODUÇÃO A BANCO DE DADOS ........................................................................................ 3 BDE................................................................................................................................................................................................................. 3 BDE ADMINISTRATOR...................................................................................................................................................................................... 3 ARQUITETURA DO BANCO DE DADOS DO DELPHI............................................................................................................................................... 4 ARQUITETURA DOS COMPONENTES DE BANCO DE DADOS ................................................................................................................................. 4 DATABASE DESKTOP........................................................................................................................................................................................ 5 ALIASES ........................................................................................................................................................................................................... 7 DATABASE EXPLORER....................................................................................................................................................................................... 7 PALETA DE COMPONENTES DA PÁGINA DE ACESSO DE DADOS ........................................................................................................................... 7 PALETA DE COMPONENTES DA PÁGINA DE CONTROLE DE DADOS....................................................................................................................... 8 USANDO DATASETS.......................................................................................................................................................................................... 9 ESTADOS DO DATASET ..................................................................................................................................................................................... 9 UTILIZANDO O COMPONENTE E DATASOURCE................................................................................................................................................. 10 PROPRIEDADES DO OBJETO TDATASET ........................................................................................................................................................... 12 MÉTODOS DO OBJETO TDATASET................................................................................................................................................................... 13 EVENTOS DO OBJETO TDATASET.................................................................................................................................................................... 14 UTILIZANDO O OBJETO TFIELDS ..................................................................................................................................................................... 15 COMPONENTE TABLE ...................................................................................................................................................................................... 18 CRIANDO UMA APLICAÇÃO UTILIZANDO O COMPONENTE TABLE..................................................................................................................... 18 O COMPONENTE QUERY ................................................................................................................................................................................. 22 CRIANDO UMA APLICAÇÃO UTILIZANDO O COMPONENTE QUERY .................................................................................................................... 24 UTILIZANDO O COMPONENTE DATABASE GRID ............................................................................................................................................... 27

2. BANCOS DE DADOS RELACIONAIS ........................................................................................ 30 CHAVES DE ACESSO........................................................................................................................................................................................ 30 CHAVES PRIMÁRIAS........................................................................................................................................................................................ 30 CHAVES SECUNDÁRIAS ................................................................................................................................................................................... 30 CHAVES ESTRANGEIRAS.................................................................................................................................................................................. 31 CONSISTÊNCIA E INTEGRIDADE DOS DADOS..................................................................................................................................................... 31 INTEGRIDADE REFERENCIAL ........................................................................................................................................................................... 31

3. FORM WIZARD.......................................................................................................................................................... 33

4. COMPONENTE DATABASE LOOKUP.................................................................................... 35 COMPONENTE DBLOOKUPLISTBOX ................................................................................................................................................................ 35 COMPONENTES DBLOOKUPCOMBOBOX ......................................................................................................................................................... 35 ADICIONANDO UM COMPONENTE DATABASE LOOKUP A UM FORM .................................................................................................................. 35 CRIANDO UMA APLICAÇÃO UTILIZANDO UM COMPONENTE DATABASE LOOKUP.............................................................................................. 36

5. CRIANDO UM APLICATIVO MASTER/DETAIL..................................................... 39 TABELA MASTER ............................................................................................................................................................................................ 45 TABELA DETAIL.............................................................................................................................................................................................. 47 ALTERANDO AS PROPRIEDADES DE ALGUNS COMPONENTES DO FORMULÁRIO. .................................................................................................. 49

6. RELATÓRIOS................................................................................................................................................................ 57 CONSTRUÇÃO DE UM RELATÓRIO SIMPLES ...................................................................................................................................................... 58 CONSTRUÇÃO DE UM RELATÓRIO MASTER/DETAIL ......................................................................................................................................... 59

2

Page 3: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

1. INTRODUÇÃO A BANCO DE DADOS Os aplicativos de banco de dados do Delphi não têm acesso direto às fontes de dados que eles referenciam. O Delphi faz interface com o Borland Database Engine (BDE) que tem acesso direto às diversas fontes de dados, incluindo dBase, Paradox, etc. O BDE também pode fazer interface com SQL, permitindo acesso a diversos servidores, remotos ou locais.

BDE O Borland Database Engine é o coração do Delphi em suas aplicações com banco de dados principalmente usando Paradox e dBase. O BDE é uma coleção de DLLs que as aplicações de banco de dados irão fazer chamadas. Cada estação de trabalho que tiver a aplicação de banco de dados instalada deverá ter também o BDE instalado. O Delphi vem com a instalação do BDE para você adicionar a sua aplicação. O BDE permite a você usar tabelas dBase, Paradox ou ODBC em modo multi-usuário. A versão Cliente/Servidor do Delphi também vem com links para servidores de banco de dados como Oracle, Sybase, MS SQL Server, Informix, e InterBase.

BDE Administrator Com o BDE Administrator você pode alterar a configuração da BDE, por exemplo em Configuration/System/Init você tem a propriedade Local Share que deve ser setada para True, quando você quiser que a base de dados seja compartilhada em uma rede. Além disso, você pode criar Aliases, como no Database Explorer.

O BDE Administrator

3

Page 4: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Arquitetura do Banco de Dados do Delphi As aplicações em Delphi não acessam diretamente o banco de dados. O acesso é feito através do BDE. Portanto devido a este fato, elas são leves e padronizadas.

Arquitetura do Banco de Dados em Delphi

Arquitetura dos Componentes de Banco de Dados

Arquitetura de Acesso a DB em Delphi

4

Page 5: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

DataBase Desktop O DataBase Desktop é uma ferramenta do DELPHI para manipulação de Banco de Dados. Ela é útil principalmente para:

• criação de banco de dados; • alteração das características dos campos.

EXEMPLO: criar uma tabela contendo os funcionários de uma empresa. Para ilustrar o funcionamento do DataBase Desktop será criada uma tabela de produtos com os seguintes campos: CÓDIGO, NOME DA PESSOA, IDADE, SEXO, ENDERECO, CIDADE, UF e SALÁRIO. Para isto devem ser seguidos os passos abaixo: PASSO 1 Clique na opção Tools no menu principal do DELPHI, e, em seguida, na opção Database Desktop. Neste momento será aberto o programa Database Desktop. PASSO 2 No menu principal do Database Desktop selecione a opção File, seguida de New e, por fim, a opção Table (Erro! A origem da referência não foi encontrada.). PASSO 3 O próximo diálogo permite que se selecione o tipo da tabela a ser criada. Selecione a opção Paradox 7 e clique em OK. As tabelas Paradox tem extensão (DB) e oferecem mais recursos que as tabelas DBase (extensão DBF).

Database Desktop: criando uma nova tabela.

PASSO 4 Neste instante devem ser definidos os atributos dos campos, como segue:

• Field Name: define o nome do campo; • Type: define o tipo do campo. Clicando com o botão direito do mouse pode-se selecionar o tipo do

campo; • Size: define o tamanho do campo. Só está disponível para alguns tipos; • Key: define campos-chave para bancos de dados relacionais. Ainda nesta tela pode-se definir: • Table properties: define características gerais dos campos da tabela; • Required Field: define se o campo tem um valor requerido; • Minimum Value: valor mínimo para o campo; • Maximum Value: valor máximo para o campo; • Default Value: valor default para o campo; • Picture: define o tipo de campos figura.

5

Page 6: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

6

Database Desktop: definindo os atributos dos campos

PASSO 5 Clicando no botão Save As, deve aparecer uma caixa de diálogo para que se possa salvar a tabela em disco. Dê um nome a tabela e clique no botão Save.

Verifique com atenção o diretório onde está gravando a tabela. Neste instante a tabela foi criada. Para verificar se ela foi criada corretamente pode-se selecionar File | Open | Table no menu principal do Database Desktop, para poder abrir o arquivo gravado.

Table Properties Em Table Properties você define os vários aspectos de configuração da tabela. Muitas dessas opções podem ser implementadas no Delphi e vários programadores preferem não usá-las no Database Desktop.

Opção Descrição

Validity Checks Validações para os campos, como obrigatoriedade, valor mínimo e máximo

Table Lookup Indica que o valor atribuído a um determinado campo tem que estar gravado em outra tabela

Secondary Indexes

Cria índices secundários

Referential Integrity

Cria integridade referencial, geralmente utilizada em relacionamentos de 1 para N.

Password Security

Permite a criação de senhas, protegendo a tabela de acesso não autorizado

Table Language Especificar o driver de língua utilizado pela tabela, geralmente é o Pdox ANSI Intl850

Dependent Tables

Mostra todas as tabela dependentes através da integridade referencial

Tipos de Campos Os principais tipos de campos são mostrados abaixo, mas existem outros além desses. Os tamanhos marcados com asterisco indicam que o campo pode guardar tamanhos maiores que os informados, o que ultrapassar o tamanho será guardado em um arquivo externo com a extensão MB.

Page 7: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Tipo Descrição Faixa Tamanho

A Alfanumérico 1-255

N Numérico ± 10 308

$ Monetário

S Short Integer ± 32767

I Long Integer ± 2147483648

D Data

T Hora

@ Data e Hora de modificação

M Memo 1-240*

G Gráfico 1-240*

L Lógico True/False

+ Autoincremental 1-2147483648

Aliases Um Alias é um nome lógico, um atalho para um banco de dados. Todo o trabalho do Delphi com um banco de dados pode ser feito baseado no Alias, de forma que para mudar de banco de dados, só é necessário mudar o Alias. Para criar um Alias você pode usar Database Explorer, o BDE Administrator ou o próprio Database Desktop.

Database Explorer Pode aparecer com os nomes Database Explorer ou SQL Explorer. Nele você pode manipular os Aliases, navegar pelas estruturas dos bancos de dados, alterar os dados das tabelas e executar comandos SQL. Para criar um Alias selecione o item Databases, clique em Object/New, escolha o tipo do banco de dados, ou Standard para dBase, Paradox e arquivos texto, depois digite um nome do Alias, esse nome será usado pelo Delphi quando você quiser acessar o banco de dados, finalmente defina as propriedades do banco de dados na seção Definition, cada banco de dados terá suas próprias definições. O assunto será abordado com detalhes posteriormente.

Paleta de Componentes da página de Acesso de Dados

Paleta Data Access

7

Componente Utilidade

TDataSource Atua como um conduto entre componentes TTable, TQuery, TStoredProc e componentes de controle, como um TDBGrid

TTable Adquire dados de uma tabela de banco de dados via o BDE e fornece dados para um ou mais componentes de controle de dados através do componente TDataSource. Envia dados recebidos de um componente para um banco de dados via o BDE.

TQuery Usa estruturas em SQL para recuperar dados de uma tabela de banco de dados via o BDE, e fornece dados para um ou mais componentes de controle de dados através de um TDataSouce, ou usa estruturas em SQL para enviar dados de um componente para um banco de dados via o BDE.

TStoreProc Habilita uma aplicação para acessar procedimentos armazenados em um servidor. Envia dados recebidos de um componente para um banco de dados via o BDE.

TDataBase Instala uma conexão permanente com um banco de dados, especialmente um banco de dados remoto requerendo um login do usuário e uma senha.

Page 8: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

TBatchMove Copia a estrutura de uma tabela ou seus dados. Pode ser usado para mover tabelas inteiras de uma formato de banco de dados para outro.

TSession Fornece gerenciamento global para um grupo de conexões a banco de dados dentro de uma aplicação. Delphi cria automaticamente uma sessão default se não for criada pelo usuário.

TUpdateSQL Aplica cached updates como agente de queries ou stored procedures que não podem ser salvas diretamente no banco de dados.

TNestedTable É um componente Dataset que encapsula uma tabela de banco de dados que está aninhada como um campo dentro de uma outra tabela.

Paleta de Componentes da página de Controle de Dados

Paleta Data Controls

Componente Utilidade

TDBGrid Grade padrão de controle de dados que possibilita visualizar e editar dados de forma tabular, semelhante a uma planilha; faz uso extensivo das propriedades do TField (estabelecidos no Editor de Campos Fields Editor) para determinar a visibilidade de uma coluna, formato da visualização, ordem, etc.

TDBNavigator Botões de navegação para controle de dados que move o apontador do registro corrente de uma tabela para o posterior ou anterior, inicia inserção ou modo de edição; confirma novos ou modificações de registros; cancela o modo de edição; e refresca (refaz) a tela para recuperar dados atualizados.

TDBText Rótulo de controle de dados que pode mostrar um campo corrente do registro ativo.

TDBEdit Caixa de edição de controle de dados que pode mostrar ou editar um campo corrente do registro ativo.

TDBCheckBox Caixa de verificação de controle de dados que pode mostrar ou editar dados lógico de uma campo corrente do registro ativo.

TDBListBox Caixa de Lista de controle de dados que pode mostrar valores da coluna de uma tabela.

TDBComboBox Caixa de Lista móvel de controle de dados que pode mostrar ou editar valores da coluna de uma tabela.

TDBRadioGroup Grupos de radio de controle de dados com botões de rádio que pode mostrar ou setar valores de colunas.

TDBMemo Caixa memo de controle de dados que pode mostrar ou editar dados textos do registro corrente ativo.

TDBImage Caixa de Imagem de controle de dados que pode mostrar, cortar ou colar imagens BLOB bitmap’s do registro corrente ativo.

TDBLookupList Caixa de Lista de controle de dados que mostrar valores mapeados através de outra tabela em tempo de compilação.

TDBLookupCombo Caixa de Combo de controle de dados que mostrar valores mapeados através de outra tabela em tempo de compilação.

TDBRichEdit Representa um controle de edit multi-linhas que pode mostrar e editar um campo memo em texto rico em um dataset..

TDBCtrlGrid Mostra registros de uma fonte de dados em um lay-out com tipo de formato livre.

TDBChart É derivado do TChart e herda todas suas funcionalidades. Adquire a série de dados direto de um banco de dados.

8

Page 9: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Usando DataSets Para manipular e consultar bancos de dados, você precisa entender o conceito de dataset. Um dataset no Delphi é um objeto que consiste de uma série de registros, cada um contendo qualquer quantidade de campos e um ponteiro para o registro atual. O dataset pode ter uma correspondência direta, um-para-um, com uma tabela física, ou, como um resultado de uma query, pode ser um subconjunto de uma tabela ou uma junção de diversas tabelas. As classes de componentes Um dataset no Delphi é o tipo de objeto TDataSet e é uma classe abstrata. Uma classe abstrata é uma classe de onde você pode derivar outras classes, mas não pode criar uma variável desta classe. Por exemplo, ambos os componentes Query e Table classificam-se como componentes TDataSet porque cada um foi derivado do objeto TDataSet. Note que você não encontrará nenhum componente chamado TDataSet nas paletas. O TDataSet contém as abstrações necessárias para manipular diretamente uma tabela. É a ferramenta utilizada para abrir uma tabela e navegar por suas colunas e linhas. Os componentes neste capítulo são referenciados pelo seu tipo de objeto (identificado no Delphi pelo seu nome com o prefixo T). O termo componente DataSet é utilizado para referenciar um componente Table, Query, ou StoredProc. TTable, TQuery, e TStoredProc são descendentes de TDataSet, ou seja, eles herdam as propriedades de TDataSet.

Datasets

Estados do DataSet

Estado Descrição

dsInactive O Dataset esta fechado.

dsBrowse Estado de Espera. O estado default quando um dataset é aberto. Registros podem ser visualizados mas não mudados ou inseridos.

dsEdit Habilita a linha corrente para ser editada.

dsInsert Habilita uma nova linha para ser inserida. Uma chamada para o Post inserir a nova linha.

dsSetKey Habilita FindKey, GotoKey, and GoToNearest para procurar valores nas tabelas do banco de dados. Estes métodos somente pertencem para o componente TTable. Para TQuery, a procura é feita com a syntax do SQL.

dsCalcFields Modo quando os OnCalcFields é executado; previne qualquer mudança para outros campos ou campos calculados. Raramente é usado explicitamente.

9

Page 10: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

10

Estados de um Dataset

Utilizando o Componente e DataSource O componente DataSource atua como intermediário entre o componente DataSet (TTable, TQuery, ou TStoredProc) e os componentes Data Control. Dentre os componentes Data Control incluem DBGrid, e DBText entre outros. Um Componente DataSource gerencia o relacionamento entre uma tabela de banco de dados e a representação deste dado em seu form. É um intermediário entre os componentes DataSet e DataControl. Componentes DataSet gerenciam a comunicação com o Borland Database Engine (BDE), e o componente DataSource gerencia a comunicação com componentes data-aware Data Control. Em uma típica aplicação de banco de dados, um componente DataSource é associado com um componente DataSet (Table ou Query) e um ou mais componentes Data Control (tais como DBGrid). A figura a seguir mostra este relacionamento:

Page 11: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Função do Componente DataSource

Utilizando Propriedades e Eventos DataSource As propriedades e eventos chave do componente DataSource são: • Propriedade DataSet • Propriedade Enabled • Propriedade AutoEdit • Evento OnDataChange • Evento OnUpdateData • Evento OnStateChange

Utilizando a propriedade DataSet do Componente DataSource A propriedade DataSet identifica o nome de um componente DataSet. Você pode atribuir à propriedade DataSet através de programação ou utilizando o Object Inspector. O valor atribuido à propriedade DataSet é o nome de um objeto TDataSet. Por exemplo, a linha de código a seguir atribui um nome ou objeto TQuery à propriedade DataSet de um componente ou objeto DataSource.

DataSource1.DataSet : = Query1 Você pode inserir diversos componentes Query, Table, e StoredProc em um form a atribuir a propriedade DataSet baseado em uma condição no programa. Você também pode atribuir a propriedade DataSet a um nome ou objeto TQuery, TTable, ou TStoredProc encontrado em outro form utilizando o identificador da unit do form. Por exemplo, após incluir a Unit1 na cláusula uses, você pode digitar o seguinte:

DataSource1.DataSet : = Unit1.Form1.Table1;

Utilizando a Propriedade Enable do Componente DataSource A propriedade Enable inicia ou termina a comunicação entre os componentes TDataSource e DataControl. É do tipo booleano assumindo True ou False. Por exemplo, o código a seguir desabilita o TDataSource, procura por um valor coincidente de número do cliente, e depois habilita o TDataSource para que ou a linha do cliente ou a última linha seja exibida.

DataSource1.Enabled : = False; Table.First; While not Table1.EOF do begin if Table1.FieldByName(‘NoCliente’).AsString = LookupCust then Break; Table1.Next; end; DataSource1.Enabled : = True;

11

Page 12: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Utilizando a propriedade Enable permite que você desconecte temporariamente o componente visual Data Control do TDataSource. No exemplo anterior, se a tabela contiver 2000 linhas e o TDataSource estiver habilitado, o usuário de sua aplicação veria 2000 linhas rolando na tela durante esta operação. Desabilitando TDataSource é uma maneira mais eficiente de se pesquisar em um grande número de linhas, pois o componente Data Control não atrasará a procura exibindo cada linha conforme esta for sendo alterada.

Utilizando a Propriedade AutoEdit do Componente DataSource A propriedade AutoEdit controla como a edição é iniciada nos componentes Data Control. Os valores das propriedades AutoEdit são: • True O modo de edição é iniciado sempre que o usuário comece a digitar dentro de um componente Data Control. • False O modo de edição é iniciado quando o método Edit é invocado, por exemplo, após o usuário dar um clique

sobre o botão Edit do Navigator. Este parâmetro controla a edição. Dentro do seu código, você pode utilizar os seguintes métodos para controlar as alterações nos dados da tabela quando AutoEdit estiver como False: • Edit • Post • Cancel O código a seguir é um exemplo utilizando o método Post:

DataSource1.DataSet.Edit; {Start edit mode} DataSource1.DataSet.Fields [3] .AsString : = “Hello”; DataSource1.DataSet.Post;

Utilizando o Evento OnDataChange do Componente DataSource O evento OnDataChange ocorre sempre que: • A propriedade State do TDataSource mudar do estado dsInactive • Ocorrer uma alteração de campo, registro, tabela, query ou layout Este evento é associado com alterações na exibição de dados, tais como rolar para um novo registro ou ativando TDataSource. Este evento é útil para monitorar alterações nos componentes Data Control.

Utilizando o Evento OnUpdateData do Componente DataSource O evento OnUpdateData ocorre quando: • O registro atual no TDataSet estiver para ser atualizado • Uma alteração estiver para ser confirmada Este evento é útil na monitoração de alterações nos dados de uma tabela. Por exemplo, você pode utilizar este evento para criar auditor de alterações nos dados em sua aplicação.

Utilizando o Evento OnStateChange do Componente DataSource O evento OnStateChange ocorre sempre que a propriedade State de DataSource for alterada. Este evento é útil para monitoração de alterações na propriedade State. A propriedade State pode ter os seguintes valores: • dsInactive • dsBrowse • dsEdit • dsInsert • dsSetKey • dsCalcFields

Propriedades do Objeto TDataSet A tabela a seguir descreve as propriedades mais importantes do objeto TDataSet:

12

Page 13: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Propriedade Descrição

Active Abre ou fecha um componente DataSet. Abrir um componente DataSet estabelece a conexão entre o componente e o banco de dados. Você pode definir a propriedade Active no Object Inspector durante o design ou diretamente em seu código, como segue:

if DeActivate = true then Table1.Active : = True Else Table1.Active : = False;

Os métodos Open e Close também definem a propriedade Active de TDataSet.

EOF (End of File) BOF (Beginning of File)

Propriedades somente de leitura (read-only) com os seguintes valores: • EOF é definido para True quando você tenta mover para além da última linha do

dataset • BOF é definido para True quando o componente DataSet é aberto ou quando o

ponteiro do DataSet para a linha atual estiver posicionado na primeira linha.

Fields Um array do objeto TField. Você pode definir e ler dados dos campos da linha atual utilizando esta propriedade. Por exemplo:

Table1.Fields[0]. AsString : = ‘Hello’; Table1.Fields[1] .AsString : = ‘World’;

Métodos do Objeto TDataSet O objeto TDataSet fornece ao componente Table diversos métodos. Alguns dos métodos mais importantes são mostrados na tabela a seguir:

Método Descrição

Open Close Refresh

Operam nos datasets, como segue: • O método Open é equivalente a definir a propriedade Active para True. • O método Close define a propriedade Active para False • O método Refresh permite ler novamente o dataset do banco de dados . Se você precisa

se assegurar que os dados são os mais atuais, contendo quaisquer alterações feitas por outros usuários, utilize o método refresh. Um componente Table, Query, ou StoredProc deve estar aberto com open quando Refresh for chamado.

Um exemplo destes métodos é :

Table1.Open; Table1.Close; Table1.Refresh;

First Last Next Prior MoveBy

Permite navegar ou alterar a linha atual do dataset. A seguir, um exemplo utilizando vários destes métodos:

Table1.First While not Table1.EOF do begin {Seu código aqui} Table1.Next; end;

O método MoveBy move um número especificado de linhas. Por exemplo: • Table1.MoveBy(3) move 3 linhas para baixo. • Table1.MoveBy(-2) move 2 linhas para cima.

Insert Edit Delete Append

Permite modificar os dados em uma tabela de banco de dados, como segue: • O método Insert permite adicionar uma linha à tabela. Por exemplo:

Table2.Insert;

13

Page 14: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Post Cancel

Table2.Fields[0] .AsInteger : = 20; Table2.Fields[1] .AsString : = ‘News’; Table2.Fields[ 2] .AsString : = ‘5 Horas’; Table2.Post;

• O método Post faz com que a operação Insert Update ou Delete ocorra. • O método Cancel faz com que uma operação Insert Delete, Edit ou Append não ocorrida

seja cancelada.

FieldByName Fornece uma maneira de acessar dados de uma coluna especificando no nome da coluna do banco de dados. Como no exemplo a seguir:

s : = Table2.FieldByName (‘area’) .AsString;

SetKey GotoKey

Procura através dos datasets, como segue: • SetKey alterna a tabela para o modo de pesquisa (search). Enquanto neste modo, a

propriedade Fields tem uma utilização especial. • GotoKey inicia a pesquisa por um valor coincidente com o valor encontrado em

Fields[n]. Fields[n] contém o valor a ser pesquisado por valores em outras colunas definindo a coluna Fields correspondente.

O exemplo a seguir mostra um exemplo da utilização de SetKey e GotoKey:

Table1.SetKey; Table1.Fields[0] .AsString Edit1.Text; Table1.GotoKey;

SetRangeStart SetRangeEnd ApplyRange

Permite ser mais seletivo nos dados que sua aplicação seleciona ou utiliza na tabela. Geralmente uma tabela é grande e você quer selecionar somente uma série de valores da tabela. O método Range permite fazer tal seleção. Exemplo:

Table1.SetRangeStart Table1.Fields[0] .AsString : = Edit1.Text; Table1.SetRangeEnd Table.Fields[0] .AsString : = Edit2.Text; Table1.ApplyRange;

A primeira chamada à SetRangeStart o coloca no modo range e a propriedade Fields toma um significado especial. Utilize a propriedade Fields para especificar o valor de início para a série. A chamada para SetRangeEnd inicia um modo onde os valores digitados na propriedade Fields são utilizadas como o valor final da série. ApplyRange faz com que o comando seja processado. Um dataset é criado contendo os valores entre os valores de início e final.

FreeBookmark GeTBookMark GotoBookmark

Permite criar um marcador de linha em uma tabela ou query e depois retornar à esta linha posteriormente. Os métodos Bookmark utilizam um tipo de objeto chamado TBookMark. Por exemplo:

Var Marker : TBookMark; begin Marker : = Table2.GeTBookMark; Table2.GotoBookmark(Marker); Table2.FreeBookmark(Marker);

O método GeTBookMark aloca um marcador para linha da tabela. O método GotoBookmark altera a localização na tabela para a linha indicada pelo Bookmark alocado anteriormente. Utilize o método FreeBookmark para liberar o espaço alocado para o marcador.

Eventos do Objeto TDataSet O objeto TDataSet permite responder a um grande número de eventos. A tabela a seguir descreve diversos deles:

14

Page 15: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Evento Descrição

OnOpen OnClose OnNewRecord BeforeInsert AfterInsert BeforeEdit AfterEdit BeforePost AfterPost OnCancel OnDelete

Permite construir e controlar o comportamento de aplicações de bancos de dados. Exemplos de utilização seguem: • Evento BeforePost para validar os campos de um registro antes de inserí-lo ou

atualizá-los • Evento AfterPost para gravar um registro de auditoria quando necessário • Evento OnDelete para gravar código que efetue a deleção em cascata quando

apropriado

Utilizando o Objeto TFields O objeto TField, como o objeto TDataSet, não é encontrado nas paletas. É uma propriedade do objeto TdataSet. Algumas propriedades no Object Inspector são objetos com seu próprio conjunto de propriedades. TFields é um deles.

Propriedades Fields do Objeto TDataSet Uma das propriedades do Objeto TDataSet (portanto, os componentes Table, Query, e StoredProc) é a propriedade Fields. Como discutido anteriormente neste capítulo, a propriedade Fields permite acessar os campos individuais do dataset. A propriedade Fields é um array dos objetos TFields. Este array ou lista é gerada dinamicamente durante a execução ( e portanto, não aparece na lista de propriedades do Object Inspector). O array representa cada uma das colunas no componente Table. Objetos estáticos TFields são visíveis no Object Inspector. Seções posteriores deste capítulo explicam como criar uma lista estática de objetos TField, mas primeiro, você deve entender algumas das propriedades destes objetos.

Fields Editor Para criar objetos para os campos de uma tabela clique duas vezes no componente Dataset ou escolha Fields Editor no seu menu de contexto, na janela do Fields Editor, clique com o botão direito do mouse e escolha Add, na janela Add Fields, escolha os campos que você vai querer usar e clique em Ok. No Fields Editor podemos também remover os campos criados, alterar sua ordem de apresentação e usar suas propriedades e eventos no Object Inspector. Para cada campo é criado um objeto de um tipo descendente de TField, como TStringField, TIntegerField, TFloatField. As principais propriedades, métodos e eventos dos objetos TField estão listadas nas tabelas abaixo. Se você não criar nenhum objeto TField, todos os campos da tabela estarão disponíveis, mas caso você crie algum, somente os campos que você criar estarão disponíveis. Se você selecionar os campos no Fields Editor e arrastar para o Form, serão criados os controles visuais para esses campos, Label, DBEdit e outros, mas antes coloque a descrição dos campos na propriedade DisplayLabel.

TField A classe TField é usada como ancestral para todos as classes dos campos. Geralmente iremos usar objetos de classes descendentes de TField, mas em todos eles podemos encontrar os itens mostrados abaixo.

15

Page 16: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Propriedades Descrição

Alignment Alinhamento do texto do campo nos controles visuais

AsBoolean Valor do campo convertido para Boolean

AsCurrency Valor do campo convertido para Currency

AsDateTime Valor do campo convertido para DataTime

AsFloat Valor do campo convertido para Double

AsInteger Valor do campo convertido para Integer

AsString Valor do campo convertido para string

AsVariant Valor do campo convertido para Variant

Calculated Indica se o campo é calculado em tempo de execução

CanModify Indica se um campo pode ser modificado

ConstraintErrorMessage Mensagem de erro se a condição de CustomConstraint não for satisfeita

CustomConstraint Condição de validação do campo

DataSet DataSet onde está o campo

DataSize Tamanho do campo, em Bytes

DataType Propriedade do tipo TFieldType, que indica o tipo do campo

DefaultExpression Expressão com valor Default do campo para novos registros

DisplayLabel Título a ser exibido para o campo

DisplayText Texto exibido nos controles visuais associados ao campo

DisplayWidth Número de caracteres que deve ser usado para mostrar o campo no controles visuais

EditMask Máscara de edição do campo

FieldKind Propriedade do tipo TFieldKind que indica o tipo do campo, como Calculado ou Lookup

FieldName Nome do campo na tabela

FieldNo Posição física do campo na tabela

Index Posição do campo nos controles visuais

IsIndexField Indica se um campo é válido para ser usado como índice

IsNull Indica se o campo está vazio

KeyFields Campo chave da tabela no relacionamento com LookupDataSet, usado em campos Lookup

Lookup Indica se um campo é Lookup

LookupCache Define se será usado cache para campos Lookup

LookupDataSet DataSet onde está definido o valor do campo Lookup

LookupKeyFields Campo chave do relacionamento em LookupDataSet

LookupResultField Valor do campo, que será mostrado nos controles visuais

ReadOnly Define se um campo é somente para leitura

Required Define se o campo é obrigatório

Size Tamanho físico do campo

Text Texto de edição do campo

Value Acesso direto ao valor do campo

Visible Define se um campo é visível

Eventos Descrição

OnChange Chamado quando o valor do campo é mudado

OnSetText Chamado pelos controles visuais para atribuir o texto digitado pelo usuário ao campo

OnGetText Chamado para formatar o texto de exibição do campo

OnValidate Validação do valor atribuído ao campo, caso o valor não seja válido, gere uma exceção

16

Page 17: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Método Descrição

Assign Atribui um valor de um campo a outro, inclusive nulo

FocusControl Seta o foco para o controle visual ligado ao campo nos Forms

Clear Limpa o conteúdo do campo

O código a seguir mostra alguns exemplos para a utilização das propriedades do TField:

Fields[0] .AsString : = Ísto é uma string’; FieldByName ('Casado’) .AsBoolean : = False; SomaDespesas : = Fields[5] As.Float; NoPedido ; = Fields[3] .AsInteger;

Estão listadas abaixo algumas classes que realmente iremos manipular no tratamento dos campos de uma tabela, são classes descendentes de TField.

TStringField TBlobField TTimeField

TSmallintField TIntegerField TBytesField

TFloatField TWordField TVarBytesField

TCurrencyField TAutoIncField TGraphicField

TBooleanField TBCDField TMemoField

TDateField TDateTimeField

Em alguns desses campos você pode encontrar as propriedades mostradas abaixo, que não estão presentes em TField.

Propriedades Descrição

MaxValue Valor máximo para o campo

MinValue Valor mínimo para campo

DisplayFormat Formato de apresentação do campo, como ,0.00” %” ou ,0.##” Km”

EditFormat Formato de edição do campo

Currency Define se um campo é monetário

DisplayValues Usado com campos Boolean, define o texto para True e False, como Sim;Não

Métodos Descrição

LoadFromFile Carrega o conteúdo do campo de um arquivo

SaveToFile Salva o conteúdo do campo para um arquivo

17

Page 18: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Componente Table O componente Table é um componente TDataSet que comunica com uma tabela de banco de dados através do BDE. A tabela do banco de dados pode ser tanto local ou em um servidor remoto. TTable herda de TDataSet a capacidade de manipular datasets. Ele fornece métodos, tais como Next, First, Last, Edit, SetRange e Insert.

Propriedades do Componente Table Como vimos, muito da funcionalidade do componente Table vem do objeto TDataSet. O componente Table permite utilizar as propriedades, métodos e eventos TDataSet, mas possui diversas propriedades próprias relativas às tabelas de banco de dados. Por exemplo, o componente Table permite que você: • Especifique índices a serem utilizados • Crie um cursor “Linkado” Cursores “Linkados” coordenam dois ou mais componentes DataSet para criar forms master-detail. A tabela a seguir descreve as propriedades mais importantes do componente Table:

Propriedade Descrição

DatabaseName Especifica o seguinte: • O diretório local de um banco de dados que contenha a tabela a ser visualizada • O alias de um banco de dados remoto

TableName Especifica o nome do banco de dados a ser visualizado

Exclusive Controla o acesso de usuário ao banco de dados. Os valores são: • True Assegura que nenhum outro usuário acesse ou modifique a tabela enquanto você a

mantiver aberta • False Permite que outros usuários acessem ou modifiquem a tabela enquanto você a mantiver

aberta. Este é o default.

IndexName Identifica um índice secundário para Table. Você não pode alterar IndexName enquanto a tabela estiver ativa

MasterFields Especifica o nome dos campos ligados ou campos na propriedade MasterFields para criar um cursor “linkado”a uma tabela secundária Para especificar diversos campos, você deve separar os nomes de campos com uma barra vertical (|) .

MasterSource Especifica o TDataSource de onde TTable obterá os dados para a tabela máster

ReadOnly Põe a tabela em modo somente-leitura. Os valores são: • True Previne o sistema de gravar alterações ao banco de dados onde a tabela resida • False Permite que o sistema grave alterações ao banco de dados onde a tabela resida

Criando uma Aplicação Utilizando o Componente Table Este processo é um tutorial de exemplo. Você construirá uma aplicação de exemplo utilizando uma tabela chamada COUNTRY. Esta tabela exibe informação sobre países do mundo inteiro. Ao invés de utilizar o DBNavigator, você utilizará botões padrão e métodos DataSet para fornecer a funcionalidade do DBNavigator. Este tutorial mostra como utilizar: • Os métodos First, Next, Prior e Last • Os métodos BOF e EOF • Os métodos Edit, Insert e Cancel

18

Page 19: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Estágio Processos

1 Adicionar e definir propriedades para os componentes TDataSet

2 Adicionar e definir propriedades para componentes DBGrid e Button

3 Criar event handlers OnClick para componentes Button

4 Executar e testar a aplicação

Passos para o Estágio 1

Passo Ação

1 Abra um novo projeto e grave-o. Quando solicitado, grave a unit como UDSEVENT.PAS e o projeto como PDSEVENT.DPR.

2 Utilizando a página Data Access, adicione o seguinte ao seu form: • Um componente Table • Um componente DataSource

3 Defina as propriedades para os componentes Table e DataSource como segue:

Nome do Componente Propriedade Valor

Table1 DatabaseName TableName Active

DBDEMOS COUNTRY.DB True

DataSource1 DataSet AutoEdit

Table1 False

Passos para o Estágio 2

Passo Ação

1 Utilizando a página Data Control, adicione um componente DBGrid. Arranje os componentes para que seu form esteja similar à figura a seguir:

Usando o componente Table

19

Page 20: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Passo Ação

2 Utilize a tabela a seguir para definir propriedades do DBGrid para que utilizem o componente DataSource do form:

Nome do Componente Propriedade Valor

DBGrid1 DataSource DataSource1

Passo Ação

3 Adicione oito botões ao form, e arranje-os para que seu form esteja similar à figura a seguir:

Montando o aplicativo usando Table

Passo Ação

4 Utilize o Object Inspector para definir as seguintes propriedades aos componentes Button:

Nome do Componente Propriedade Valor

Button1 Caption Primeiro

Button2 Caption Último

Button3 Caption Próximo

Button4 Caption Anterior

Button5 Caption Editar

Button6 Caption Post

Button7 Caption Cancelarr

Button8 Caption Inserir

Passos para o Estágio 3

Passo Ação

1 Digite o código a seguir para os eventos OnClick nos botões apropriados.

20

Page 21: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Nome do Componente Evento Código

Button1 OnClick Table1.First;

Button2 OnClick Table1.Last;

Button3 OnClick if not Table1.EOF then Table1.Next;

Button4 OnClick if not Table1.BOF then Table1.Prior;

Button5 OnClick Table1.Edit;

Button6 OnClick if Table1.State in [dsEdit, dsInsert] then Table1.Post;

Button7 OnClick Table1.Cancel;

Button8 OnClick Table1.Insert;

Passos para o Estágio 4

Passo Ação

1 Compile e grave a aplicação. Execute e teste cada botão para verificar se o método funciona.

2 Quando tiver completado o teste, grave e feche o projeto.

21

Page 22: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

O Componente Query O componente Query permite utilizar comandos SQL para executar o seguinte: • Especificar ou criar datasets que possam ser exibidos • Inserir linhas • Editar a atualizar colunas • Deletar linhas O componente Query gerencia a comunicação com o BDE e serve como interface entre o BDE e os componentes DataSource (TDataSource) em seus forms Como com o componente Table, um componente DataSource é anexado ao componente Query para gerenciar a comunicação entre o componente Data Control e o componente Query. Uma aplicação típica possui um componente DataSource para cada componente Query.

Propriedade do Componente Query A tabela a seguir descreve diversas propriedades importantes do componente Query:

Propriedade Descrição

Active Abre ou fecha uma query. Os valores são: • True Abre uma query, o que faz com que o comando SQL seja executado, como no exemplo:

{Abre a query} Query1.Active : = True;

• False Fecha uma query, como segue:

{Fecha a query} Query1.Active : = False;

Database Name

Identifica o alias do banco de dados ou o drive e diretório de um banco de dados local. A propriedade DatabaseName pode ser definida somente quando a query não estiver ativa, como no exemplo a seguir:

{Fecha o DBDataSet} Query1.Active : = False; Query1.DatabaseName : = ‘Demos’; Query1.Active : = True;

Fields Suportam os campos no componente Query. É uma propriedade somente durante execução e é utilizada para examinar ou modificar um determinado campo, como no exemplo a seguir:

Query1.Fields[3] .AsString : = ÓK’;

DataSource Fornece valores para queries parametrizadas. Uma query parametrizada é uma onde um ou mais valores na condição de seleção não é conhecida

Params Guardam os parâmetros para uma query parametrizada. Uma query parametrizada envolve um ou mais valores na condição de seleção que não são conhecidas até a execução, como no exemplo a seguir:

Select * from Orders Where CustNo = :SomeNo

Esta é uma propriedade de somente-leitura, durante a execução. Consulte o Help Online para maiores informações sobre queries parametrizadas.

SQL Guarda o texto do comando de query SQL

EOF (End of File) BOF (Beginning of File)

Propriedade somente-leitura com valores a seguir: • EOF é True quando você tenta mover para além da última linha do dataset. • BOF é True quando o componente DataSet é aberto, ou quando o ponteiro do TDataSet

da linha atual estiver na primeira linha.

Métodos do Componente Query A tabela a seguir descreve alguns métodos do componente Query:

22

Page 23: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Método Descrição

ExecSQL Executa comando SQL atribuido à propriedade SQL se o comando não retornar dados. Quando estiver inserindo, atualizando ou deletando dados, você deve utilizar este método. Se estiver executando um comando de seleção, utilize o método Open. A seguir um exemplo da utilização do método ExecSQL:

Query1.Close; Query1.Clear; Query1.SQL.Add ( ‘Delete emp where empno = 1010’); Query1.ExecSQL;

Open Abre o componente Query. É equivalente a definir a propriedade Active para True. A seguir um exemplo utilizando o método Open:

Query1.Open;

Close Fecha o componente Query fazendo com que quaisquer atualizações pendentes sejam efetuadas no banco de dados. Chamar Close é equivalente a definir a propriedade Active para False. A seguir mostramos um exemplo utilizando o método Close:

Query1.Close;

Prepare Traduz a propriedade SQL para criar a propriedade Text para Submeter ao servidor. O método Prepare também envia a requisição ao servidor para propósito de otimização, embora nenhum valor parametrizado esteja incluido. A requisição inteira com parâmetros não é submetida até que o método Open ou ExecSQL sejam chamados. Se você não chamar Prepare explicitamente, o Delphi chama Prepare implicitamente quando utilizar o comando em ExecSQL. A seguir um exemplo utilizando o método Prepare:

Query1.Close; Query1.SQL : = ‘Delete emp where empno = : empno’; Query1.Prepare;

Métodos TQuery Herdados de TDataSet O objeto TDataSet fornece ao componente Query uma grande variedade de métodos. Alguns dos mais importantes são mostrados na tabela a seguir:

Método Descrição

First Last Next Prior MoveBy

Permite navegar ou alterar a linha atual do dataset. A seguir um exemplo utilizando diversos destes métodos:

Query1.First While not Query1.EOF do begin {Seu código aqui} Table1.Next; End;

O método MoveBy move um número determinado de linhas. Por exemplo: • Query1.Moveby(3) move 3 linhas para baixo. • Query1.Moveby (-2)move 2 linhas para cima

Insert Edit Delete Append Post Cancel

Permite modificar o conjunto resultante de uma query. O método Insert permite adicionar linhas à tabela, como no exemplo a seguir:

Query2.Insert; Query2.Fields [0] .AsInteger : = 20; Query2.Fields [1] .AsString : = ‘News’; Query2.Fields [2] .AsString : = ‘5 horas’; Query2.Post;

• O método Post faz com que as operações Insert, Update, ou Delete ocorram. • O método Cancel faz com que um Insert, Delete, Edit ou Append não completado seja

cancelado.

SetKey GotoKey

Pesquisa através dos datasets, como segue: • O método SetKey alterna o dataset para o modo de procura. Neste modo, a propriedade

Fields tem uso especial. • O método GotoKey inicia uma procura por um valor que coincida com o valor

23

Page 24: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

encontrado em Fields[n]. Fields[n] contém o valor que você está procurando e que ocorre na primeira coluna da tabela ou dataset. Você pode procurar por valores em outras colunas definindo a coluna correspondente.

O exemplo a seguir mostra a utilização dos métodos SetKey e GotoKey:

Query1.SetKey; Query1.Fields [0] .AsString : = Edit1.Text; Query1.GotoKey;

FreeBookmark GeTBookMark GotoBookmark

Permite criar um marcador em uma linha na tabela ou query e retornar posteriormente para esta linha, como segue: • O método FreeBookmark libera espaço alocado para o marcador • O método GeTBookMark aloca um marcador para a linha atual da tabela. • O método GotoBookmark altera a localização na tabela para a linha indicada por um

marcador alocado préviamente . Os métodos Bookmark utilizam o objeto tipo TBookMark, como no exemplo a seguir:

Var Marker : TBookMark; begin Marker : = Query2.GeTBookMark; Query2.GotoBookmark (Marker); Query2.FreeBookmark (Marker);

Eventos do Componente Query Derivados de TDataSet O componente Query responde aos eventos herdados do objeto TDataSet. A tabela a seguir descreve estes eventos:

Eventos Descrição

OnOpen OnClose OnNewRecord BeforeInsert AfterInsert BeforeInsert AfterEdit BeforePost AfterPost OnCancel OnDelete

Permite construir e controlar o comportamento da aplicação de banco de dados. Por exemplo: • O event handler BeforePost valida os campos de um registro antes de inserir ou

atualizar os dados • O evento AfterPost é útil para gravar um registro de auditoria quando necessário. • O evento OnDelete é útil para escrever código que efetue a deleção em cascata quando

apropriado.

Criando uma aplicação Utilizando o Componente Query Esta seção fornece um aprendizado na utilização do componente Query. O componente Query possui muitas características avançadas. Entretanto, este exemplo focaliza as características básicas deste componente. Este exercício demonstra como utilizar um componente Query para criar um dataset, e métodos TDataSet para executar operações no dataset, envolvendo os seguintes estágios:

Estágio Processo

1 Construir uma aplicação e exibir os dados utilizando um comando SQL

2 Modificar uma aplicação para consultar um banco de dados, baseado no campo CustID

Passos para o Estágio 1 Execute os passos a seguir para construir uma aplicação de clientes e exibir dados do cliente utilizando um comando SQL:

24

Page 25: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Passo Ação

1 Abra um novo projeto e grave-o. Quando solicitado, grave a unit como EX7SQL.PAS e o projeto como EX7P.DPR.

2 Utilizando a página Data Access page da Component Palette, adicione os seguintes ao seu form: • Um componente Query • Um componente DataSource

3 Defina as propriedades dos componentes Query e DataSource, como segue:

Nome do Componente Propriedade Valor

Query1 DatabaseName RequestLive

DBDEMOS True

DataSource1 DataSet Query1

Passo Ação

4 Utilizando a página Data Controls da Component Palette, adicione os seguintes ao seu form: • Um componente DBGrid Um componente DBNavigator

5 Utilize a tabela a seguir para definir propriedades dos componentes DBNavigator e DBGrid para que utilizem o componente DataSource do form:

Nome do Componente

Propriedades Valor

DBGrid1 DataSource DataSource1

DBNavigator DataSource DataSource1

6 Crie um event handler OnActivate para o form utilizando o Object Inspector. Digite o código abaixo no handler OnActivate:

Query1.SQL.Add (‘Select * from customer’); Query1.Open;

Este código adiciona uma instrução SQL à propriedade SQL do componente Query. Você pode definir esta instrução SQL como uma propriedade utilizando o Object Inspector. Após adicionar a instrução SQL, seu event handler deve ser:

Query1.SQL.Add( ‘Select * From Customer’ ); Query1.Open;

7 Quando sua aplicação for compilada satisfatoriamente. grave-a. Depois, execute sua aplicação e teste-a utilizando o Navigator para atualizar e inserir linhas no dataset.

8 Quando tiver terminado, feche a aplicação.

Passos para o Estágio 2

Passo Ação

1 Utilizando a página Standard do Component Palette, adicione os seguintes ao form: • Dois componentes botão • Um componente Edit • Um componente Label

25

Page 26: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

2 Utilize a informação da tabela a seguir para definir propriedades destes componentes:

Nome do Componente Propriedade Valor

Button1 Caption Query

Button2 Caption Exec Query

Edit1 Text Visible

(Empty) False

Label Caption Visible

IdCliente False

Passo Ação

3 Adicione o seguinte código para o evento OnClick do Button1: Edit1.Visible : = True; Label1.Visible : = True;

4 Adicione o seguinte código ao evento OnClick do Button2 Query1.Close; Query1.SQL.Clear; Query.SQL.Add (‘Select * from customer where ‘+’CustNo = ‘+ Edit1.Text); Query.Open; Edit1.Visible : = False; Label1.Visible : = False;

Passo Ação

5 Compile e grave sua aplicação. Execute e teste-a através do seguinte: • Selecione um número de cliente da lista de clientes e dê um clique em Query. • Digite o número e dê um clique em Exec Query para exibir um único cliente no grid.

26

Page 27: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Utilizando o Componente Database Grid Como você já pode ter observado, o componente DBGrid fornece uma maneira conveniente de se exibir diversas linhas de dados de um componente Table ou Query. Sua aplicação pode utilizar o DBGrid para inserir, deletar, editar ou exibir dados de um banco de dados. Combinado com o DBNavigator, o DBGrid permite protipar e exibir rapidamente dados do banco de dados. Até agora, você tem visto exemplos utilizando o componente DBGrid. Uma lista completa das propriedades, métodos e eventos do DBGrid encontram-se no Help Online Este tópico oferece sugestões para: • Definir a propriedade Options do Componente DBGrid • Definir caracteristicas de exibição de campo para o componente DBGrid

Propriedades de Options do DBGrid A figura a seguir mostra um conjunto de propriedades que compõem a propriedade Options do componente DBGrid. O conjunto aparece quando você clica o sinal (+) na frente da propriedade Options.

Opções do DBGrid

Descrição da Propriedade Options Você pode alterar a aparência e comportamento de uma grade alterando valores da propriedade Options, utilizando o Object ou escrevendo código. A tabela a seguir descreve as definições de Options do componente DBGrid:

Propriedade Options Descrição Quando Definido para True

DgEditing O usuário pode editar dados na grade. Quando a propriedade ReadOnly do DataSet for True e dgEditing também for True, os usuários podem utilizar a tecla Insert para inserir uma linha em branco, ou pressionar a tecla de seta para baixo quando posicionado no final da grade para adicionar uma linha em branco, embora não possam digitar texto na nova linha.

DgTitles Os títulos das colunas são visíveis.

DgIndicator Um pequeno ponteiro fica visível para indicar a coluna atual.

27

Page 28: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

dgColumnResize As colunas podem ser reajustadas.

DgColLines As linhas entre as colunas ficam visíveis

DgRowLines As linhas entre as linhas ficam visíveis.

DgTabs Os usuários podem pressionar a tecla Tab e Shift+ Tab para se moverem entre as colunas da grade.

Propriedade Options como Tipo Set A propriedade Options do componente DBGrid é um tipo set. Você pode modificar a propriedade Options utilizando operadores set. As linhas a seguir são comandos Object Pascal válidos:

DBGrid1.Options : = DBGrid1.Options + [dgTitles]; DBGrid1.Options : = DBGrid1.Options - [dgTitles, dgRowLines];

Definindo Características de Exibição de Campo para o Componente DBGrid Geralmente no desenvolvimento de uma aplicação, você precisa controlar o comportamento de campos no componente DBGrid. O comportamento default do DBGrid é determinar dinamicamente o tamanho do campo e permitir ao usuário o uso do mouse para reajustar o tamanho do campo. A chave para obter o controle das características de exibição do DBGrid ou outro componente data-aware é criar uma lista estática de componentes Field. Uma vez criados componentes para cada um dos campos no dataset, você pode definir o seguinte: • Tamanho de exibição • Formato de exibição • Máscara de Edição • Rótulos de exibição

Passos para Definir Tamanho de Exibição Execute os passos a seguir para criar campos de exibição de tamanho fixo no componente DBGrid:

Passo Ação

1 Abra o Fields Editor para o componente TDataSet que será exibido no componente DBGrid.

2 Adicione cada um dos campos de banco de dados que você queira no dataset. Este passo cria componentes TFields estáticos para os campos a serem exibidos no DBGrid.

3 Localize o componente DBGrid no Object Inspector, e defina a opção dgColumnReSize para False. Como alternativa, você pode escrever comandos Object Pascal em sua aplicação para alterar esta propriedade.

4 Altere o tamanho da coluna exibida de uma destas maneiras: -Utilize o mouse para arrastar e reajustar o tamanho das colunas no DBGrid -Defina a propriedade DisplayWidth para cada um dos componentes Field que o Fields Editor adicionou.

Definindo a Propriedade DisplayLabel Uma vez que você utilizou o Fields Editor para gerar um conjunto de objetos TField para o dataset, você pode utilizar o Object Inspector para definir a propriedade DisplayLabel do componente Field. O componente DisplayLabel do componente Field.

Definindo Propriedade DisplayMask Campos, Float, Integer e Date possuem uma propriedade DisplayMask. Você pode utilizar esta propriedade para formatar a exibição em um DBGrid ou outro componente Data Control. Por exemplo, o formato de exibição mm-dd-yy pode ser utilizado para exibir um campo data.

Definindo a Propriedade EditMask Os componentes Field possuem uma propriedade EditMask que você pode definir sempre que digitar dados em um DBGrid ou outro componente Data Control. Para definir uma propriedade EditMask, localize o componente Field no Object Inspector, e clique a propriedade EditMask. O quadro de diálogo Input Mask Editor é exibido, como segue: 28

Page 29: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Para testar sua máscara de edição, digite um valor no campo Test Input.

Editor de Máscara

29

Page 30: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

2. BANCOS DE DADOS RELACIONAIS Existem situações no projeto de um banco de dados, onde é necessário criar relações entre tabelas, visando principalmente evitar inconsistência e duplicação de informações. O modo mais comum de se realizar esta tarefa é através dos bancos de dados relacionais. Os bancos de dados relacionais permitem o relacionamento entre as tabelas através da definição de chaves de acesso. Os bancos de dados também devem conter índices que são utilizados principalmente para agilizar operações de pesquisa e classificação. Os bancos de dados que contém índices para acesso aos dados nele armazenados são denominados de bancos de dados indexados. Os índices em um banco de dados estabelecem uma ordem pré-definida de registros em determinados campos de uma tabela. No Paradox e no DBase, os índices são gerados automaticamente, a partir do momento que se define um campo como chave (key). VANTAGEM DOS BANCOS DE DADOS INDEXADOS: • os bancos de dados devem ser indexados para agilizar operações de pesquisa e classificação sobre os

mesmos, a partir dos campos definidos como chave. DESVANTAGEM DOS BANCOS DE DADOS INDEXADOS:

• a indexação em um banco de dados torna as operações de atualização e inserção mais lentas.

Chaves de Acesso As chaves são campos do banco de dados para agilizar sua manipulação. As chaves podem ser classificadas como: • chaves primárias: estabelecem as chaves principais de acesso aos campos de uma tabela; • chaves secundárias: estabelecem chaves auxiliares de acesso aos campos de uma tabela; • chaves estrangeiras: estabelecem chaves de acesso aos campos de outras tabelas.

Chaves Primárias As chaves primárias são as principais chaves de acesso a um banco de dados. As principais características das chaves primárias são: • definindo-se uma chave como primária garante-se que ela não estará duplicada dentro de um banco

de dados; • a definição de chaves primárias, em bancos de dados dBase e Paradox, cria automaticamente um

índice para acesso aos dados das chaves; • a definição de chaves primárias faz com que o banco de dados seja automaticamente ordenado pelas

chaves; • para definir uma chave como primária em bancos de dados DBase e Paradox, basta colocar um * no

campo Key, utilizando o Database Desktop; É importante ressaltar que um banco de dados pode ter vários campos definidos como chaves primárias.

Chaves Secundárias As chaves secundárias estabelecem chaves auxiliares de acesso aos campos de uma tabela. Elas devem ser utilizadas em campos onde se fazem pesquisas ou classificações eventuais sobre uma tabela. Para se definir uma chave secundária, através do Database Desktop, deve-se seguir os passos abaixo:

1. Abra o Database Desktop e a tabela onde se quer definir uma chave secundária. 2. Entre na opção Restructure Table. 3. Selecione, na caixa Table properties, a opção Secondary Indexes. 4. Selecione o botão Define.

30

Page 31: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

5. Selecione o campo que quer utilizar como chave secundária, de modo que ele apareça na lista Indexed Fields.

6. Clique em OK, dê um nome a nova chave secundária e clique novamente em OK. 7. Salve a tabela utilizando o botão Save.

Os campos definidos como chaves secundárias também possuem índices relacionados a eles.

Chaves Estrangeiras As chaves estrangeiras permitem o acesso e validação a outros banco de dados. Suas principais características são:

• as chaves estrangeiras permitem que se faça o relacionamento entre os bancos de dados; • as chaves estrangeiras, em um banco de dados, armazenam chaves de outros bancos de dados; • as chaves estrangeiras devem ter o mesmo tipo de sua correspondente chave em um outro banco de

dados. Para se definir uma chave estrangeira, através do Database Desktop, deve-se seguir os passos abaixo:

1. Abra o Database Desktop e a tabela onde se quer definir uma chave estrangeira. 2. Entre na opção Restructure Table. 3. Selecione, na caixa Table properties, a opção Referential Integrity. 4. Selecione o botão Define. 5. Selecione o campo que quer utilizar como chave estrangeira na coluna Fields e clique na seta para a

direita para definir o campo Child Fields. 6. Selecione a tabela com a qual quer estabelecer o relacionamento e clique na seta para a esquerda

para definir o campo Parent’s Key. 7. O relacionamento está estabelecido entre as chaves definidas em Child Fields e Parent’s Key, que

devem ter o mesmo tipo. 8. Clique em OK, dê um nome a nova chave secundária e clique novamente em OK. 9. Salve a tabela utilizando o botão Save.

A restrição desta definição é que o relacionamento pode ser definido apenas com o primeiro campo da outra tabela. Em tabelas Paradox para ser definida como chave estrangeira uma chave tem que ser definida como primária ou secundária.

Consistência e Integridade dos Dados A maioria dos bancos de dados relacionais possue recursos para consistir e tornar íntegro os dados armazenados em suas tabelas. Desta forma, qualquer ferramenta que o usuário utilizar para acessá-lo é obrigada a respeitar as regras, mantendo a integridade dos dados. Os recursos de consistência variam de banco para banco, mas pode-se definir conceitualmente algumas categorias de integridade como: integridade referencial, domínios e regras do negócio.

Integridade Referencial Integridade referencial é um conjunto de regras e de consistências entre os registros de duas tabelas que se relacionam. Como foi visto no modelo relacional, quando duas tabelas se relacionam, a chave primária de uma é copiada para a outra e se esses dados forem alterados ou excluídos da tabela original é necessário verificar o que será feito com os dados e registros duplicados na outra tabela. Quando se define uma integridade referencial, está se definindo o procedimento que será tomado quando esses processos ocorrerem. Sejam duas tabelas “A” e “B” que se relacionam através de uma coluna “c” que é a chave primária de “A” e portanto foi repetida em “B” para se fazer o relacionamento. Quando se define uma integridade referencial para esse relacionamento, está se definindo que a coluna “c” da tabela “B” só pode conter valores já cadastrados na coluna “c” da tabela “A”.

31

Page 32: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

32

Tabela B *a b c

Tabela A

d e . .

*c

Integridade Referencial

Existem três formas de se manter essa regra quando registros da tabela “A” são excluídos: • Restrict: Define que se o valor da coluna “c” de “A” existir em algum registro de “B”, o registro não poderá

ser excluído e uma mensagem de erro retornará para a aplicação; • Cascade: Define que se o valor da coluna “c” de “A” existir em algum registro de “B”, todos os registros que

possuírem esse valor serão também excluídos; • Set Null: Define que se o valor da coluna “c” de “A” existir em algum registro de “B”, os valores de “c” em

todos os registros serão transformados para “Null”; Em todos os casos, se o usuário tentar inserir um registro em “B” com um valor de “c” que não exista na tabela “A”, um erro será reportado à aplicação. Alguns bancos, também permitem fazer o mesmo tratamento quando a chave da tabela for alterada, ao invés de excluída. Entretanto, essa alteração de chaves não deve ser um processo comum nas aplicações, sendo normalmente proibidas. Os bancos de dados possuem formas diferentes de disponibilizar esses serviços. Alguns possuem até mais de uma forma de fazer o mesmo processo. Mas de maneira geral existem duas possibilidades de implementação:

Page 33: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

3. FORM WIZARD O Form Wizard é uma ferramenta do DELPHI que permite criar um formulário padrão para a manipulação de banco de dados. Sua principal vantagem está na automatização do processo de criação de formulário, o que permite ganhar tempo no desenvolvimento da aplicação. EXEMPLO: neste exemplo será criado um formulário para manipular os dados da tabela criada no exemplo apresentado no Database Desktop. PASSO 1 Inicie um novo projeto, clicando na opção File no menu principal do DELPHI, e, em seguida, na opção New Application. Neste momento será aberto um novo projeto. PASSO 2 Clique na opção Database no menu principal do DELPHI, e, em seguida, na opção Form Wizard. Neste momento será aberto uma tela para iniciar o processo de criação do formulário. PASSO 3 Na tela inicial do Form Wizard deve-se selecionar o tipo do banco de dados e o tipo do conjunto de dados. Os tipos de banco de dados são:

• Simple: banco de dados simples, onde todos os dados estão armazenados em uma mesma tabela. • Master/Detail: banco de dados relacional Já o tipo de conjunto de dados pode ser: • TTable: quando os dados forem manipuladas diretamente na tabela. • TQuery: quando os dados forem manipulados a partir de uma consulta. Para o exemplo apresentado selecione Simple Form, TTable e em seguida clique no botão Next. Neste instante deverá aparecer a tela para seleção do banco de dados.

PASSO 4 Esta tela permite que se selecione a tabela onde estão armazenados os dados. Selecione a tabela criada no exemplo do Database Desktop e pressione o botão Next. Neste instante deverá aparecer a tela de seleção dos campos a serem editados. PASSO 5 Esta tela permite selecionar os campos que poderão ser editados. Todos os campos que estiverem na coluna Ordered Selected Fields poderão ser manipulados no formulário. Selecione todos os campos (botão >>) e clique em Next. Neste instante deverá aparecer a tela de layout do formulário. PASSO 6 Esta tela permite selecionar a forma de apresentação dos dados, que poderá ser na Vertical, Horizontal, ou em linhas de grade. Selecione a opção Horizontal e clique em Next. Neste instante deverá aparecer a tela final de criação do formulário. PASSO 7 Na última tela da criação do formulário deve-se definir se o formulário é o formulário principal da aplicação e se na geração do formulário deve ser criado ou não um Data Module. Ative a opção Generate main form e selecione a opção Form and Data Module e clique no botão Finish. Neste instante deve aparecer na tela o formulário criado pelo Form Expert, de acordo com as definições selecionadas (Erro! A origem da referência não foi encontrada.).

33

Page 34: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Formulário criado com o Form Wizard.

34

Page 35: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

4. Componente Database Lookup Um database lookup, ou tabela de busca é o processo de encontrar texto descritivo de um valor codificado. Uma situação comum onde tabelas de busca seriam utilizadas, seria quando você está editando o input de usuário e quiser exibir uma informação mais significativa, e não valores codificados. O Delphi fornece dois componentes para buscar valores em uma tabela de banco de dados, ou editar o input contra um valor em uma tabela. Eles são os seguintes: • Componente DBLookuplistBox • Componente DBLookupComboBox O termo lookup em cada nome de componente refere-se às tabelas de busca. O termo lookup tables refere-se às tabelas que contém informação descritiva sobre um valor codificado. Esta seção discute a utilização destes componentes. Eles se encontram na página Data Controls da Component Palette.

Componente DBLookuplistBox O componente DBLookuplistBox é um componente ListBox data-aware projetado para buscar valores em uma tabela baseado no valor de uma segunda tabela. O DBLookuplistBox contém um conjunto finito de dados, o usuário deve selecionar uma das opções da lista. Um DBLookuplistBox permite exibir um conjunto de opções baseado no valor em outra tabela. O componente DBLookuplistBox difere do componente DBListBox porque permite coordenar o valor selecionado do DBLookuplistBox com a linha corrente de outra tabela do banco de dados.

Componentes DBLookupComboBox O componente DBLookupComboBox é um componente ComboBox dataware similar ao BDLookupListBox, exceto que um usuário pode selecionar um valor na lista ou digitar um novo valor. Um ComboBox de onde o DBLookupComboBox é derivado combina as capacidades de um ListBox com as capacidades de um componente Edit.

Adicionando um Componente Database Lookup a um Form Quando você adiciona um componente DBLookuplistBox ou DBLookupComboBox ao seu form, assumimos que: • Você possui uma aplicação de banco de dados • O form na aplicação possui pelo menos um DataSource e um componente derivado de TDataSet sendo

utilizado para exibir informações do banco de dados Adicionar um componente database lookup envolve o seguinte processo:

Estágio Processo

1 Adicionar o componente database lookup e ligá-lo a um componente DataSource existente e propriedade DataField

2 Adicionar um novo componente Query ou Table (TDataSet) e DataSource, e utilizar este DataSource para buscar valores codificados no primeiro DataSource

Passos para o Estágio 1 Execute os passos a seguir para adicionar um componente DBLookuplistBox ou DBLookupComboBox a um data source existente:

Passo Ação

1 Adicione um componente database lookup em seu form.

2 Defina a propriedade DataSource a um componente DataSource que exista no form e que contenha o valor que você esteja procurando.

3 Defina a propriedade DataField ao campo que necessite de busca.

35

Page 36: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Passos para o Estágio 2 Execute os passos a seguir para anexar o componente DBLookuplistBox ou DBLookupComboBox à tabela de busca:

Passo Ação

1 Adicione um componente TDataSet utilizando um componente Table ou Query que corresponda à tabela de busca.

2 Defina a propriedade DatabaseName do novo componente TDataSet.

3 Execute um dos seguintes: • Defina a propriedade TableName do novo componente Table. • Entre com um query para a propriedade SQL do componente query.

4 Adicione um novo componente DataSource, e defina a propriedade DataSet ao novo componente TDataSet.

5 Defina a propriedade ListSource de componente DBLookup ao novo componente DataSource.

6 Defina a propriedade KeyField ao valor chave da tabela de busca.

7 Defina a propriedade ListField ao campo que você queira exibir no componente DBLookuplistBox.

Criando uma Aplicação Utilizando um Componente Database Lookup A melhor maneira de se aprender a utilizar um componente DBLookup é através de um exemplo. Nesta seção, você utilizará um componente DBLookuplistBox para exibir um nome de empresa baseado no campo CustlD encontrado na tabela Orders.

Passos O processo do tutorial envolve os seguintes estágios:

Estágio Processo

1 Criar um form que exiba uma lista estática dos campos de uma tabela de banco de dados utilizando um componente Table, DataSource, DBGrid e DBNavigator

2 Adicionar e conectar um componente TDBLookuplistBox à aplicação

3 Adicionar código para coordenar ações do componente TDBLookuplistBox quando o sistema insere ou atualiza uma linha

Passos para o Estágio 1 Execute os passos a seguir para criar um form que exiba campos selecionados da tabela Orders:

Passo Ação

1 Abra um novo projeto e grave-o Quando solicitado, grave a unit como EX7CMAIN.PAS e o projeto como EXAMP7.DPR.

2 Utilizando a página Data Access da Component Palette, adicione um componente Table e DataSource ao seu form.

3 Utilizando a página Data Controls, adicione os seguintes ao seu form: • Um componente DBGrid • Um componente DBNavigator

4 Defina as seguintes propriedades para cada componente, como mostrado na tabela:

Nome do Componente

Propriedade Valor

Table1 Database Name TableName

DBEMOS ORDERS.DB

36

Page 37: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Active True

DataSource1 DataSet AutoEdit

Table1 False

DBGrid1 DataSource DataSource1

DBNavigator DataSource DataSource1

Passo Ação

5 Utilize o Fields Editor para adicionar os seguintes campos ao dataset Table1: • OrderNo • CustNo • SaleDate • ItemsTotal • AmountPaid

6 Arranje os campos no Fields Editor para que OrderNo seja o primeiro campo e CustNo seja o segundo.

7 Compile e grave a aplicação.Execute e teste-a.

Passos para o Estágio 2 Execute os passos a seguir para adicionar um componente DBLookuplistBox à aplicação:

Passo Ação

1 Utilizando a página Data Controls da Component Palette, adicione um componente DBLookuplistBox ao seu form:

2 Utilize o Object Inspector para definir as seguintes propriedade do componente DBLookuplistBox:

Nome do Componente

Propriedade Valor

DBLookuplistBox1 DataSource DataField

DataSource1 CustNo

Passo Ação

3 Adicione um novo componente Table e DataSource ao seu form. Defina as propriedades para cada componente, como mostrado na tabela a seguir:

Nome do Componente

Propriedade Valor

Table2 DatabaseName TableName Active

DBDEMOS CUSTOMER.DB True

DataSource2 DataSet Table2

Passo Ação

4 Utilize o Fields Editor para adicionar os seguintes campos ao dataset Table2: • CustNo • Company

5 Conecte o componente DBLookuplistBox ao segundo DataSource utilizando a tabela a seguir:

37

Page 38: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Nome do Componente

Propriedade Valor

DBLookuplistBox1 ListSource KeyField ListField

DataSource2 CustNo Company

Passo Ação

6 Compile e grave a aplicação. Execute e teste-a. O componente DBLookuplistBox destaca a empresa que corresponde ao valor de CustNo na linha do DBGrid.

Passos para o Estágio 3 Este código de event handler permitirá definir o valor de CustNo durante o modo de edição ou inserção através de um duplo-clique no componente DBLookuplistBox. Execute os passos a seguir para adicionar um event handler para os eventos de DBLookuplistBox, OnDblClick, ou OnClick:

Passo Ação

1 Adicione as instruções a seguir no evento OnDblClick do componente DBLookuplistBox: if Table.State in [dsEdit, dsInsert] then Table1CustNo.Value := Table2CustNo.Value;

2 Compile e grave sua aplicação. Execute e teste-a alternando a aplicação entre o modo de edição e inserção e utilizando o DBLookuplistBox para definir o valor de CustNo na tabela Orders.

38

Page 39: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

5. CRIANDO UM APLICATIVO MASTER/DETAIL No grupo de programas do Delphi, encontramos o utilitário Database Desktop, que permite a criação e manipulação de banco de dados de diversos formatos. O nosso exemplo gerenciará duas tabelas. Uma com o cadastro dos clientes e outra com as vendas realizadas para estes clientes. Execute o Database Desktop, selecionando a opção Database Desktop no menu Tools.

O Database Desktop

Crie uma nova tabela como mostra a figura a seguir.

Criando uma tabela

39

Page 40: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Escolha o tipo Paradox 7. Aparecendo então a janela Create Paradox 7 Table.

Tipo da Tabela Criada

Digite o nome para o primeiro campo (CODIGO) e mude para tipo de campo (Type) usando a tecla Tab. Com o campo Type selecionado, de um clique com o botão direito do mouse nele, para ser exibido o menu pop-up com todos os valores para o tipo de campo. As letras sublinhadas correspondem à letra de atalho para cada tipo de dado. O nosso campo CODIGO será definido como tipo Alpha. Apesar de ser um campo com números nós não iremos realizar nenhum cálculo matemático com ele, por isso o definimos como Alpha.

Criando os campos da tabela

O campo CODIGO será a nossa chave primária para a identificação dos clientes na tabela Clientes. Para definir um campo como chave primária, pressione qualquer tecla quando o campo Key estiver selecionado, marcando este campo com um * - asterisco.

40

Page 41: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

41

Tornando o Campo CODIGO Chave primária

Dê continuidade entrando com outros campos, seguindo o modelo apresentado abaixo.

Criando os Demais Campos

Page 42: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Salve-a como Clientes.db.

Salvando a Tabela Paradox

Logo após, abra uma nova tabela no mesmo formato, e construa-a como mostrado abaixo.

Criando a Tabela Vendas

Para que a tabela Vendas se relacione com a tabela Clientes, deveremos definir o campo CODIGO como índice secundário na tabela Vendas. No ComboBox Table properties, selecione a opção Secondary Indexes e clique no botão Define..., aparecendo o quadro de diálogo Define Secondary Index. Na janela Define Secondary Index, selecione o campo CODIGO e dê um clique na seta para introduzi-lo como campo índice, e finalmente dê um clique no botão OK para aceitar a opção. Será então solicitado um nome para este índice, digite INDCODIGO.

42

Page 43: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Definindo Índices Secundários

Salvando os Índices

Salve a tabela como Vendas.db. Saia do Database Desktop, através do menu File, opção Exit. O Delphi possui o assistente Form Wizard para a construção de formulários de acesso a Banco de Dados, nós iremos utilizá-lo para construirmos o nosso projeto, que utiliza as tabelas de Clientes e Vendas construídas anteriormente. Volte ao Delphi, e exclua o formulário Form1 que o Delphi cria junto com um novo projeto. No menu Project,

escolha a opção Remove from Project..., ou o botão ( ) na barra de ferramentas, e exclua Form1 não salvando o arquivo. Pois o Form Wizard criará um novo formulário automaticamente.

Removendo o form do projeto

43

Page 44: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Excluído o formulário, inicie o wizard escolhendo a opção Form Wizard do menu Database. O Database Form Wizard é o assistente para a criação de Formulários envolvendo banco de dados. Este assistente ajudará na definição dos campos a serem mostrados e o layout do formulário, além de incluir um componente DBNavigator, que será usado para a navegação entre os registros das tabelas.

DBNavigator

O nosso primeiro formulário terá duas divisões, uma para cada tabela. A primeira conterá os dados relativos a um cliente, e a segunda as compras realizadas por este cliente. Inicie o Form Wizard, seguindo as opções mostradas nas figuras a seguir; pressionando o botão Next para continuar com o assistente.

Iniciando o Form Wizard

44

Page 45: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Estas opções criam um formulário com duas divisões, usando componentes TTable. Um componente TTable realiza a conexão entre o formulário e uma tabela do banco de dados. Ele é um componente visível somente em tempo de projeto - semelhante ao componente TTimer.

Tabela Master Inclua a tabela Clientes.db, como sendo a master query. Ou seja, a tabela que irá comandar a apresentação do dados.

Incluindo a tabela Clientes como Master Query

Selecione o botão >> para incluir todos os campos da tabela Clientes.db no formulário.

Incluindo Todos os Campos

45

Page 46: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

A opção Vertical posiciona os campos dentro do formulário, um acima do outro.

Selecionando a Opção Vertical para Mostrar os Campos

Alinhamento Left, posiciona as legendas ao lado esquerdo dos quadros de Edit.

Escolhendo o Alinhamento Left (Esquerdo)

46

Page 47: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Tabela Detail Defina a tabela Vendas.db como a tabela de detalhes.

Definindo a Tabela Vendas Como Detalhe

Inclua todos os campos da tabela Vendas, e a seguir, escolha o formato Grid para a apresentação da tabela Vendas.

Mostrando os Campos do Detalhe em Grid

Selecione os campos que farão a ligação entre as duas tabelas, escolhendo INDCODIGO como índice. Em Detail Fields e Master Fields, selecione o campo CODIGO como campo de junção em ambas as tabelas e pressione Add. Como mostrado a seguir.

47

Page 48: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

48

Fazendo a Ligação entre as Tabelas

Concluindo a Ligação entre Tabelas

Pressione Next e finalize o Form Wizard. O seu formulário estará como a figura a seguir.

Page 49: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

49

Resultado do Form Wizard

Alterando as propriedades de alguns componentes do formulário. Comece alterando o tamanho do Panel3 referente aos dados dos clientes. E redesenhe o formulário como a figura abaixo.

Redesenhando o Formulário Principal

Page 50: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Para formatar a entrada de dados, ou seja, definir o formato do dado, para a tabela Clientes.db, dê um clique duplo em Table1 para acessar o editor de campos (Fields Editor). Selecione o campo CEP e no Object Inspector, procure a propriedade Edit Mask. Esta propriedade abre o quadro de diálogo Input Mask Editor onde poderemos escolher uma máscara para o campo CEP, escolha Long Zip Code e na caixa Input Mask elimine um dígito 9, como mostra as figuras a seguir.

Configurando a Máscara do Campo CEP

Mascarando o Campo CEP

Faça o mesmo para o campo Telefone, escolhendo a máscara Phone. Feche a Input Mask Edit. Selecione o campo CODIGO em Table2, e mude a propriedade Visible:=False, para não aparecer o código do cliente no componente DBGrid, pois ele já será exibido por um componente Edit. Selecione o EditEstado e altere a propriedade Charcase:=ecUpperCase, para que os caracteres neste TEdit sejam apresentados em maiúscula. Insira um botão BitBtn no Formulário com as seguintes definições de propriedades: 1 - Caption:=Sai&r; Kind:=bkCLose A propriedade Kind do BitBtn determina qual desenho será mostrado na face do botão. Esta propriedade também implementa algumas funções ao botão eliminando linhas de código, neste caso não será necessário nenhuma linha de código para fechar o formulário. Finalmente, mude a propriedade Active dos dois componentes TTable (Table1 Table2) de False para True. Isto tornará o Table ativo tanto em tempo de projeto quanto em tempo de execução. Ao ativarmos o Table, os controles TEdit mudarão seu conteúdo, passando a exibir o primeiro registro da tabela a eles ligada.

50

Page 51: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Dê o nome de frmClientes ao Formulário e salve como frmClientesUnt.pas.

O formClientes Após as Mudanças

O próximo formulário será construído manualmente, sem o uso do Form Wizard. Não utilizaremos o Form Wizard apenas por questões didáticas, mas este novo Formulário também poderia ser construído utilizando este assistente. Este segundo formulário servirá para cadastrar vendas. O usuário selecionará um nome de cliente já cadastrado, a partir de um quadro combo, digitará a data da venda e escolherá um produto, através de botões de opção, definindo também a quantidade de itens de um mesmo produto e o valor total da venda.

Insira um novo formulário ao projeto escolhendo a opção New Form do menu File ou o botão ( ). Monte este novo formulário utilizando os componentes descritos na figura abaixo.

Fazendo o Formulário de Vendas

Altere as propriedades, de alguns componentes, indicadas na tabela a seguir:

51

Page 52: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Componente Propriedade Valor

Table1 DatabaseName C:\Curso Delphi 5

TableName Vendas.db

Name tblVendas

Active True

DataSource1 DataSet tblVendas

Name dsrVendas

Table2 DatabaseName C:\Curso Delphi 5

TableName Clientes.db

Name tblClientes

Active True

DataSource2 DataSet tblClientes

Name dsrClientes

DbNavigator DataSource dsrVendas

Name navVendas

ShowHint True

Selecione todos os TDBEdit, dando um clique em cada um enquanto pressiona a tecla Shift, e altere a propriedade DataSource de todos ao mesmo tempo para dsrVendas. Depois selecione um por vez e altere a propriedade DataField correspondente a cada TEdit. Dê um clique duplo em tblVendas para editar o campo Data. Repare que a janela Fields Editor aparece vazia sem nenhum campo listado. Clique com o botão direito do mouse no Fields Editor e escolha a opção Add Fields..., selecione todos os campos e pressione Ok, para inserir todos os campos da tabela Vendas.db no Fields Editor.

Adicionando os Campos da Tabela Vendas

Voltando ao Fields Editor, selecione o campo DATA e altere o formato da propriedade EditMask para Date. Após a inserção de todos os campos da tabela Vendas no componente tblVendas, as propriedades destes campos podem ser acessadas diretamente através do Object Inspector. Como ilustra a figura a seguir.

52

Page 53: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Acessando os Campos Diretamente do Object Inspector

O componente DBLookupComboBox, exibe os valores de um campo em uma lista, onde o usuário poderá escolher um valor para este campo. Os valores exibidos pertencem a uma tabela e quando o usuário fizer uma escolha, o valor escolhido será vinculado a uma outra tabela. No formulário que estamos projetando - Vendas, o nome dos clientes virá da tabela Clientes e quando inserirmos a venda, o nome do cliente escolhido será vinculado a esta venda na tabela Vendas através da chave primária CODIGO. Portanto o DBLookupComboBox trabalha com duas tabela simultaneamente, uma que fornece os dados para a lista e outra que está associada ao DbLookupComboBox. A tabela abaixo explica as propriedades relativas a esta vinculação.

Propriedade Uso

DataSource Indica qual tabela associada.

DataField Indica o campo associado.

ListSource Determina a tabela que fornecerá os dados para a lista.

KeyField Indica qual o campo da tabela acima será usado como vínculo.

ListField Indica qual campo será mostrado na lista do quadro combo.

Siga a tabela abaixo para determinar as propriedades do nosso DBLookupComboBox.

Propriedade Valor

Data Source dsrVendas

Data Field CODIGO

ListSource dsrClientes

KeyField CODIGO

ListField NOME

A lista de clientes será vinculada através do campo CODIGO mas estará exibindo ao usuário, o campo NOME. O componente DBRadioGroup apresenta uma série de opções pré-definidas a serem selecionadas pelo usuário, contendo um botão para cada opção. Estas opção são determinadas pela propriedade Items. O valor do campo na tabela associada ao DBRadioGroup, será o mesmo valor do botão selecionado. Selecione o DBRadioGroup e edite a propriedade Items, configurando três opção para produtos vendidos, seguindo o modelo a seguir.

53

Page 54: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Configurando o DBRadioGroup com 3 RadioButtons

Altere outras propriedades conforme a tabela mostrada abaixo:

Propriedade Valor

DataSource dsrVendas

DataField PRODUTO

Columns 3

Caption vazia

Salve este Formulário com o nome de frmVendasUnt.Pas. O Formulário final é mostrada abaixo.

O Formulário frmVendas Finalizado

O próximo formulário será a abertura do programa. A partir dele serão chamados os dois formulários construídos anteriormente. Acrescente um formulário vazio File e New Form, e construa-o da seguinte forma:

54

Page 55: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

55

O Formulário de Apresentação frmControle

A propriedade Hint dos SpeedButtons, contém o texto que será mostrado quando o mouse ficar parado por alguns instantes sobre o botão. Define ShowHint:=True, para ativar esta função. Com isto concluímos a construção de nossa interface gráfica com o usuário. Salve o formulário com o nome frmControleUnt.pas Temos então em nosso projeto três formulários - frmControle, frmClientes e frmVendas. Todos foram salvos no disco com o mesmo nome da sua propriedade Name mais "Unt". Começaremos o código pelo frmControle. implementation uses frmVendaUnt, frmClientesUnt; {$R *.DFM} procedure TfrmControle.SpeedButton3Click(Sender: TObject); begin Close; end; procedure TfrmControle.SpeedButton2Click(Sender: TObject); begin frmVenda.Show; end; procedure TfrmControle.SpeedButton1Click(Sender: TObject); begin frmClientes.Show; end; Código para frmVendas.

Page 56: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

procedure TfrmVenda.BitBtn1Click(Sender: TObject); begin frmVenda.Hide; {o método Hide esconde o Formulário, mas não a elimine da memória, enquanto que Close retira o Formulário da memória } end; Antes de compilar o projeto, verifique se o formulário inicial do programa é mesmo o frmControle. No menu Project do Delphi, escolha a opção Option..., e defina como o Main Form o formulário frmControle.

Colocando o frmControle como o Formulário Principal

Execute o programa pressionando F9.

56

Page 57: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

6. RELATÓRIOS Para a geração de relatórios no Delphi usamos as ferramentas do QuickReport presentes na paleta QReport da barra de ferramentas. Com estes controles poderemos construir relatórios que serão compilados diretamente em nosso projeto sem a necessidade de carregar outras ferramentas de relatório. Poderemos também incluir código a vários eventos relatórios proporcionando uma grande flexibilidade em nossos projetos. O Delphi nos proporciona alguns modelos de relatórios, também um assistente para a criação destes relatórios. Selecione File | New | Form e observe que existem três modelos de relatórios:

Modelos de Relatórios

• QuickReportLabels - Utilizado na criação de etiquetas.

• QuickReport List - Permite a criação de relatórios simples, a partir de dados de uma tabela ou query.

• QuickReport Master/Detail - É um modelo de relatório que obtém dados a partir de duas tabelas. Primeiro vamos criar um relatório com as informações clientes partindo da tabela Customer.db. Na caixa de diálogo New Items, escolha QuickReport List.

QuickReport List

57

Page 58: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

O Delphi nos apresenta um modelo de relatório com alguns componentes já inseridos. Um dos tipos destes componentes são as bandas, elas nos dão funcionalidade como títulos, cabeçalhos, rodapés, detalhes, e sub-detalhes para dados do relatório - representam o componente QRBand. Outros componentes que iremos utilizar são o QRLabel e o QRDBTex. O primeiro exibe informações estáticas no relatório, enquanto o segundo exibe informações dinâmicas vindas do banco de dados, pois está ligado a um campo de determinada tabela.

Construção de um Relatório Simples Repare que o formulário aberto pelo Delphi é do tipo TQRListForm, ou seja, é um formulário específico para relatórios de lista. Selecione o formulário e mude as seguintes propriedades: Name = ClientesRep ReportTitle = Informações de Clientes O componente Table presente no relatório, recebeu o nome de MasterTable e ele será nossa fonte de informações do banco de dados. Altere suas propriedades: DatabaseName = DBDemos TableName = Customer.db Na segunda faixa - ColumnHeader - coloque mais dois (já possui um) QRLabel e altere suas legendas para Nome, Endereço e Telefone. Na terciera faixa - Detail - posicione três QRDBText em baixo das legendas da faixa anterior, definindo a propriedade DataSet como MasterTable para as três, e as propriedades DataField como Company, Addr1 e Phone. Posicione os controles de forma que seu formulário de relatório se pareça com a figura a seguir.

O Relatório Configurado

Este formulário possui um pop-menu que nos dá acesso a uma caixa de diálogo onde poderemos além de outras coisas, configurar a apresentação do nosso relatório e também a opção de visualização antes dele estar vinculado ao aplicativo. As opções são: Report Settings e Preview. Faça uma visualização do relatório e, se tudo estiver de acordo com o seu gosto, inclua um botão na página Clientes do nosso projeto, com o seguinte código para exibir o relatório. Não se esquecendo de incluir o nome da unidade do relatório na seção uses do formulário principal. procedure TForm1.RelatorioBtnClick(Sender: TObject); begin ClientesRep.Preview; end;

58

Page 59: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Construção de um Relatório Master/Detail Abra um novo relatório, mas desta vez como Master/Detail.

Relatório Master/Detail

Este novo formulário possui a mais, duas tabelas, um DataSource e uma faixa de sub-detalhes em comparação ao anterior. Ele também pertence a outro tipo de componente o TQRMDForm, sendo um formulário específico para a construção de relatórios Master/Detalhe. Altere as seguintes propriedades do formulário: Name = VendasRep ReportTitle = Vendas As duas tabelas estão nomeadas como MasterTable e DetailTable, e o DataSource como MasterDS. O DataSource está presente apenas para criar uma vinculação entre as tabelas. Altere suas propriedades associando-as às tabelas Customer.db e Orders.db, e tornando-as ativas. Vá até a DetailTable e selecione a propriedade MasterFields para exibir a caixa de diálogo Field Link Designer, vista anteriormente no curso, utilizada para a vinculação de tabelas. Vincule as duas tabelas pelo índice CustNo.

A tabela de Detalhe

Na banda Column Header, coloque dois componentes QRLabel com as legendas Nome do Cliente e Código. Na banda Detail, insira dois QRDBText associados aos campos Company e CustNo da MasterTable. Aumente a largura desta faixa, e inclua mais dois QRLabel com as legendas Número do Pedido e Valor Pago. Na quarta banda - SubDetail - coloque dois QRDBText, para os detalhes das compras, associados aos campos OrderNo e AmountPaid da tabela Orders.db - DetailTable.

59

Page 60: Apostila Delphi e Banco de Dados Local (Excelente)

AApplliiccaaççõõeess ppaarraa BBaannccoo ddee DDaaddooss LLooccaall _______________________________________________________________________________

Altere a propriedade DataSet da banda SubDetail para DetailTable. Ao final, o seu formulário deverá se parecer com o da figura a seguir:

Relatório Master/Detail Final

Inclua mais um botão no formulário principal para a exibição deste último relatório. E teste o seu programa. Os relatórios construídos anteriormente também poderiam ser construídos partindo-se de um formulário comum, desde que incluíssemos o componente QuickRep neste formulário, dimensionando-o na área de cliente de acordo com as necessidades. E a partir daí colocaríamos os demais componentes existentes de modo semelhante nos relatórios construídos como exercícios.

60