Sie sind auf Seite 1von 18

Tutorial: Utilizando o Formulrio DataModule

Faculdade de Filosofia Santa Dorotia Tecnologia em Informtica Programao IV Autor: Mrcio Gil Maldonado Atualizao: 12/04/2004

ndice
ndice...................................................................................................................................................................2 Tutorial: Utilizando o Formulrio DataModule..................................................................................................4 . I Objetivo.......................................................................................................................................................4 . II Pr-requisitos.............................................................................................................................................4 . III Notao.....................................................................................................................................................4 . IV Dicionrio de dados..................................................................................................................................4 . V Criando o Programa...................................................................................................................................5 . VI Componentes do DataModule..................................................................................................................5 . A O Componente TDatabase.....................................................................................................................6 . B O Componente TUpdateSQL.................................................................................................................6 . C O Componente TQuery..........................................................................................................................7 . D O Componente TDataSource.................................................................................................................7 . VII Inserindo Campos...................................................................................................................................7 . A A Classe TField.....................................................................................................................................8 . VIII Codificando os Eventos da Tabela........................................................................................................8 . A O Evento TabUfBeforeInsert.............................................................................................................8 . B O Evento TabUfBeforeEdit...............................................................................................................8 . C O Evento TabUfBeforeDelete...........................................................................................................9 . D O Evento TabUfBeforePost...............................................................................................................9 . E O Evento TabUfAfterPost................................................................................................................10 . IX A Janela de Detalhes..............................................................................................................................10 . A O Componente DBEdit........................................................................................................................11 . X Codificando os Eventos da Janela de Detalhes........................................................................................11 . A O Evento DetUfOnShow.................................................................................................................11 . B O Evento BitBtn1OnClick...............................................................................................................11 . C O Evento BitBtn2OnClick...............................................................................................................12 . D O Evento DetUfOnClose.................................................................................................................12 . XI A Janela de Cadastro..............................................................................................................................12 . A O Componente TDBGrid.....................................................................................................................13 . XII Codificando os Eventos da Janela de Cadastro.....................................................................................13 . A O Evento CadUfOnShow................................................................................................................13 . B O Evento Button1OnClick...............................................................................................................13 . C O Evento Button2OnClick...............................................................................................................13 . D O Evento Button3OnClick...............................................................................................................14 . E O Evento Button4OnClick...............................................................................................................14 . F O Evento CadUfOnKeyDown..........................................................................................................14 . XIII O Menu Principal.................................................................................................................................14 . XIV Codificando os Eventos do Menu Principal........................................................................................15 . A O Evento MainCadOnShow............................................................................................................15 . B O Evento MainCadOnClose............................................................................................................15 . C O Evento Button4OnClick...............................................................................................................15 . D O Evento Button1OnClick...............................................................................................................16 . XV Compilando o Programa.......................................................................................................................16 . XVI Inserindo os Outros Formulrios.........................................................................................................16 . A No formulrio DMCad........................................................................................................................16 . B Nos formulrios DetCidade e DetBairro.............................................................................................16 . C Nos formulrios CadCidade e CadBairro............................................................................................17 . D No formulrio MainCad......................................................................................................................17 . XVII Incluindo Referncias Entre as Tabelas.............................................................................................17 2

. A Referncia por Cdigo para Edio.....................................................................................................17 . B Referncia Via SQL para Consultas....................................................................................................17 . XVIII O Componente TDBLookupComboBox..........................................................................................18 . XIX Finalizando..........................................................................................................................................18

Tutorial: Utilizando o Formulrio DataModule


. IObjetivo
Exemplificar a utilizao de um formulrio DataModule no Borland C++ Builder (verso 5.0) com um banco de dados SQL relacional, de modo que o gerenciamento da base de dados fique centralizado ao mximo no programa.

. IIPr-requisitos
O servidor de banco de dados deve estar instalado ou acessvel da sua mquina. O driver ODBC, bem como o DSN da sua base de dados, devem estar devidamente instalados e configurados, ou seja, este no um guia de instalao e configurao de banco de dados. Voc pode utilizar qualquer gerenciador de banco de dados compatvel com a linguagem SQL e acessvel via ODBC, tal como MySQL, PostgreSQL, InterBase, etc.

. IIINotao
Neste tutorial utilizaremos o nome dbCad para a base de dados, que poder ser trocado por qualquer outro nome. Por conveno, todos os nomes escritos em itlico 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 notao utilizada: a) Os nomes dos formulrios 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 formulrio (propriedade Name) devem ser sempre diferentes, por isso invertemos o nome do formulrio para o nome do arquivo, exemplo: formulrio DMCad, arquivo CadDM.cpp; formulrio CadUf, arquivo UfCad.cpp, etc.; motivo: todos os arquivos ficam agrupados por mdulo, exemplo: todos os arquivos de unidade federativa ficaro 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 maiscula, exemplo: uf_cod vira Uf_cod;

. IVDicionrio de dados
Abaixo esto descritas as tabelas utilizadas como exemplo neste tutorial:
CREATE TABLE uf ( uf_cod INT PRIMARY KEY, uf_nome VARCHAR(20), uf_sigla VARCHAR(2) ); CREATE TABLE cidade ( cid_cod INT PRIMARY KEY, cid_nome VARCHAR(20), cid_ufcod INT REFERENCES uf(uf_cod) ); CREATE TABLE bairro ( bai_cod INT PRIMARY KEY, bai_nome VARCHAR(20), bai_cidcod INT REFERENCES cidade(cid_cod) ); -- Cdigo da unidade federativa -- Nome da unidade federativa -- Sigla da unidade federativa

-- Cdigo da cidade -- Nome da cidade -- Cdigo da unidade federativa

-- Cdigo do bairro -- Nome do bairro -- Cdigo da cidade

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

. VCriando o Programa
1. Se voc no abriu o C++ Builder agora, escolha File New Application; 2. Abra File New... e insira um formulrio Data Module e dois formulrios 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 Comentrio CadProj.cpp Arquivo de projeto Application CadMain.cpp Name MainCad Janela principal Form Caption Menu Principal Ttulo da janela CadDM.cpp Name DMCad Mdulo de dados Data Module UfDet.cpp Name DetUf Detalhes da unidade federativa Form UfCad.cpp Name CadUf Cadastro de unidade federativa Form Caption Cadastro de Unidade Ttulo da janela Federativa KeyPreview true Para utilizar teclas especiais OBS: a) No preciso definir o ttulo da janela de detalhes (propriedade Caption), pois o mesmo ser atribudo nos eventos BeforeInsert e BeforeEdit. Veja o captulo . VIII. A(pgina 8); b) Para o formulrio de cadastro, sempre modificamos a propriedade KeyPreview para true. isso que faz o evento OnFormKeyDown funcionar. Veja o captulo . XII. F(pgina 14).

. VIComponentes do DataModule
4. Abra View Forms..., escolha DMCad e confirme; 5. Insira os componentes listados abaixo, atribuindo suas respectivas propriedades: Guia Componente Propriedade Valor Comentrio Data Access Name DataCad Componente de acesso Database base de dados AliasName dbCad Alias ODBC DatabaseName DataCad Alias interno Name UpdUf Componente de UpdateSQL atualizao de tabela ModifySQL Cdigo SQL para alterar UPDATE uf SET uf_nome = :uf_nome, registro. Ver parte . uf_sigla = :uf_sigla B(pgina 6) InsertSQL
WHERE uf_cod = :OLD_uf_cod INSERT INTO uf ( uf_cod, uf_nome, uf_sigla ) VALUES ( :uf_cod, :uf_nome, :uf_sigla ) DELETE FROM uf WHERE uf_cod = :OLD_uf_cod

Cdigo SQL para inserir registro. Ver parte . B(pgina 6) Cdigo SQL para excluir registro. Idem Componente de consulta base de dados

DeleteSQL Query Name

TabUf 5

DatabaseName RequestLive SQL UpdateObject DataSource Name DataSet

DataCad true
SELECT * FROM uf ORDER BY uf_nome

Nome da base de dados (alias interno) Permite editar os dados da tabela Consulta SQL Componente de atualizao de tabela Componente de acesso tabela Componente de consulta base de dados

UpdUf DSUf TabUf

. AO Componente TDatabase
Controla o acesso ao servidor de banco de dados. A princpio este componente poderia ser eliminado do projeto, j que a propriedade DatabaseName do componente TQuery pode ser atribudo diretamente ao alias OBDC (dbCad), porm este componente permite uma srie de configuraes e maior controle de acesso base de dados. Um exemplo a propriedade Params, que permite configurar os parmetros de acesso ao servidor SQL. Voc pode clicar no boto da propriedade Params e inserir as seguintes linhas, com os valores corretos para usurio e senha preenchidos:
user_name= password=

Agora mude a propriedade LoginPrompt para false e o programa no ir mais pedir usurio e senha ao ser aberto. Porm, no 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.

. BO Componente TUpdateSQL
Permite entrar com comandos SQL para a manuteno da base de dados. Torna o componente TQuery, que a princpio somente para leitura, em uma tabela onde se pode fazer incluso, excluso e alterao de registros. Basicamente, o TQuery guarda os valores digitados pelo usurio e uma cpia do valor original em componentes TField; quando o mtodo Post chamado, o TUpdateSQL substitui os nomes prfixados 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 tambm contm um utilitrio para gerar todo o cdigo SQL para voc, como voc pode ver no exemplo da figura abaixo:

Para que este utilitrio funcione, preciso que o componente TQuery esteja configurado e conectado, pela propriedade UpdateObject, ao UpdateSQL. Aps 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 no sero atualizados pelo programa, como os campos de auto-incremento. Clique no boto Generate SQL e os campos ModifySQL, InsertSQL e DeleteSQL sero preenchidos; confira o cdigo gerado nos itens Modify, Insert e Delete da aba SQL e confirme.

. CO Componente TQuery
Possibilita a realizao de consultas no banco de dados e a sua navegao em estilo de tabela. Tal navegao pode ser realizada por mtodos tais como: First() (primeiro registro), Last() (ltimo registro), Next() (prximo registro) e Prior() (registro anterior), ou pelo componente DBNavigator da guia Data Controls. A princpio, qualquer consulta reconhecvel pelo servidor pode ser escrita na propriedade SQL, mas, se a propriedade RequestLive for mudada para true, uma srie de restries imposta a sua consulta. A primeira restrio que voc s poder codificar consultas em SQL padro ( SQL/92); qualquer recurso especfico do seu servidor ir provocar um erro de execuo. A segunda restrio para abrir a consulta para leitura e gravao; voc no poder utilizar nem juno de tabelas ( INNER JOIN), nem agrupamentos (GROUP BY) ou funes de agregao (count(), sum(), etc.). Caso contrrio, a tabela ser aberta somente para leitura (read only). Expresses de filtragem (WHERE) e ordenao (ORDER BY) so permitidas. Tal como o TUpdateSQL, este componente tambm tem um utilitrio para ajuda-lo a construir suas consultas. Clique com o boto direito sobre o TQuery e escolha SQL Builder... Voc pode selecionar os campos a serem visualizados, definir critrios, agrupamento, ordem, juno de tabelas, tudo isso usando apenas o mouse. Muito til se voc no 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 contm os principais eventos que permitem controlar as alteraes feitas na tabela.

. DO Componente TDataSource
Este componente necessrio para ligar a interface de usurio com a consulta SQL ( TQuery). Voc pode verificar que praticamente todos os componentes da guia Data Controls tm uma propriedade DataSource a fim de serem conectados tabela.

. VIIInserindo Campos
6. De um clique duplo sobre o componente TabUf ou clique com o boto direito e escolha Fields Editor...; deve aparecer uma pequena janela de ttulo DMCadTabUf. Clique com o boto 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 boto OK. O resultado dever ser este:

OBS: Em alguns servidores de banco de dados, o nome de tabelas e campos sensvel ao caso, provocando erros do tipo: Table does not exist. Pode ser que o nome da sua tabela tenha sido convertido para minsculo, de Uf para uf, por exemplo, e voc precise corrigir sua consulta SQL. 7. Modifique as propriedades dos campos conforme indicado abaixo: 7

Campo uf_cod uf_nome uf_sigla

Propriedade Name DisplayLabel Name DisplayLabel Name DisplayLabel

Valor Uf_cod Cdigo Uf_nome Nome Uf_sigla Sigla

Comentrio Nome de acesso Ttulo na tabela Nome de acesso Ttulo na tabela Nome de acesso Ttulo 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 no estiver acessvel.

. AA Classe TField
Cada um destes campos que voc inseriu acima um objeto de uma classe descendente da classe TField. Alguns exemplos so as classes TIntegerField para campos numricos 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)), alm da possibilidade de se entrar com parmetros para a visualizao e edio dos campos. Um exemplo a propriedade DisplayLabel, onde se define o ttulo do campo na grade de consulta. Outros exemplos so as propriedades EditFormat, para campos numricos, 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 maisculo (>). Os dois parmetros restantes (;0; ) indicam a no utilizao de caracteres fixos (0) e a visualizao dos caracteres no preenchidos como espaos.

. VIIICodificando os Eventos da Tabela


9. Escolha File Include Unit Hdr..., clique em UfDet e confirme; TabUf, abra a guia Events do Object Inspector e insira os seguintes 10. Clique no componente eventos:

. AO Evento TabUfBeforeInsert
Sempre antes de inserir um registro na base de dados (mtodo Insert()), o componente TQuery chama este evento. Esta implementao abre uma janela (DetUf) para que o usurio entre com os dados.
//--------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforeInsert(TDataSet *DataSet) { DetUf->Caption = "Inserindo Unidade Federativa"; DetUf->Show(); }

. BO Evento TabUfBeforeEdit
Este evento chamado sempre antes da tabela passar para o modo de edio (mtodo Edit()). Esta implementao abre ento uma janela (DetUf) para que o usurio possa alterar os dados.
//--------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforeEdit(TDataSet *DataSet) { DetUf->Caption = "Alterando Unidade Federativa"; DetUf->Show(); }

. CO Evento TabUfBeforeDelete
Sempre que houver uma tentativa de excluso de registro (mtodo Delete()), o componente TQuery chama este evento que, por sua vez, pedir a confirmao do usurio. Caso o usurio no confirme a excluso, a operao cancelada pela funo Abort().
//--------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforeDelete(TDataSet *DataSet) { if (Application->MessageBox( "Deseja realmente excluir o registro?", "Ateno!", MB_YESNO|MB_ICONQUESTION ) == IDNO) { ShowMessage( "Excluso cancelada" ); Abort(); } }

. DO Evento TabUfBeforePost
Antes de o registro ser efetivamente gravado na tabela (mtodo Post()), este evento chamado, de modo que podemos fazer todas as checagens bsicas necessrias e impedimos, na maior parte dos casos, que o usurio receba mensagens de erro vindas do gerenciador de banco de dados, geralmente muito pouco amigveis. Tambm implementamos o auto-incremento de cdigo que, embora pudesse estar no evento BeforeInsert (antes de inserir), aqui permite que dois usurios, em terminais diferentes, possam cadastrar dados, ao mesmo tempo, na mesma tabela.
//--------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforePost(TDataSet *DataSet) { int ncod; TQuery *sql; // Checagem bsica 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 cdigo 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 cdigo e que este reutiliza a numerao de registros recentemente excludos. Mas, se o seu banco de dados suportar a opo AUTOINCREMENT (MySQL), SERIAL (PostgreSQL) 9

ou algo equivalente, e voc quiser utiliza-la, ento elimine o bloco if (TabUf->State == dsInsert). Veja o cdigo alternativo:
//--------------------------------------------------------------------------void __fastcall TDMCad::TabUfBeforePost(TDataSet *DataSet) { // Checagem bsica 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 cdigo alternativo, altere a propriedade InsertSQL do componente TabUf para:
INSERT INTO uf ( uf_nome, uf_sigla ) VALUES ( :uf_nome, :uf_sigla )

. EO Evento TabUfAfterPost
Um dos detalhes mais problemticos ao se trabalhar no C++ Builder com SQL a atualizao. Uma soluo simples que, aps qualquer alterao na tabela, guardamos o cdigo 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() ); }

. IXA 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 Standard Alignment taRightJustify Label FontStylefsBold true Caption Cdigo: Alignment taRightJustify Label FontStylefsBold true Caption Nome: Alignment taRightJustify Label FontStylefsBold true Caption Sigla: Data controls DataSource DMCadDSUf DBEdit DataField uf_cod Enabled false 10

Comentrio Inserir no canto superior esquerdo Inserir abaixo do label anterior Inserir abaixo do label anterior Origem dos dados Nome do campo Somente leitura

DBEdit DBEdit Additional BitBtn BitBtn

DataSource DataField DataSource DataField Kind Kind Caption

DMCadDSUf uf_nome DMCadDSUf uf_sigla bkOK bkCancel Cancelar

Origem dos dados Nome do campo Origem dos dados Nome do campo Inserir no canto inferior esquerdo Inserir direita do boto anterior

O resultado dever ser mais ou menos este:

. AO Componente DBEdit
Permite editar os campos do registro. A caixa de edio para o campo Uf_cod foi desabilitada porque o cdigo auto-incrementado e no pode ser alterado.

. XCodificando os Eventos da Janela de Detalhes


. AO Evento DetUfOnShow
Ao abrir o formulrio, posicionamos o foco do teclado no primeiro campo a ser digitado (DBEdit2).
//--------------------------------------------------------------------------void __fastcall TDetUf::FormShow(TObject *Sender) { ActiveControl = DBEdit2; }

. BO Evento BitBtn1OnClick
Neste evento chamamos o mtodo Post() se o registro estiver no estado de edio ou insero (dsEdit ou dsInsert). Se passar para o modo de consulta (dsBrowse), fechamos o formulrio.
//--------------------------------------------------------------------------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

. CO Evento BitBtn2OnClick
Ao cancelar, verificamos se o registro est no estado de edio ou insero (dsEdit ou dsInsert). No necessrio checar se a operao foi bem sucedida.
//--------------------------------------------------------------------------void __fastcall TDetUf::BitBtn2Click(TObject *Sender) { if (DMCad->TabUf->State == dsEdit || DMCad->TabUf->State == dsInsert) { DMCad->TabUf->Cancel(); Close(); } }

. DO Evento DetUfOnClose
Neste evento, verificamos se o formulrio foi fechado pelos botes OK e Cancelar. Para isso, checamos se o registro est no estado de edio ou insero ( dsEdit ou dsInsert), neste caso o usurio clicou no x do formulrio ou teclou Alt+F4, e assim pedimos a confirmao 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?", "Ateno!", 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; } }

. XIA 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 Standard Align alTop Panel Caption Data Controls Align alClient DBGrid DataSource DMCadDSUf OptionsdgEditing false Standard Button (em Panel1) Button (em Panel1) Caption Caption 12 Incluir Excluir

Comentrio Na parte superior Limpe este campo No resto da tela Origem dos dados No permite edio direta no formulrio. No canto superior esquerdo direita do boto

Button (em Panel1) Button (em Panel1)

Caption Caption

Alterar Fechar

anterior direita do boto anterior direita do boto anterior

. AO Componente TDBGrid
Aqui o usurio pode visualizar toda a consulta de uma s vez. As colunas com seus ttulos so acessados, automaticamente, do componente TQuery. Porm, voc pode configurar quais campos devem aparecer. Para isso de um clique duplo no DBGrid, clique com o boto direito na janela que foi aberta e escolha Add All Fields; agora voc pode excluir, mover colunas, ou atribuir uma srie de parmetros adicionais. Desabilitamos a propriedade OptionsdgEditing pois a edio ser feita na janela de detalhes. Porm, se voc no quiser utilizar uma tabela de detalhes, elimine os eventos TabUfBeforeInsert e TabUfBeforeEdit e deixe o dgEditing habilitado.

. XIICodificando os Eventos da Janela de Cadastro


. AO Evento CadUfOnShow
Ao abrir o formulrio, garantimos que a tabela est ativa e o foco do teclado est na grade. O bloco try ... catch impede que a funo 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; }

. BO Evento Button1OnClick
Insere um registro na tabela.
//--------------------------------------------------------------------------void __fastcall TCadUf::Button1Click(TObject *Sender) { DMCad->TabUf->Insert(); }

. CO Evento Button2OnClick
Exclui o registro selecionado da tabela.
//---------------------------------------------------------------------------

13

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

. DO Evento Button3OnClick
Altera o registro atual. Um duplo clique no registro tambm deve altera-lo. Para isso, selecione o evento DBGrid1DblClick e escolha Button3Click.
//--------------------------------------------------------------------------void __fastcall TCadUf::Button3Click(TObject *Sender) { DMCad->TabUf->Edit(); }

. EO Evento Button4OnClick
Fecha o formulrio de cadastro.
//--------------------------------------------------------------------------void __fastcall TCadUf::Button4Click(TObject *Sender) { Close(); }

. FO Evento CadUfOnKeyDown
Implementa atalhos de teclado para os comandos: incluir (Ins), excluir (Del), alterar (Enter) e sair (Esc). Se o valor da propriedade KeyPreview do formulrio no for true, este mtodo no 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; } }

. XIIIO 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

Guia Additional

Componente Button Button Button Button

Propriedade Caption Caption Caption Caption

Valor Cadastro de UF Cadastro de Cidade Cadastro de Bairro Sair

Comentrio No canto superior esquerdo Abaixo do boto anterior Abaixo do boto anterior Abaixo do boto anterior

. XIVCodificando os Eventos do Menu Principal


. AO Evento MainCadOnShow
Ao entrar no programa, tentamos abrir o banco de dados. O bloco try ... catch impede que a funo seja interrompida no caso de haver erro e assim podemos checar se a operao foi bem sucedida, no 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(); } }

. BO Evento MainCadOnClose
Implementamos um dilogo simples para confirmar a sada do programa.
//--------------------------------------------------------------------------void __fastcall TMainCad::FormClose(TObject *Sender, TCloseAction &Action) { if (Application->MessageBox( "Deseja realmente sair do sistema?", "Ateno!", MB_YESNO|MB_ICONQUESTION ) == IDNO) Action = caNone; else if (DMCad->DataCad->Connected) DMCad->DataCad->Close(); }

. CO Evento Button4OnClick
Boto sair.
//--------------------------------------------------------------------------void __fastcall TMainCad::Button4Click(TObject *Sender) { Close(); }

15

. DO Evento Button1OnClick
Chama o cadastro de unidade federativa.
//--------------------------------------------------------------------------void __fastcall TMainCad::Button1Click(TObject *Sender) { CadUf->Show(); }

. XVCompilando o Programa
Agora o programa est pronto para rodar. Abra o menu Run Run e veja o resultado. Se no funcionar, certifique-se que a base de dados est acessvel e revise calmamente as propriedades de todos os componentes e o cdigo de todos os eventos listados acima.

. XVIInserindo os Outros Formulrios


Podemos, afinal, inserir os formulrios que esto faltando: 20. Abra File New... e insira quatro formulrios 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 Comentrio CidadeDet.cpp Name DetCidade Detalhes de cidade Form CidadeCad.cpp Name CadCidade Cadastro de cidade Form Caption Cadastro de Cidade Ttulo da janela KeyPreview true Para utilizar teclas especiais BairroDet.cpp Name DetBairro Detalhes de bairro Form BairroCad.cpp Name CadBairro Cadastro de bairro Form Caption Cadastro de Bairro Ttulo da janela KeyPreview 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 no conter referncias s outras tabelas. Abaixo voc tem um resumo das incluses necessrias para implementar os cadastros de cidade e bairro, volte aos captulos indicados, substituindo os nomes em itlico, referentes UF, para os nomes correspondentes para Cidade e Bairro. Nos captulos seguintes (. XVIIe . XVIII) voc ver como implementar referncias entre as tabelas.

. ANo formulrio DMCad


a) b) c) d) e) f) Os componentes TUpdateSQL: UpdCidade e UpdBairro. Captulo . VI(pgina 5); Os componentes TQuery: TabCidade e TabBairro. Ibidem; Os componentes TDataSource: DSCidade e DSBairro. Ibidem; Os campos das tabelas TabCidade e TabBairro. Captulo . VII(pgina 7); Os campos referncia Cid_ufnome e Bai_cidnome. Captulo . XVII(pgina 17); Os eventos das tabela TabCidade e TabBairro. Captulo . VIII(pgina 8).

. BNos formulrios DetCidade e DetBairro


a) Os componentes TLabel e TDBEdit para cdigo e nome. Captulo . IX(pgina 10); b) Os componentes TLabel e TDBLookupComboBox para editar as referncias entre as tabelas TabCidade e TabUf e entre as tabelas TabBairro e TabCidade. Captulo . XVIII(pgina 18); c) Os botes de controle Ok e Cancelar. Captulo . IX(pgina 10); 16

d) Os eventos da janela e dos botes. Captulo . X(pgina 11).

. CNos formulrios CadCidade e CadBairro


a) Os componentes TPanel, TDBGrid e os botes de controle. Captulo . XI (pgina 12); b) Os eventos da janela e dos botes. Captulo . XII(pgina 13).

. DNo formulrio MainCad


Codifique os eventos dos botes Button2 e Button3 para chamar os formulrios CadCidade e CadBairro, respectivamente, conforme exemplificado no captulo . XIV. D(pgina 16).

. XVIIIncluindo Referncias Entre as Tabelas


Freqentemente 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 referncias entre tabelas, uma para edio e outra, mais simples, para consultas.

. AReferncia por Cdigo para Edio


22. Ainda no editor de campos, clique com o boto direito e escolha New Field...; 23. Deve aparecer uma janela de ttulo New Field. Agora preencha os campos conforme indicado na tabela: Propriedade Valor Comentrio Name cid_ufnome Nome do novo campo Component Cid_ufnome Nome de acesso ao novo campo Type String Tipo de dado para visualizao Field type Tipo de campo Lookup KeyFields A chave estrangeira cid_ufcod Dataset TabUf A tabela alvo Lookup Keys Campo chave na tabela alvo uf_cod Result Field uf_nome Campo para visualizao Veja como fica o exemplo:

. BReferncia Via SQL para Consultas


Uma forma mais simples de incluir campos de referncia codificando-o diretamente na consulta SQL. Exemplo:
SELECT cid_cod, cid_nome, cid_ufcod, uf_nome AS cid_ufnome FROM cidade, uf WHERE cid_ufcod = uf_cod ORDER BY cid_nome

17

Porm, esta forma s permitida em consultas. Se voc tentar incluir os campos, conforme o captulo . VII(pgina 7), estando a opo RequestLive igual a true, voc receber uma mensagem de erro do tipo Table is read only (Tabela somente para leitura). Porm, se RequestLive for false, voc conseguir inserir os campos sem problemas, mas tambm no conseguir cadastrar os dados atravs do seu programa.

. XVIIIO Componente TDBLookupComboBox


24. Alm das caixas de textos para cdigo e nome de cidade, conforme exemplificado no captulo . IX(pgina 10), insira os componentes listados abaixo para a edio do campo cid_ufcod: Guia Componente Propriedade Valor Comentrio Standard Alignment TaRightJustify Abaixo do label para Label nome. FontStylefsBold True Caption Uf: Data DataSource DSCidade Origem dos dados DBLookupComboBox DataField controls A chave estrangeira cid_ufcod ListSource DSUf Origem do alvo KeyField Chave na tabela alvo uf_cod ListField uf_nome Campo visualizao O Componente TDBLookupComboBox mantm uma lista atualizada de itens para campos de referncia (chaves estrangeiras). Esconde do usurio todos os cdigos da base de dados e assim, por exemplo, ele poder entrar com Rio de Janeiro ao invs de 1 para informar a unidade federativa de uma cidade. Dica: Voc pode incluir um pequeno boto ao lado do DBLookupComboBox, com Caption = &Novo..., de modo que o usurio no precise acessar o menu a fim de incluir uma referncia que esqueceu de cadastrar. Basta codificar o evento OnClick deste boto com a linha:
//--------------------------------------------------------------------------void __fastcall TDetCidade::BitBtn3Click(TObject *Sender) { DMCad->TabUf->Insert(); }

. XIXFinalizando
Agora rode o programa clicando no boto Run e veja o resultado. Voc pode utilizar este tutorial para implementar seus projetos, bastando trocar os nomes em itlico pelos nomes corretos.

18