tutorial c++ builder

24
Tutorial: Utilizando o Formulário DataModule Faculdade de Filosofia Santa Dorotéia Tecnologia em Informática – Programação IV Autor: Márcio Gil Maldonado Atualização: 12/04/2004

Upload: eduardo-kaio-michelle

Post on 31-Dec-2014

179 views

Category:

Documents


13 download

TRANSCRIPT

Page 1: Tutorial C++ Builder

Tutorial: Utilizando o Formulário DataModule

Faculdade de Filosofia Santa Dorotéia

Tecnologia em Informática – Programação IV

Autor: Márcio Gil Maldonado

Atualização: 13/04/2004

Page 2: Tutorial C++ Builder

ÍndiceI. Objetivo........................................................................................................................................................4II. Pré-requisitos..............................................................................................................................................4III. Notação......................................................................................................................................................4IV. Dicionário de dados...................................................................................................................................4V. Criando o Programa....................................................................................................................................5VI. Componentes do DataModule...................................................................................................................5

A. O Componente TDatabase......................................................................................................................6B. O Componente TUpdateSQL.................................................................................................................6C. O Componente TQuery...........................................................................................................................7D. O Componente TDataSource..................................................................................................................7

VII. Inserindo Campos....................................................................................................................................7A. A Classe TField......................................................................................................................................8

VIII. Codificando os Eventos da Tabela.........................................................................................................8A. O Evento TabUf→BeforeInsert..............................................................................................................8B. O Evento TabUf→BeforeEdit................................................................................................................8C. O Evento TabUf→BeforeDelete.............................................................................................................9D. O Evento TabUf→BeforePost................................................................................................................9E. O Evento TabUf→AfterPost.................................................................................................................10

IX. A Janela de Detalhes...............................................................................................................................10A. O Componente DBEdit.........................................................................................................................11

X. Codificando os Eventos da Janela de Detalhes........................................................................................11A. O Evento DetUf→OnShow..................................................................................................................11B. O Evento BitBtn1→OnClick................................................................................................................11C. O Evento BitBtn2→OnClick................................................................................................................12D. O Evento DetUf→OnClose..................................................................................................................12

XI. A Janela de Cadastro...............................................................................................................................12A. O Componente TDBGrid.....................................................................................................................13

XII. Codificando os Eventos da Janela de Cadastro.....................................................................................13A. O Evento CadUf→OnShow.................................................................................................................13B. O Evento Button1→OnClick................................................................................................................13C. O Evento Button2→OnClick................................................................................................................13D. O Evento Button3→OnClick...............................................................................................................14E. O Evento Button4→OnClick................................................................................................................14F. O Evento CadUf→OnKeyDown...........................................................................................................14

XIII. O Menu Principal.................................................................................................................................14XIV. Codificando os Eventos do Menu Principal.........................................................................................15

A. O Evento MainCad→OnShow.............................................................................................................15B. O Evento MainCad→OnClose.............................................................................................................15C. O Evento Button4→OnClick................................................................................................................15D. O Evento Button1→OnClick...............................................................................................................16

XV. Compilando o Programa........................................................................................................................16XVI. Inserindo os Outros Formulários..........................................................................................................16

A. No formulário DMCad.........................................................................................................................16B. Nos formulários DetCidade e DetBairro..............................................................................................16C. Nos formulários CadCidade e CadBairro............................................................................................17D. No formulário MainCad.......................................................................................................................17

XVII. Incluindo Referências Entre as Tabelas..............................................................................................17A. Referência por Código para Edição......................................................................................................17B. Referência Via SQL para Consultas.....................................................................................................17

2

Page 3: Tutorial C++ Builder

XVIII. O Componente TDBLookupComboBox...........................................................................................18XIX. Finalizando...........................................................................................................................................18

3

Page 4: Tutorial C++ Builder

Tutorial: Utilizando o Formulário DataModule

I. ObjetivoExemplificar a utilização de um formulário DataModule no Borland C++ Builder (versão 5.0) com

um banco de dados SQL relacional, de modo que o gerenciamento da base de dados fique centralizado ao máximo no programa.

II. Pré-requisitosO servidor de banco de dados deve estar instalado ou acessível da sua máquina. O driver ODBC, bem

como o DSN da sua base de dados, devem estar devidamente instalados e configurados, ou seja, este não é um guia de instalação e configuração de banco de dados. Você pode utilizar qualquer gerenciador de banco de dados compatível com a linguagem SQL e acessível via ODBC, tal como MySQL, PostgreSQL, InterBase, etc.

III. NotaçãoNeste tutorial utilizaremos o nome “dbCad” para a base de dados, que poderá ser trocado por

qualquer outro nome. Por convenção, todos os nomes escritos em itálico podem ser trocados por qualquer outro nome. Utilizaremos como exemplo um cadastro de cidades e bairros, principalmente por ser este um exemplo simples e de poucos campos. Veja a notação utilizada:

a) Os nomes dos formulários recebem um prefixo de acordo com sua finalidade: Cad para as janelas de cadastro, Det para as janelas de detalhe, entre outros, exemplo: CadUf e DetUf;

b) O nome do arquivo fonte (.cpp) e do formulário (propriedade Name) devem ser sempre diferentes, por isso invertemos o nome do formulário para o nome do arquivo, exemplo: formulário DMCad, arquivo CadDM.cpp; formulário CadUf, arquivo UfCad.cpp, etc.; motivo: todos os arquivos ficam agrupados por módulo, exemplo: todos os arquivos de unidade federativa ficarão juntos (Uf*.*);

c) Os nomes dos componentes recebem um prefixo distinto para cada tipo de componente: Tab para componentes TQuery; Upd para componentes TUpdateSQL, etc;

d) Os componentes do tipo TField recebem o mesmo nome do campo, mas com a inicial maiúscula, exemplo: uf_cod vira Uf_cod;

IV. Dicionário de dadosAbaixo estão descritas as tabelas utilizadas como exemplo neste tutorial:

CREATE TABLE uf ( uf_cod INT PRIMARY KEY, -- Código da unidade federativa uf_nome VARCHAR(20), -- Nome da unidade federativa uf_sigla VARCHAR(2) -- Sigla da unidade federativa);

CREATE TABLE cidade ( cid_cod INT PRIMARY KEY, -- Código da cidade cid_nome VARCHAR(20), -- Nome da cidade cid_ufcod INT REFERENCES uf(uf_cod) -- Código da unidade federativa);

CREATE TABLE bairro ( bai_cod INT PRIMARY KEY, -- Código do bairro bai_nome VARCHAR(20), -- Nome do bairro bai_cidcod INT REFERENCES cidade(cid_cod) -- Código da cidade);

4

Page 5: Tutorial C++ Builder

OBS: Utilizamos aqui a opção REFERENCES do PostgreSQL para indicar as chaves estrangeiras. Se você utilizar outro gerenciador, pode remove-la sem problemas.

V. Criando o Programa

1. Se você não abriu o C++ Builder agora, escolha File – New Application;

2. Abra File – New... e insira um formulário Data Module e dois formulários comuns (Form), atribuindo suas propriedades conforme descrito na tabela abaixo;

3. Escolha File – Save All, nomeando os arquivos conforme indicado abaixo:Item Arquivo Propriedade Valor Comentário

ApplicationCadProj.cpp Arquivo de projeto

FormCadMain.cpp Name MainCad Janela principal

Caption Menu Principal Título da janela

Data ModuleCadDM.cpp Name DMCad Módulo de dados

FormUfDet.cpp Name DetUf Detalhes da unidade federativa

FormUfCad.cpp Name CadUf Cadastro de unidade federativa

Caption Cadastro de Unidade Federativa

Título da janela

KeyPreview true Para utilizar teclas especiaisOBS:

a) Não é preciso definir o título da janela de detalhes (propriedade Caption), pois o mesmo será atribuído nos eventos BeforeInsert e BeforeEdit. Veja o capítulo A. (página 8);

b) Para o formulário de cadastro, sempre modificamos a propriedade KeyPreview para true. É isso que faz o evento OnFormKeyDown funcionar. Veja o capítulo F. (página 14).

VI. Componentes do DataModule

4. Abra View – Forms..., escolha DMCad e confirme;5. Insira os componentes listados abaixo, atribuindo suas respectivas propriedades:

Guia Componente Propriedade Valor ComentárioData Access

DatabaseName DataCad Componente de acesso à

base de dadosAliasName dbCad Alias ODBCDatabaseName DataCad Alias interno

UpdateSQLName UpdUf Componente de

atualização de tabelaModifySQL UPDATE uf

SET uf_nome = :uf_nome, uf_sigla = :uf_siglaWHERE uf_cod = :OLD_uf_cod

Código SQL para alterar registro. Ver parte B. (página 6)

InsertSQL INSERT INTO uf ( uf_cod, uf_nome, uf_sigla )VALUES ( :uf_cod, :uf_nome, :uf_sigla )

Código SQL para inserir registro. Ver parte B. (página 6)

DeleteSQL DELETE FROM ufWHERE uf_cod = :OLD_uf_cod

Código SQL para excluir registro. Idem

QueryName TabUf Componente de consulta

à base de dados

5

Page 6: Tutorial C++ Builder

DatabaseName DataCad Nome da base de dados (alias interno)

RequestLive true Permite editar os dados da tabela

SQL SELECT * FROM ufORDER BY uf_nome

Consulta SQL

UpdateObject UpdUf Componente de atualização de tabela

DataSourceName DSUf Componente de acesso à

tabelaDataSet TabUf Componente de consulta

à base de dados

A. O Componente TDatabaseControla o acesso ao servidor de banco de dados. A princípio este componente poderia ser eliminado

do projeto, já que a propriedade DatabaseName do componente TQuery pode ser atribuído diretamente ao alias OBDC (dbCad), porém este componente permite uma série de configurações e maior controle de acesso à base de dados.

Um exemplo é a propriedade Params, que permite configurar os parâmetros de acesso ao servidor SQL. Você pode clicar no botão da propriedade Params e inserir as seguintes linhas, com os valores corretos para usuário e senha preenchidos:

user_name=password=

Agora mude a propriedade LoginPrompt para false e o programa não irá mais pedir usuário e senha ao ser aberto. Porém, não é muito seguro deixar sua senha em aberto e, portanto, se você tem uma senha, procure preencher somente a propriedade user_name, mantendo LoginPrompt como true.

B. O Componente TUpdateSQLPermite entrar com comandos SQL para a manutenção da base de dados. Torna o componente

TQuery, que a princípio é somente para leitura, em uma tabela onde se pode fazer inclusão, exclusão e alteração de registros. Basicamente, o TQuery guarda os valores digitados pelo usuário e uma cópia do valor original em componentes TField; quando o método Post é chamado, o TUpdateSQL substitui os nomes pré-fixados com “:” (dois pontos) pelo valor atualizado dos campos indicados e os precedidos por “:OLD_” pelo valor original, executando o comando resultante no servidor.

Este componente também contém um utilitário para gerar todo o código SQL para você, como você pode ver no exemplo da figura abaixo:

6

Page 7: Tutorial C++ Builder

Para que este utilitário funcione, é preciso que o componente TQuery esteja configurado e conectado, pela propriedade UpdateObject, ao UpdateSQL. Após criar a consulta, de um clique duplo no UpdateSQL e irá aparecer uma janela com o campo Table Name preenchido com o nome da tabela e duas colunas, Key Fields e Update Fields, contendo a lista dos campos. Na primeira coluna, selecione o campo ou campos chave; na segunda deixe todos os campos selecionados ou desmarque aqueles que não serão atualizados pelo programa, como os campos de auto-incremento. Clique no botão Generate SQL e os campos ModifySQL, InsertSQL e DeleteSQL serão preenchidos; confira o código gerado nos itens Modify, Insert e Delete da aba SQL e confirme.

C. O Componente TQueryPossibilita a realização de consultas no banco de dados e a sua navegação em estilo de tabela. Tal

navegação pode ser realizada por métodos tais como: First() (primeiro registro), Last() (último registro), Next() (próximo registro) e Prior() (registro anterior), ou pelo componente DBNavigator da guia Data Controls.

A princípio, qualquer consulta reconhecível pelo servidor pode ser escrita na propriedade SQL, mas, se a propriedade RequestLive for mudada para true, uma série de restrições é imposta a sua consulta. A primeira restrição é que você só poderá codificar consultas em SQL padrão (SQL/92); qualquer recurso específico do seu servidor irá provocar um erro de execução. A segunda restrição é para abrir a consulta para leitura e gravação; você não poderá utilizar nem junção de tabelas (INNER JOIN), nem agrupamentos (GROUP BY) ou funções de agregação (count(), sum(), etc.). Caso contrário, a tabela será aberta somente para leitura (read only). Expressões de filtragem (WHERE) e ordenação (ORDER BY) são permitidas.

Tal como o TUpdateSQL, este componente também tem um utilitário para ajuda-lo a construir suas consultas. Clique com o botão direito sobre o TQuery e escolha SQL Builder... Você pode selecionar os campos a serem visualizados, definir critérios, agrupamento, ordem, junção de tabelas, tudo isso usando apenas o mouse. Muito útil se você não está muito familiarizado com a linguagem SQL, ou simplesmente para testar suas consultas (pelo menu Query – Run Query).

Como você verá a seguir, este componente contém os principais eventos que permitem controlar as alterações feitas na tabela.

D. O Componente TDataSourceEste componente é necessário para ligar a interface de usuário com a consulta SQL (TQuery). Você

pode verificar que praticamente todos os componentes da guia Data Controls têm uma propriedade DataSource a fim de serem conectados à tabela.

VII. Inserindo Campos

6. De um clique duplo sobre o componente TabUf ou clique com o botão direito e escolha Fields Editor...; deve aparecer uma pequena janela de título DMCad→TabUf. Clique com o botão direito do mouse sobre a janela e escolha Add all fields. Deverá abrir uma janela Database login, digite o seu login e a sua senha, se tiver, ou simplesmente clique no botão OK. O resultado deverá ser este:

OBS: Em alguns servidores de banco de dados, o nome de tabelas e campos é sensível ao caso, provocando erros do tipo: “Table does not exist”. Pode ser que o nome da sua tabela tenha sido convertido para minúsculo, de “Uf” para “uf”, por exemplo, e você precise corrigir sua consulta SQL.

7. Modifique as propriedades dos campos conforme indicado abaixo:

7

Page 8: Tutorial C++ Builder

Campo Propriedade Valor Comentáriouf_cod Name Uf_cod Nome de acesso

DisplayLabel Código Título na tabelauf_nome Name Uf_nome Nome de acesso

DisplayLabel Nome Título na tabelauf_sigla Name Uf_sigla Nome de acesso

DisplayLabel Sigla Título na tabela

8. Feche o editor de campos, clique sobre o componente DataCad e altere sua propriedade Connected para false. Com isso você evita problemas mais tarde, ao abrir novamente seu projeto, se o banco de dados não estiver acessível.

A. A Classe TFieldCada um destes campos que você inseriu acima é um objeto de uma classe descendente da classe

TField. Alguns exemplos são as classes TIntegerField para campos numéricos e TStringField pata campos caracter.

A principal vantagem de se criar estes objetos é o uso de nomes alternativos para os campos (Uf_cod é melhor de escrever que TabUf->FieldByName(“uf_cod”)), além da possibilidade de se entrar com parâmetros para a visualização e edição dos campos. Um exemplo é a propriedade DisplayLabel, onde se define o título do campo na grade de consulta. Outros exemplos são as propriedades EditFormat, para campos numéricos, e EditMask, para campos caracter. Por exemplo: podemos atribuir o EditMask do campo Uf_sigla para “>LL;0; ” e assim a sigla só aceitará duas letras (L) convertidas em maiúsculo (>). Os dois parâmetros restantes (;0; ) indicam a não utilização de caracteres fixos (0) e a visualização dos caracteres não preenchidos como espaços.

VIII. Codificando os Eventos da Tabela

9. Escolha File – Include Unit Hdr..., clique em UfDet e confirme;

10. Clique no componente TabUf, abra a guia Events do Object Inspector e insira os seguintes eventos:

A. O Evento TabUf→BeforeInsertSempre antes de inserir um registro na base de dados (método Insert()), o componente TQuery

chama este evento. Esta implementação abre uma janela (DetUf) para que o usuário entre com os dados.

//---------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforeInsert(TDataSet *DataSet){ DetUf->Caption = "Inserindo Unidade Federativa"; DetUf->Show();}

B. O Evento TabUf→BeforeEditEste evento é chamado sempre antes da tabela passar para o modo de edição (método Edit()). Esta

implementação abre então uma janela (DetUf) para que o usuário possa alterar os dados.

//---------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforeEdit(TDataSet *DataSet){ DetUf->Caption = "Alterando Unidade Federativa"; DetUf->Show();}

8

Page 9: Tutorial C++ Builder

C. O Evento TabUf→BeforeDeleteSempre que houver uma tentativa de exclusão de registro (método Delete()), o componente TQuery

chama este evento que, por sua vez, pedirá a confirmação do usuário. Caso o usuário não confirme a exclusão, a operação é cancelada pela função Abort().

//---------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforeDelete(TDataSet *DataSet){ if (Application->MessageBox( "Deseja realmente excluir o registro?", "Atenção!", MB_YESNO|MB_ICONQUESTION ) == IDNO) { ShowMessage( "Exclusão cancelada" ); Abort(); }}

D. O Evento TabUf→BeforePostAntes de o registro ser efetivamente gravado na tabela (método Post()), este evento é chamado, de

modo que podemos fazer todas as checagens básicas necessárias e impedimos, na maior parte dos casos, que o usuário receba mensagens de erro vindas do gerenciador de banco de dados, geralmente muito pouco amigáveis.

Também implementamos o auto-incremento de código que, embora pudesse estar no evento BeforeInsert (antes de inserir), aqui permite que dois usuários, em terminais diferentes, possam cadastrar dados, ao mesmo tempo, na mesma tabela.

//---------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforePost(TDataSet *DataSet){ int ncod; TQuery *sql;

// Checagem básica de erro if (Uf_nome->AsString.IsEmpty()) { ShowMessage( "Favor informar o nome da UF" ); Abort(); } else if (Uf_sigla->AsString.IsEmpty()) { ShowMessage( "Favor informar a sigla da UF" ); Abort(); }

// Auto-incremento do código if (TabUf->State == dsInsert) { sql = new TQuery(DMCad); sql->DatabaseName = "DataCad"; sql->SQL->SetText( "SELECT MAX(uf_cod) as uf_cod FROM uf" ); sql->Open(); sql->Last(); ncod = sql->FieldByName( "uf_cod" )->AsInteger + 1; Uf_cod->AsInteger = ncod; sql->Close(); delete sql; }}

OBS: A vantagem do auto-incremento por código e que este reutiliza a numeração de registros recentemente excluídos. Mas, se o seu banco de dados suportar a opção AUTOINCREMENT (MySQL), SERIAL (PostgreSQL)

9

Page 10: Tutorial C++ Builder

ou algo equivalente, e você quiser utiliza-la, então elimine o bloco “if (TabUf->State == dsInsert)”. Veja o código alternativo:

//---------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforePost(TDataSet *DataSet){ // Checagem básica de erro if (Uf_nome->AsString.IsEmpty()) { ShowMessage( "Favor informar o nome da UF" ); Abort(); } else if (Uf_sigla->AsString.IsEmpty()) { ShowMessage( "Favor informar a sigla da UF" ); Abort(); }}

OBS: Caso use este código alternativo, altere a propriedade InsertSQL do componente TabUf para:

INSERT INTO uf ( uf_nome, uf_sigla ) VALUES ( :uf_nome, :uf_sigla )

E. O Evento TabUf→AfterPostUm dos detalhes mais problemáticos ao se trabalhar no C++ Builder com SQL é a atualização. Uma

solução simples é que, após qualquer alteração na tabela, guardamos o código original, fechamos e abrimos a tabela e, finalmente, localizamos o registro anterior.

//---------------------------------------------------------------------------void __fastcall TDMCad::TabUfAfterPost(TDataSet *DataSet){ int cod;

cod = Uf_cod->AsInteger; TabUf->Close(); TabUf->Open(); TabUf->Locate( "uf_cod", cod, TLocateOptions() );}

IX. A Janela de Detalhes

11. Abra View – Forms..., escolha DetUf e confirme;

12. Escolha File – Include Unit Hdr..., clique em CadDM e confirme;13. Insira os componentes listados abaixo:Guia Componente Propriedade Valor ComentárioStandard

LabelAlignment taRightJustify Inserir no canto

superior esquerdoFont→Style→fsBold trueCaption Código:

LabelAlignment taRightJustify Inserir abaixo do

label anteriorFont→Style→fsBold trueCaption Nome:

LabelAlignment taRightJustify Inserir abaixo do

label anteriorFont→Style→fsBold trueCaption Sigla:

Data controls DBEdit

DataSource DMCad→DSUf Origem dos dadosDataField uf_cod Nome do campoEnabled false Somente leitura

10

Page 11: Tutorial C++ Builder

DBEditDataSource DMCad→DSUf Origem dos dadosDataField uf_nome Nome do campo

DBEditDataSource DMCad→DSUf Origem dos dadosDataField uf_sigla Nome do campo

Additional BitBtn

Kind bkOK Inserir no canto inferior esquerdo

BitBtnKind bkCancel Inserir à direita do

botão anteriorCaption Cancelar

O resultado deverá ser mais ou menos este:

A. O Componente DBEditPermite editar os campos do registro. A caixa de edição para o campo Uf_cod foi desabilitada porque

o código é auto-incrementado e não pode ser alterado.

X. Codificando os Eventos da Janela de Detalhes

A. O Evento DetUf→OnShowAo abrir o formulário, posicionamos o foco do teclado no primeiro campo a ser digitado (DBEdit2).

//---------------------------------------------------------------------------void __fastcall TDetUf::FormShow(TObject *Sender){ ActiveControl = DBEdit2;}

B. O Evento BitBtn1→OnClickNeste evento chamamos o método Post() se o registro estiver no estado de edição ou inserção (dsEdit

ou dsInsert). Se passar para o modo de consulta (dsBrowse), fechamos o formulário.

//---------------------------------------------------------------------------void __fastcall TDetUf::BitBtn1Click(TObject *Sender){ if (DMCad->TabUf->State == dsEdit || DMCad->TabUf->State == dsInsert) { DMCad->TabUf->Post(); if (DMCad->TabUf->State == dsBrowse) Close(); }}

11

Page 12: Tutorial C++ Builder

C. O Evento BitBtn2→OnClickAo cancelar, verificamos se o registro está no estado de edição ou inserção (dsEdit ou dsInsert). Não

é necessário checar se a operação foi bem sucedida.

//---------------------------------------------------------------------------void __fastcall TDetUf::BitBtn2Click(TObject *Sender){ if (DMCad->TabUf->State == dsEdit || DMCad->TabUf->State == dsInsert) { DMCad->TabUf->Cancel(); Close(); }}

D. O Evento DetUf→OnCloseNeste evento, verificamos se o formulário foi fechado pelos botões OK e Cancelar. Para isso,

checamos se o registro está no estado de edição ou inserção (dsEdit ou dsInsert), neste caso o usuário clicou no x do formulário ou teclou Alt+F4, e assim pedimos a confirmação dele.

//---------------------------------------------------------------------------void __fastcall TDetUf::FormClose(TObject *Sender, TCloseAction &Action){ int res;

if (DMCad->TabUf->State == dsEdit || DMCad->TabUf->State == dsInsert) { res = Application->MessageBox( "Gravar Registro?", "Atenção!", MB_YESNOCANCEL|MB_ICONQUESTION );

if (res == IDYES) { DMCad->TabUf->Post(); if (DMCad->TabUf->State != dsBrowse) Action = caNone; } else if (res == IDNO) DMCad->TabUf->Cancel(); else Action = caNone; }}

XI. A Janela de Cadastro

14. Abra View – Forms..., escolha CadUf e confirme;

15. Escolha File – Include Unit Hdr..., clique em CadDM e confirme;16. Insira os componentes listados abaixo:

Guia Componente Propriedade Valor ComentárioStandard

PanelAlign alTop Na parte superiorCaption Limpe este campo

Data Controls DBGrid

Align alClient No resto da telaDataSource DMCad→DSUf Origem dos dadosOptions→dgEditing false Não permite edição

direta no formulário.Standard

Button (em Panel1)Caption Incluir No canto superior

esquerdo

Button (em Panel1)Caption Excluir À direita do botão

12

Page 13: Tutorial C++ Builder

anterior

Button (em Panel1)Caption Alterar À direita do botão

anterior

Button (em Panel1)Caption Fechar À direita do botão

anterior

A. O Componente TDBGridAqui o usuário pode visualizar toda a consulta de uma só vez. As colunas com seus títulos são

acessados, automaticamente, do componente TQuery. Porém, você pode configurar quais campos devem aparecer. Para isso de um clique duplo no DBGrid, clique com o botão direito na janela que foi aberta e escolha Add All Fields; agora você pode excluir, mover colunas, ou atribuir uma série de parâmetros adicionais.

Desabilitamos a propriedade Options→dgEditing pois a edição será feita na janela de detalhes. Porém, se você não quiser utilizar uma tabela de detalhes, elimine os eventos TabUf→BeforeInsert e TabUf→BeforeEdit e deixe o dgEditing habilitado.

XII. Codificando os Eventos da Janela de Cadastro

A. O Evento CadUf→OnShowAo abrir o formulário, garantimos que a tabela está ativa e o foco do teclado está na grade. O bloco

“try ... catch” impede que a função seja interrompida no caso de haver erro.

//---------------------------------------------------------------------------void __fastcall TCadUf::FormShow(TObject *Sender){ try { DMCad->TabUf->Open(); } catch (Exception &exception) { Application->ShowException(&exception); } if (!DMCad->TabUf->Active) { ShowMessage( "Falha abrindo tabela" ); Close(); } ActiveControl = DBGrid1;}

B. O Evento Button1→OnClickInsere um registro na tabela.

//---------------------------------------------------------------------------void __fastcall TCadUf::Button1Click(TObject *Sender){ DMCad->TabUf->Insert();}

C. O Evento Button2→OnClickExclui o registro selecionado da tabela.

//---------------------------------------------------------------------------

13

Page 14: Tutorial C++ Builder

void __fastcall TCadUf::Button2Click(TObject *Sender){ DMCad->TabUf->Delete();}

D. O Evento Button3→OnClickAltera o registro atual. Um duplo clique no registro também deve altera-lo. Para isso, selecione o

evento DBGrid1→DblClick e escolha Button3Click.

//---------------------------------------------------------------------------void __fastcall TCadUf::Button3Click(TObject *Sender){ DMCad->TabUf->Edit();}

E. O Evento Button4→OnClickFecha o formulário de cadastro.

//---------------------------------------------------------------------------void __fastcall TCadUf::Button4Click(TObject *Sender){ Close();}

F. O Evento CadUf→OnKeyDownImplementa atalhos de teclado para os comandos: incluir (Ins), excluir (Del), alterar (Enter) e sair

(Esc). Se o valor da propriedade KeyPreview do formulário não for true, este método não irá funcionar.

//---------------------------------------------------------------------------void __fastcall TCadUf::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift){ switch (Key) { case VK_INSERT: DMCad->TabUf->Insert(); break; case VK_DELETE: DMCad->TabUf->Delete(); break; case VK_RETURN: DMCad->TabUf->Edit(); break; case VK_ESCAPE: Close(); break; }}

XIII. O Menu Principal

17. Abra View – Forms..., escolha MainCad e confirme;

18. Escolha File – Include Unit Hdr..., clique em CadDM e em UfCad com a tecla Control pressionada e confirme;

19. Insira os componentes listados abaixo:

14

Page 15: Tutorial C++ Builder

Guia Componente Propriedade Valor ComentárioAdditional

ButtonCaption Cadastro de UF No canto superior

esquerdo

ButtonCaption Cadastro de Cidade Abaixo do botão

anterior

ButtonCaption Cadastro de Bairro Abaixo do botão

anterior

ButtonCaption Sair Abaixo do botão

anterior

XIV. Codificando os Eventos do Menu Principal

A. O Evento MainCad→OnShowAo entrar no programa, tentamos abrir o banco de dados. O bloco “try ... catch” impede que a

função seja interrompida no caso de haver erro e assim podemos checar se a operação foi bem sucedida, não permitindo o acesso ao sistema se o acesso à base de dados for negado.

//---------------------------------------------------------------------------void __fastcall TMainCad::FormShow(TObject *Sender){ try { DMCad->DataCad->Open(); } catch (Exception &exception) { Application->ShowException(&exception); } if (!DMCad->DataCad->Connected) { ShowMessage( "Falha acessando a base de dados" ); Close(); }}

B. O Evento MainCad→OnCloseImplementamos um diálogo simples para confirmar a saída do programa.

//---------------------------------------------------------------------------void __fastcall TMainCad::FormClose(TObject *Sender, TCloseAction &Action){ if (Application->MessageBox( "Deseja realmente sair do sistema?", "Atenção!", MB_YESNO|MB_ICONQUESTION ) == IDNO) Action = caNone; else if (DMCad->DataCad->Connected) DMCad->DataCad->Close();}

C. O Evento Button4→OnClickBotão sair.

//---------------------------------------------------------------------------void __fastcall TMainCad::Button4Click(TObject *Sender){ Close();}

15

Page 16: Tutorial C++ Builder

D. O Evento Button1→OnClickChama o cadastro de unidade federativa.

//---------------------------------------------------------------------------void __fastcall TMainCad::Button1Click(TObject *Sender){ CadUf->Show();}

XV. Compilando o Programa

Agora o programa está pronto para rodar. Abra o menu Run - Run e veja o resultado. Se não funcionar, certifique-se que a base de dados está acessível e revise calmamente as propriedades de todos os componentes e o código de todos os eventos listados acima.

XVI. Inserindo os Outros FormuláriosPodemos, afinal, inserir os formulários que estão faltando:

20. Abra File – New... e insira quatro formulários comuns (Form), atribuindo suas propriedades conforme descrito na tabela abaixo;

21. Escolha File – Save All, nomeando os arquivos conforme indicado abaixo:Item Arquivo Propriedade Valor Comentário

FormCidadeDet.cpp Name DetCidade Detalhes de cidade

FormCidadeCad.cpp Name CadCidade Cadastro de cidade

Caption Cadastro de Cidade Título da janelaKeyPreview true Para utilizar teclas especiais

FormBairroDet.cpp Name DetBairro Detalhes de bairro

FormBairroCad.cpp Name CadBairro Cadastro de bairro

Caption Cadastro de Bairro Título da janelaKeyPreview true Para utilizar teclas especiais

O que ainda falta ser implementado é bastante similar ao que já foi feito com a tabela de unidade federativa, exceto pelo fato da UF não conter referências às outras tabelas. Abaixo você tem um resumo das inclusões necessárias para implementar os cadastros de cidade e bairro, volte aos capítulos indicados, substituindo os nomes em itálico, referentes à UF, para os nomes correspondentes para Cidade e Bairro. Nos capítulos seguintes (XVII. e XVIII. ) você verá como implementar referências entre as tabelas.

A. No formulário DMCada) Os componentes TUpdateSQL: UpdCidade e UpdBairro. Capítulo VI. (página 5);b) Os componentes TQuery: TabCidade e TabBairro. Ibidem;c) Os componentes TDataSource: DSCidade e DSBairro. Ibidem;d) Os campos das tabelas TabCidade e TabBairro. Capítulo VII. (página 7);e) Os campos referência Cid_ufnome e Bai_cidnome. Capítulo XVII. (página 17);f) Os eventos das tabela TabCidade e TabBairro. Capítulo VIII. (página 8).

B. Nos formulários DetCidade e DetBairroa) Os componentes TLabel e TDBEdit para código e nome. Capítulo IX. (página 10);b) Os componentes TLabel e TDBLookupComboBox para editar as referências entre as tabelas

TabCidade e TabUf e entre as tabelas TabBairro e TabCidade. Capítulo XVIII. (página 18);c) Os botões de controle Ok e Cancelar. Capítulo IX. (página 10);

16

Page 17: Tutorial C++ Builder

d) Os eventos da janela e dos botões. Capítulo X. (página 11).

C. Nos formulários CadCidade e CadBairroa) Os componentes TPanel, TDBGrid e os botões de controle. Capítulo XI. (página 12);b) Os eventos da janela e dos botões. Capítulo XII. (página 13).

D. No formulário MainCadCodifique os eventos dos botões Button2 e Button3 para chamar os formulários CadCidade e

CadBairro, respectivamente, conforme exemplificado no capítulo D. (página 16).

XVII. Incluindo Referências Entre as TabelasFreqüentemente precisamos mostrar dados de tabelas diferentes em uma mesma consulta. Em bancos

de dados relacionais, usamos chaves estrangeiras para isso. Asseguir mostramos duas formas de implementar referências entre tabelas, uma para edição e outra, mais simples, para consultas.

A. Referência por Código para Edição22. Ainda no editor de campos, clique com o botão direito e escolha New Field...;23. Deve aparecer uma janela de título New Field. Agora preencha os campos conforme indicado na

tabela:Propriedade Valor Comentário

Name cid_ufnome Nome do novo campoComponent Cid_ufnome Nome de acesso ao novo campoType String Tipo de dado para visualizaçãoField type Lookup Tipo de campoKeyFields cid_ufcod A chave estrangeiraDataset TabUf A tabela alvoLookup Keys uf_cod Campo chave na tabela alvoResult Field uf_nome Campo para visualização

Veja como fica o exemplo:

B. Referência Via SQL para ConsultasUma forma mais simples de incluir campos de referência é codificando-o diretamente na consulta

SQL. Exemplo:

SELECT cid_cod, cid_nome, cid_ufcod, uf_nome AS cid_ufnomeFROM cidade, ufWHERE cid_ufcod = uf_cod ORDER BY cid_nome

17

Page 18: Tutorial C++ Builder

Porém, esta forma só é permitida em consultas. Se você tentar incluir os campos, conforme o capítulo VII. (página 7), estando a opção RequestLive igual a true, você receberá uma mensagem de erro do tipo “Table is read only” (Tabela é somente para leitura). Porém, se RequestLive for false, você conseguirá inserir os campos sem problemas, mas também não conseguirá cadastrar os dados através do seu programa.

XVIII. O Componente TDBLookupComboBox24. Além das caixas de textos para código e nome de cidade, conforme exemplificado no capítulo IX.

(página 10), insira os componentes listados abaixo para a edição do campo cid_ufcod:Guia Componente Propriedade Valor ComentárioStandard

LabelAlignment TaRightJustify Abaixo do label para

nome.Font→Style→fsBold TrueCaption Uf:

Data controls DBLookupComboBox

DataSource DSCidade Origem dos dadosDataField cid_ufcod A chave estrangeiraListSource DSUf Origem do alvoKeyField uf_cod Chave na tabela alvoListField uf_nome Campo visualização

O Componente TDBLookupComboBox mantém uma lista atualizada de itens para campos de referência (chaves estrangeiras). Esconde do usuário todos os códigos da base de dados e assim, por exemplo, ele poderá entrar com “Rio de Janeiro” ao invés de “1” para informar a unidade federativa de uma cidade.

Dica: Você pode incluir um pequeno botão ao lado do DBLookupComboBox, com Caption = “&Novo...”, de modo que o usuário não precise acessar o menu a fim de incluir uma referência que esqueceu de cadastrar. Basta codificar o evento OnClick deste botão com a linha:

//---------------------------------------------------------------------------void __fastcall TDetCidade::BitBtn3Click(TObject *Sender){ DMCad->TabUf->Insert();}

XIX. Finalizando

Agora rode o programa clicando no botão Run e veja o resultado. Você pode utilizar este tutorial para implementar seus projetos, bastando trocar os nomes em itálico pelos nomes corretos.

18