30

Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

  • Upload
    lekien

  • View
    234

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log
Page 2: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

Revista The Club Megazine - 09/2003A utilização, reprodução, apropriação, armazenamento em banco de dados,sob qualquer forma ou meio, de textos, fotos e outras criações intelectuaisem cada publicação da revista “The Club” são terminantemente proibidos

sem autorização escrita dos titulares dos direitos autorais.Copyright© The Club® 2003

Page 3: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 33333

EDITORIALEDITORIALEDITORIALEDITORIALEDITORIAL

Editorial

Celso Jefferson PaganelliPresidente - The Club

Editorial ............................................................................ 03News ............................................................................... 04Dicas & Truques ................................................................. 05Pesquisa em Banco de Dados ............................................. 08DBExpress - Criando um relacionamentoMASTER/DETALHE - Parte II ............................................... 14IntraWeb - Desenvolvendo aplicações web page ................ 18Delphi Web HardCore ........................................................ 24Rave Reports - Carregando Imagens Dinâmicamente ......... 28

THE CLUBAv. Celso Ferreira da Silva, 190

Jd. Europa - Avaré - SP - CEP 18.707-150Informações: (0xx14) 3732-3689

Suporte: (0xx14) 3733-1588 - Fax: (0xx14) 3732-0987

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected]ções: [email protected]

DúvidasCorrespondência ou fax com dúvidas devem serenviados ao - THE CLUB, indicando "Suporte".

OpiniãoSe você quer dar a sua opinião sobre o clube em

geral, mande a sua correspondência para a seção"Tire sua dúvida".

ReproduçãoA utilização, reprodução, apropriação,

armazenamento em banco de dados, sob qualquerforma ou meio, de textos, fotos e outras criações

intelectuais em cada publicação da Revista“The Club” são terminantemente proibidos sem

autorização escrita dos titulares dos direitosautorais.

Copyright© The Club® 2003

Impressão e acabamento:Impressos Gril - Gril Gráfica e Repr. Ind. Ltda.

Tel.: (0xx14) 3762.1345 - Fax: (0xx14) 3762.1259Rua São Paulo, 447 - Cep 18.740-000

Taquarituba - SPTiragem: 5.000 exemplares

ColaboradoresEmerson Facunte

Diretor - Presidente

Celso Jefferson M. Paganelli

Diretor Técnico

Mauro Sant’Anna

Delphi é marca registrada da Borland International, asdemais marcas citadas são registradas pelos seus

respectivos proprietários.

Olá amigos,

Estamos trazendo até você a 108ª edição da nossa The Club Megazine e como decostume com muita coisa legal preparada especialmente para você!

Começamos com a sessão Dicas & Truques, trazendo algumas das dicas solicitadasao nosso setor de suporte, porém, como são muitas, não temos como estar publicandoaqui todas as novas dicas, mas você poderá acessar diretamente em nosso site, http:/www.theclub.com.br na sessão “Suporte On-Line”, bastando para isso baixar umpequeno plug-in de acesso e com isso acessar diretamente nosso banco de dados!

Pesquisa em Banco de Dados! Este ítem sem dúvidas é um dos mais requisitadosaos nossos consultores, visto ser algo imprescindível em qualquer tipo de aplicação eassim sendo, estamos demonstrando uma das abordagens possíveis para este assunto.

Continuando, estamos trazendo a segunda parte do artigo sobre relacionamentosmaster/detalhe utilizando dbExpress, com mais algumas dicas e macetes bastanteinteressantes!

Falando em Internet, estamos trazendo mais um artigo sobre a suite decomponentes Intraweb, desta vez, abordando a versão que acompanha o Delphi 7Professional e mostrando que através desta versão também é possível obter ótimosresultados sem muito esforço. Ainda falando em Internet, Emerson Facunte,especialista neste assunto traz um excelente artigo mesclando as tecnologiasWebBroker, Mobile, Intraweb e WebServices, vale a pena conferir!

E finalizamos com um artigo sobre o gerador de relatórios Rave Reports,demonstrando uma abordagem bastante interessante para apresentação de imagensdinâmicamente.

Aproveitem e até a próxima,

Page 4: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE44444

NEWSNEWSNEWSNEWSNEWS

Extended Systems lança o Advantage Database Server 7.0A Extended Systems XTND anunciou que a empresa está

reforçando sua solução de gerenciamento de banco de dados como lançamento da versão 7.0 do Advantage Database Server.

Novas funcionalidades significativas foram incorporadas aoAdvantage Database Server, incluindo “triggers”, compressão dedados na comunicação, “full text search” (procura completa detextos), “.NET data provider” e “driver type-4 JDBC”. Com estasmelhorias, a Extended Systems continua fornecendo aosdesenvolvedores de aplicações comerciais sua robusta soluçãogerenciamento de banco de dados cliente/servidor, que pode serutilizada facilmente e sem custos extras, em diversasplataformas.

Os desenvolvedores Java e .Net estarão particularmenteinteressados no Advantage Database Server 7.0, pois o driverAdvantage JDBC permite acesso nativo ao Advantage DatabaseServer enquanto .NET Data Provider permite às aplicaçõesADO.NET acesso nativo. Estas inovações permitem que aExtended Systems persiga agressivamente os mercados Java e.NET, fornecendo aos seus desenvolvedores, alternativa degerenciamento de banco de dados de alto nível, que é escalonável,robusta e de fácil distribuição.

”O Advantage é desenhado especificamente para desenvolvedoresde aplicações que necessitem de uma solução de gerenciamentode dados na filosofia cliente/servidor e que forneça funcionalidadepara todo o tipo de processamento crítico, sem criar problemasadministrativos.”, disse Chuck Vertrees, gerente de produtosAdvantage, da Extended Systems. “Estamos com o compromissode, continuadamente, atualizar e melhorar o ADS e fornecertecnologias adicionais para a nossa leal base de clientes atual etambém para futuros clientes.”

Funcionalidades adicionais incorporadas ao AdvantageDatabase Server 7.0:

- “Triggers” - excelente para melhorar autorizações desegurança mais complexas e para fornecer eventos de log eauditoria, de forma transparente e independente.

- Compressão de dados na comunicação - consegue tráfego derede reduzido entre clientes Advantage e o servidor Advantage.

- Capacidade para “Full Text Search” (procura completa de

textos) - usado para encontrar registros que contenham dadosque confiram com condições de procura, construídas através depalavras e frases, combinadas com operadores lógicos AND, OR eNOT e o operador de proximidade NEAR

Disponibilidade do Advantage 7.0O Advantage Database Server estará disponível em 22/09/03.

O .NET Data Provider estará disponível logo depois. Versõesanteriores do Advantage poderão ser atualizadas por umaporcentagem do preço do produto final. No Brasil, contate aReNet Tecnologia (www.renet.com.br), telefone 11 3872-0423.

Sobre o Advantage Database ServerAdvantage Database Server é a culminação sobre de 13 anos

da experiência do desenvolvimento no mercado de banco dedados. Advantage é suportada por completo departamento detécnicos treinados que ajudam usuários a extrair o máximo desuas soluções cliente/servidor através de excepcional suporte,treinamento e consultoria. Hoje, o Advantage Database Server éum produto premiado (*) que suporta mais de 2,5 milhões deinstalações mundialmente. É solução confiável para empresasclassificadas de pequenas a integrantes do Fortune 500, queconfiam ao Advantage Database Server a missão de processaraplicações críticas que permitem a conduzir com sucesso seusnegócios através do país e do mundo. Para mais informações,visite o Web site do distribuidor no Brasil: www.renet.com.br/database.

Sobre a Extended Systems

A Extended Systems fornece perícia, estratégia e soluções paraajudar as corporações afinarem seus processos corporativos.Fundada em 1984, a Extended Systems têm escritórios esubsidiárias nos Estados Unidos e no resto do mundo. Para maisinformações, visite o Web Site da companhia emwww.extendedsystems.com. No Brasil, visite www.renet.com.br.

(*) Delphi Informant Magazine 2003, 2002, and 2001Readers Choice Award

Visite www.renet.com.br ou contate-nos para detalhesadicionais e conhecer o programa de avaliação.

ReNet Tecnologia [email protected].: 11 3872-0423

Page 5: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 55555

Dicas & TDicas & TDicas & TDicas & TDicas & Truquesruquesruquesruquesruques

QuickReport – Como criar bandas viaprogramação

Muitas vezes, temos a necessidade de criar bandas ecomponentes QRDBText via programação em um QuickReport enesta dica iremos demonstrar alguns macetes para isso...

{

Esta função tem a finalidade de retornar a banda no

qual componentes como um QRDBText irão ser

apresentados.

}

function AchaParent(Nome: String; QRep: TQuickRep):

TWinControl;

var

i: Integer;

begin

Result := Nil;

for i := 0 to QRep.ControlCount-1 do

if QRep.Controls[i].Name = Nome then

begin

Result := QRep.Controls[i] as TWinControl;

Break;

end;

end;

{

Cria os objetos e chama o Preview.

}

procedure TForm1.btnPreviewClick(Sender: TObject);

var

i: Integer;

begin

// Criando uma banda do tipo QRGroup

with TQRGroup.Create(Self) do

begin

Parent := QuickRep1;

Master := Parent;

Expression := ‘Continent’;

Color := clAqua;

Name := ‘QRGroup1’;

end;

// Criando um componente QRDBText

with TQRDBText.Create(Self) do

begin

Parent := AchaParent(‘QRGroup1’, QuickRep1);

Dataset := QuickRep1.Dataset;

DataField := ‘Continent’;

Color := clAqua;

Font.Style := [fsBold];

end;

QuickRep1.Preview;

end;

Page 6: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE66666

Auto-CompletarEsta funcionalidade existe em

aplicações como por exemplo, noInternet Explorer, no qual, quandocomeçamos digitar um endereço,automaticamente se esse já foidigitado anteriormente, ele éautomaticamente completado. Aqui,iremos demonstrar uma abordagempara implementar uma pesquisa embanco de dados com estafuncionalidade. Para estaabordagem, adicione umcomponente TDBGrid, um Tedit,uma TTable e um TdataSource econfigure como mostra a figura ao lado:

Para esta funcionalidade, utilizamos o evento OnKeyUp docomponente TEdit, como poderá verificar abaixo:

procedure TForm1.EdPesqKeyUp

(Sender: TObject; var Key: Word;

Shift: TShiftState);

var

theText: string;

i, p: integer;

begin

with EdPesq do

case key of

8, 13, 46, 37..40: ; // Se for backspace,

enter, delete, ou setas, ignora...

else

begin

p := SelStart;

theText := copy(text, 0, p);

if TabCountry.Locate(‘Name’, theText,

[loCaseInsensitive, loPartialKey]) then begin

text := TabCountry.FieldByName

(‘Name’).AsString;

SelStart := p;

SelLength := length(text) - selStart;

end;

end; // case

end; // with

end;

DBExpressPlus – Turbinando a dbExpress

O DBExpressPlus é uma suíte de componentes gratuítos quefacilitam a execução de tarefas comuns no dia-a-dia doprogramador Delphi.

Você poderá fazer o download do DBExpressPlus no seguinteendereço:

http://sourceforge.net/projects/dbexpressplus

A instalação é bastante simples, basta descompactar oarquivo baixado preferencialmente criando uma pasta em$(Delphi)\Source\dbExpressPlus, onde “$(Delphi)” indica apasta de instalação de seu Delphi.

Após isso, abra o pacote dbExprPlus_r?0.dpk (?=versão doDelphi, 6 ou 7) e clique no botão “Compile”. Continuando, abra opacote dbExprPlus_d?0.dpk, clique em “Compile” e depois em“Install”.

Para concluir, acesso o menu “Tools | Environment Options| Library | Library Path” e adicione o path onde os arquivosforam descompactados, ou seja,$(Delphi)\Source\dbExpressPlus e com isso finalizamos ainstalação do dbExpressPlus.

Se tudo ocorreu sem problemas, você poderá visualizar osnovos componentes na paleta de componentes dbExpress:

Dicas & TDicas & TDicas & TDicas & TDicas & Truquesruquesruquesruquesruques

Page 7: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 77777

Entre vários componentes que o pacote instala, podemosdestacar um que é bastante útil, o SQLScript, que permite aoprogramador rodar scripts SQL para manutenção no banco dedados.

Para conhecer as funcionalidades de todos os componentes,você poderá abrir o projeto de exemplo que acompanha odbExpressPlus, podendo ser encontrado na pasta Demo($(Delphi)\Source\dbExpressPlus\Demo).

Rave Reports – Como acessar valores nos eventos internos

O Rave Reports possui eventos internos visíveis somentedentro de sua própria IDE, eventos estes que trabalham comuma linguagem própria de scripts, a qual até o momento aindanão encontramos documentação a respeito, contudo, em cima detestes estamos conseguindo desvendar o caminho das pedras. Porexemplo, para acessar um determinado valor no eventoOnBeforePrint de uma banda do Rave, bastará acessar

diretamente via campo gerado pelo DataView:

if DataView1VendorName.AsString =

‘Cacor Corporation’ then

Text2.Text := DataView1VendorName.AsString;

end if;

Porta Serial – Como verificar se uma porta está em uso

Existem APIs do Windows que possibilitam fazer acesso emanutenção à portas seriais, veja abaixo:

var

portHandle: Integer;

begin

portHandle := 0;

portHandle := CreateFile(Pchar(ComboCOM.Text),

GENERIC_READ or GENERIC_WRITE, 0, nil,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if portHandle > 0 then

ShowMessage(‘Porta em uso!’)

else

raise Exception.Create

(‘Não consegui abrir a porta!’);

end;

Neste exemplo, estamos utilizando o objeto TGifImage que éinstalado junto com a suite de componentes RxLib. Esta suite égratuíta e possui vários componentes bem legais e, caso hajainteresse, poderá baixar em nosso site, www.theclub.com.br.Abaixo, segue a rotina de conversão:

implementation

uses RxGif;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);

var

GIF: TGIFImage;

BMP: TBitmap;

begin

GIF := TGIFImage.Create;

BMP := TBitmap.Create;

try

GIF.LoadFromFile(‘c:\banner_theclub.gif’);

BMP.Assign(GIF);

BMP.SaveToFile(‘c:\theclub.bmp’);

finally

GIF.Free;

BMP.Free;

end;

end;

GIF – Como converter uma imagem GIF para BMP

Envie-nos suas dicas para que possamos compartilhá-las com todos associados.

Dicas & TDicas & TDicas & TDicas & TDicas & Truquesruquesruquesruquesruques

Page 8: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE88888

DelphiDelphiDelphiDelphiDelphi

IntroduçãoOlá amigos, neste artigo vamos abordar um tema bastante

solicitado à nossa equipe de suporte e que parece ter ser um bichopapão, quando na realidade trata-se de algo bastante simples,como poderá ser acompanhar a seguir.

Iremos aqui, mostrar uma das abordagens possíveis naimplementação de um formulário de pesquisa, formulário esteque poderá ser utilizado praticamente em quase todas assituações onde sua aplicação necessitar de uma pesquisa, seja elauma pesquisa exata ou parcial, e ainda, permitindo ao usuárioselecionar qualquer campo (desde que este seja um tipo válido)para efetuar a pesquisa.

LógicaA idéia é bastante simples... Criaremos um formulário que

irá receber alguns parâmetros, tais como um objeto TDataSet(TQuery, TClientDataSet, TSimpleDataSet, etc) e o nome databela que irá sofrer a pesquisa. Após isso, iremos obter todos oscampos que nos interessarem do referido TDataSet passado comoparâmetro para montar uma lista na qual o próprio usuáriopoderá estar selecionando por qual campo irá pesquisar. Bem,chega de conversa e vamos por a mão-na-massa.

Primeiramente, abra o Delphi e crie um novo projeto esalve-o em seguida. Neste exemplo, iremos fazer acesso a umbanco Interbase/Firebird chamado EMPLOYEE.GDB, que é um,banco de dados exemplo que acompanha a instalação doInterbase/Firebird, via dbExpress utilizando o componenteTSimpleDataSet (disponível a partir do Delphi 7), mas, nadaimpede de aplicar esta abordagem a qualquer outra engine deacesso e banco de dados. Insira um componente TSimpleDataSetno formulário e configure seu nome para sdsCustomer, cliquecom o botão direito do mouse sobre ele e selecione o ítem “EditConnection” e crie uma conexão com seu banco de dados ou com o

banco de exemplo sugerido acima. Após isso, acesse a propriedade“DataSet” e na sub-propriedade “CommandText” adicione ainstrução SQL para acesso a sua tabela ou a tabela sugeridaCUSTOMERS, como exemplo, “Select * From CUSTOMERS”.Bem, agora dê um duplo clique no componente sdsCustomer ecom o botão direito, adicione os TFields (campos) na lista “FieldsEditor”, como mostra a Figura 1:

Pesquisa em Banco de Dados

Configure a propriedade DisplayLabel de todos oscampos para um nome amigável ao usuário. Oconteúdo da propriedade DisplayLabel será utilizadomais tarde quando formos implementar o formulário depesquisa

Sugestão:

Figura 1 – Campos no Fields Editor

Aprenda a implementar um formuláriogenérico para pesquisas

por Alessandro Ferreira, [email protected]

Page 9: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 99999

DelphiDelphiDelphiDelphiDelphi

Figura 2 – Formulário “Cadastro”

Adicione ainda, um componente TDBNavigator e umcomponente TSpeedButton, o qual receberá o nome desbtnPesquisa e o caption “Pesquisar”. Basicamente, nossoformulário de cadastro está pronto!

Implementação do Formulário de PesquisaVamos iniciar a implementação de nosso formulário genérico

de pesquisa.O primeiro passo é criar o formulário, para isso, adicione um

novo formulário, configure seu nome como “fmPesquisa” e salve-o com a unit como “unPesquisa” ou outro nome que achar maisconveniente.

Na sessão private deste do “fmPesquisa”, declare as seguintesvariáveis:

private

{ Private declarations }

Campos: TStringList;

Tabela: string;

edTexto (Edit)

cmbTipo (ComboBox)

Como mencionei anteriormente, esteformulário de pesquisa irá receberalguns parâmetros para “saber” emqual tabela irá ser efetuada a pesquisa etambém, quais os campos serãoapresentadas ao usuário. Para isso,iremos usar um artífio simples, porém,pode ser desconhecido à algunsprogramadores... Iremos reintroduzir oevento “Constructor” deste referidoformulário através da diretiva “reintro-duce”. Você pode me perguntar, -paraque isso? Bem, a resposta é bastantesimples: -quando chamamos o métodocreate de um objeto, automaticamente oevento constructor é acionado e comonecessitamos passar alguns parâmetrospara o novo formulário de pesquisaassim que o mesmo form criado,reintroduzimos o constructor definindoneste os parâmetros que desejamosinformar, pois, com isso, criamos eenviamos os parâmetros de uma só vez.A primeira vista pode parecer um poucoconfuso, mas na prática é bastante

simples. Antes de explicarmos o código que será implementado nofmPesquisa, vamos mostrar o layout sugerido para ofmPesquisa, conforme a Figura 3.

O componente CombBox nomeado cmbTipos irá conter os tiposdisponíveis de pesquisa, tendo os seguintes ítens fixos:

* Pelas Iniciais* Em qualquer parte do texto* Exata

Continuando, iremos inicar as implementações necessáriaspara nossa pesquisa funcionar! Agora, na sessão public de nossofmPesquisa, faça a declaração conforme mostra a Listagem 1:

public

{ Public declarations }

constructor Create(AOwner: TComponent; DataSet:

TSimpleDataSet; TableName: string); reintroduce;

end;

Listagem 1 – Constructor.

Onde:AOwner - objeto que está sendo criado (parâmetro

obrigatório)

Page 10: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 01 01 01 01 0

DelphiDelphiDelphiDelphiDelphi

DataSet - objeto TDataSet (nosso TSimpleDataSet que irásofrer a pesquisa)

TableName - nome da tabela onde efetuaremos a pesquisa

Tecle a combinação de teclas “CTRL+SHIFT+C” com isso,automaticamente a IDE do Delphi irá declarar o “corpo” paranossa procedure, onde faremos as implementações conformeapresentada na Listagem 2:

constructor TfmPesquisa.Create(AOwner: TComponent;

DataSet: TSimpleDataSet; TableName: string);

var

i: integer;

begin

inherited Create(AOwner);

Tabela := TableName;

// liga DataSource

dsPesq.DataSet := DataSet;

// guardar nome dos campos.

Campos := TStringList.Create;

// Preenche campos no combobox

for i := 0 to DataSet.FieldCount-1 do

if DataSet.Fields[i].DataType in [ftString,

ftInteger] then

begin

cmbCampos.Items.Add(DataSet.Fields[i].DisplayLabel);

Campos.Add(DataSet.Fields[i].FieldName);

end;

// Posiciona no primeiro item

if cmbCampos.Items.Count>0 then

cmbCampos.ItemIndex := 0;

end;

Listagem 2 – Evento Constructor do fmPesquisa

Bastante atenção na implementação desta procedure, pois elaé fundamental para o perfeito funcionamento de nossoformulário de pesquisa. Para um melhor entendimento, vamosexplicar cada linha deste procedure a seguir...

Iniciamos com a diretiva inherited a qual deve estar naprimeira linha da procedure e faz a chamada do método Create naclasse base. Após isso, atribuímos o parâmetro TableName à nossavariável Tabela que deve ter sido declarada previamente na sessãoPrivate do fmPesquisa. Continuando, informamos o DataSetpassado como parâmetro à um componente datasource chamadodsPesq existente em nosso fmPesquisa.

Vamos instanciar agora um objeto do tipo TStringList quetambém já deve ter sido declarado na sessão private, o qual irá

Figura 3 – Layout sugerido para o fmPesquisa

Page 11: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 11 11 11 11 1

DelphiDelphiDelphiDelphiDelphi

receber os campos dentro de um looping, varrendo todos oscampos do DataSet e testando campo a campo se é do tipo stringou integer (você pode adicionar outros tipos, caso acheinteressante) e caso seja, adicionamos o referido campo à lista(Campos) e os Labels à um TComboBox que nomeamos decmbCampos. (Lembra quando sugeri a configuração dapropriedade DisplayLabel dos campos?!, É exatamente isso queiremos apresentar em nosso Combo).

E, finalizando, apenas posicionamos o cmbCampos noprimeiro item de sua lista.

Continuando nossa implementação, iremos fazer algunspequenos ajustes para deixar nosso exemplo mais funcional,conforme demonstra a Listagem 3:

// evento OnCloseUp do cmbCampos

procedure TfmPesquisa.cmbCamposCloseUp(Sender:

TObject);

begin

EdTexto.SetFocus;

end;

// evento OnCreate do fmPesquisa

procedure TfmPesquisa.FormCreate(Sender: TObject);

begin

cmbTipo.ItemIndex := 0;

end;

// evento OnEnter do EdTexto

procedure TfmPesquisa.EdTextoEnter(Sender: TObject);

begin

// limpar o Edit.

EdTexto.Clear;

end;

// evento OnClose do fmPesquisa

procedure TfmPesquisa.FormClose(Sender: TObject; var

Action: TCloseAction);

begin

Campos.Free;

end;

// evento OnKeyDown do fmPesquisa

procedure TfmPesquisa.FormKeyDown(Sender: TObject;

var Key: Word;

Shift: TShiftState);

begin

case Key of

vk_Escape: ModalResult := mrCancel;

vk_F5: if not dsPesq.DataSet.IsEmpty then

ModalResult := mrOK;

end;

end;

// evento OnKeyDown do DBGrid_Pesq

procedure TfmPesquisa.DBGrid_PesqKeyDown(Sender:

TObject; var Key: Word;

Shift: TShiftState);

begin

if (key = vk_Return) and not

(dsPesq.DataSet.IsEmpty) then

ModalResult := mrOK;

end;

Listagem 3 – Alguns eventos do fmPesquisa

O próximo passo, posso dizer que em conjunto com o eventoconstructor do fmPrincipal, é o evento mais importante de nossoformulário de pesquisa, visto ser neste que será implementada apesquisa propriamente dita. Para isso, abra o evento OnKeyDowndo componente EdTexto e nele vamos passo a passo concluirnossa pesquisa. Comece declarando três variáveis do tipo string,sendo aSQL, aWhere e Campo. A Listagem 4, mostra o código completodo evento OnKeyDown...

procedure TfmPesquisa.EdTextoKeyDown(Sender:

TObject; var Key: Word;

Shift: TShiftState);

var

aSql, aWhere, Campo: string;

begin

if (key in [vk_Down, vk_Up]) and not

(dsPesq.DataSet.IsEmpty) then

DBGrid_Pesq.SetFocus;

if (edTexto.Text<>’’) and (Key = vk_Return) then

begin

// descobrir o campo.

Campo := Campos[cmbCampos.ItemIndex];

// inicializar variáveis auxiliares

aSql := ‘’;

aWhere := ‘’;

// montar cláusula where.

case cmbTipo.ItemIndex of

0: {Iniciais}aWhere := Format(‘ Where

Upper(%s) Like %s ‘, [Campo,

QuotedStr(EdTexto.Text+’%’)]);

1: {Qualquer}aWhere := Format(‘ Where

Upper(%s) Like %s ‘, [Campo,

QuotedStr(‘%’+EdTexto.Text+’%’)]);

2: {Exata }aWhere := Format(‘ Where

Upper(%s) = %s ‘ , [Campo,

QuotedStr(EdTexto.Text)]);

end;

aSql := Format(‘Select * From %s %s’, [Tabela,

aWhere]);

Page 12: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 21 21 21 21 2

DelphiDelphiDelphiDelphiDelphi

with TSimpleDataSet(dsPesq.DataSet) do

begin

Close;

DataSet.CommandText := aSql;

Open;

if not IsEmpty then

DBGrid_Pesq.SetFocus;

end;

end;

end;

Listagem 4 – Evento OnKeyDown do EdTexto

No início do evento OnKeyDown, começamos fazendo umaverificação das teclas vk_Down (seta abaixo) e vk_Up (seta acima) e,caso a tabela apresentada esteja com algum registro visível,mandamos o foco para o DBGrid_Pesq.

Para que a pesquisa seja efetuada, verificamos se o usuárioteclou vk_Return (Enter) e se existe alguma coisa digitada nocomponente EdTexto e caso sim, entramos no bloco para realizar apesquisa.

A variável local Campo recebe o nome do campo selecionado nocmbCampos, porém, obtendo o nome através da lista (Campos),lista esta que alimentamos com o nome dos campos no eventoconstructor, lembra?!

Seguindo, inicializamos as variáveis locais aSQL e aWherecomo vazias, e montamos um “case”, analisando o tipo depesquisa selecionada no cmbTipos e assim, montar a cláusulaWhere para nossa pesquisa. Basicamente, nosso “case” verifica oseguinte:

* Opção 0, pesquisa pelas iniciais- Nesta abordagem, preparamos a cláusula where para

utilizar o operador Like, adicionando a caracter coringa “%”apenas no final do valor pesquisado, como exemplo, “ Select *From Tabela where campo Like ‘TheClub%’ “.

* Opção 1, pesquisa em qualquer parte do campo- Nesta abordagem, preparamos a cláusula where para

também utilizar o operador Like, contudo, adicionando o caractercoringa “%” no início e no final do valor pesquisado, exemplo:“Select * From Tabela where campo Like ‘%TheClub%’”.

* Opção 2, pesquisa exata- Nesta abordagem, preparamos a cláusula where para

trabalhar com o operador “=”, visto a busca ser exata. Exemplo: “Select * From Tabela where campo = ‘TheClub’ “.

Estando pronta nossa claúsula where, partimos para aimplementação de nossa sentença SQL completa, atribuindo a

mesma para a variável local aSQL:

aSql := Format(‘Select * From %s %s’,

[Tabela, aWhere]);

E finalizando, iremos repassar asentença SQL completa para o objetoTDataSet, utilizando o valor configuradona propriedade DataSet do dsPesq, ondefazemos um typecast* paraTSimpleDataSet, abrimos o mesmo e casoalgum registro tenha sido encontrado,mandamos o foco para nossoDBGrid_Pesq.

Como mencionei, esta abordagem pode ser Aplicada à outrosobjetos TdataSets, como por exemplo uma TQuery ou umTClientDataSet, onde a implementação ficaria como demonstradona Listagem 5.

// TClientDataSet *

with TClientDataSet(dsPesq.DataSet) do

begin

Close;

CommandText := aSql;

Open;

if not IsEmpty then

DBGrid_Pesq.SetFocus;

end;

// TQuery

with TQuery(dsPesq.DataSet) do

begin

Close;

SQL.Text := aSql;

Open;

if not IsEmpty then

DBGrid_Pesq.SetFocus;

end;

Listagem 5 – Utilizando ClientDataSet e Query.

Chamando o Formulário de Pesquisa

Antes de finalizamos o artigo, iremos demonstrar comochamar o nosso formulário de pesquisa. O código demonstrado naListagem 6 representa o evento OnClick do botão sbtnPesquisa, na qualpoderá ver que a chamada é bastante simples e funcional.

procedure TForm1.sbtnPesquisaClick(Sender: TObject);

begin

TypeCast - Conversão detipos em object pascal, ouseja, no exemplo citado,convertemos um objetoTDataSet para um objetoTSimpleDataSet, afim depoder acessarpropriedades, métodos eeventos de umTSimpleDataSet.

Dica

TClientDataSet - No casodesta abordagem utilizandoum componenteTClientDataSet, vocêdeverá alterar a propriedadeOptions |AllowCommandText doc o m p o n e n t eTDataSetProvider ao qualseu ClientDataSet estáligado.

Dica

Page 13: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 31 31 31 31 3

DelphiDelphiDelphiDelphiDelphi

fmPesquisa := tfmPesquisa.Create(Self,

sdsCustomer, ‘CUSTOMER’);

try

fmPesquisa.ShowModal;

finally fmPesquisa.Free; end;end;

Listagem 6 – Chamada da Pesquisa

Veja que não há nada em especial, a não ser, a chamada dométodo create, o qual recebe alguns parâmetros a mais (essa já eranossa intenção no início), sendo o objeto TDataSet (no casosdsCustomer) e o nome da tabela, neste exemplo CUSTOMER.Depois, executamos o método ShowModal como de costume e umFree para liberar o formulário da memória.

ConclusãoNeste simples artigo, procuramos mostrar uma das

abordagens possíveis para implementação de um formulário depesquisa genérica, sendo esta apenas a ponta do iceberg, a qualcom um pouco mais de criatividade pode ser enriquecida deacordo com suas necessidades. Espero ter contribuído parafacilitar seu dia-a-dia, e, caso tenha alguma sugestão ou crítica,bastará nos enviar que faremos o possível para atendê-lo,abraços e até a próxima.

Download

O projeto de exemplo referente este artigo está disponível paradownload em:

http://www.theclub.com.br/revista/download/pesquisagenerica.zip

Sobre o autorAlessandro Ferreira,Consultor Técnico do The [email protected]

Page 14: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 41 41 41 41 4

DelphiDelphiDelphiDelphiDelphi

Na matéria anterior focamos a criação de um relacionamentoMaster/Detail com DBExpress.

Nesta segunda parte iremos fazer algumas alterações emnosso projeto inicial, pois da maneira como foi criado ele nãovisualiza o código sequencial criado dentro do banco através dastriggers, com isso dependendo de como você irá utilizá-lo ocorremerros porque os ClientDataSets ainda não estão visualizandoesses códigos.

Portanto somente iremos mudar a criação do códigosequencial das tabelas Master e Detalhe que estão dentro de duastriggers para serem geradas dentro do projeto, para que assimlogo após o CDSMaster incluir um registro o seu código já estarávisível ao usuário.

O mesmo caso será feito para o CDSDetalhe. Vamos iniciaras alterações.

Alteração no banco de dados ( GDB )

Bem a primeira alteração que iremos fazer é em nosso bancode dados, ao qual nós iremos apagar as duas Triggersresponsáveis pela criação do código sequencial. Para apagar essasduas Triggers iremos executar as seguintes instruções:

DROP TRIGGER AI_MASTER_CODMASTERDROP TRIGGER AI_DETALHE_CODDETALHE

Pronto, essa é a única alteração realizada em nosso banco dedados.

Alteração no projeto

Em nosso projeto a alteração também será simples, poissomente iremos criar uma função ao qual irá executar um Selectnos Generators para pegar o próximo valor do Código sequencialdo Master e do Detalhe.

Primeiro passo, abra o DataModule e dê duplo click sobre ocomponente SQLMaster para abrir a lista de tfields. Selecione otfield CODMASTER e na propriedade ProviderFlags altere aopção pfInUpdate para TRUE, ficando como TRUE as opçõespfInUpdate e pfInKey.

Faça os mesmos passos para o SQLDetalhe, isso é, altere oProviderflags do campo CODDETALHE deixando o pfInUpdate eo pfInKey como TRUE.

Não é necessário alterar os Providerflags dos ClientDataSets.Neste momento habilitamos para que os campos

DBEXPRESSDBEXPRESSDBEXPRESSDBEXPRESSDBEXPRESSCriando um relacionamento MASTER/DETALHE – Parte II

por André Colavite – Suporte THE [email protected]

Page 15: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 51 51 51 51 5

DelphiDelphiDelphiDelphiDelphi

CODMASTER e CODDETALHE possam receber valores geradosdentro do projeto Delphi, o próximo passo será gerar esse códigoautomaticamente.

Gerando o código sequencial dentro do projeto

Bem, para começar coloque um componente SQLQuery nodatamodule e em sua propriedade NAME coloque SQLGen. Nasua propriedade SQLConnection ligue ao SQLConnection1, jáexistente no datamodule.

Esse SQLGen será utilizado para ler o próximo valor dosGenerators e para isso iremos criar uma function chamadaGeraCodigo.

Esta function terá um parâmetro chamado NomeGeneratorao qual será utilizado para indicar o nome do Generator a serutilizado e dentro dessa function iremos montar, viaprogramação, uma instrução de Select ao qual irá buscar opróximo valor desse Generator passado como parâmetro.

Veja abaixo a function criada na unit do DataModulecontendo a instrução para montar o select e pegar o próximovalor do Generator.

function TDM.GeraCodigo(NomeGenerator: String):

Integer;

begin

SQLGen.SQL.Text := ‘select

Gen_ID(‘+NomeGenerator+’,1) from RDB$DataBase’;

SQLGen.Open;

Result := SQLGen.Fields[0].AsInteger;

SQLGen.Close;

end;

Listagem – Function GeraCodigo

Essa function poderá ser declarada na seção Private da Unit,conforme o exemplo abaixo:

private

function GeraCodigo(NomeGenerator: String):

Integer;

public

{ Public declarations }

end;

Listagem – Declaração da function GeraCodigo

O próximo passo será criar uma chamada para essa functionao qual será no evento BeforePost do CDSMaster e doCDSDetalhe.

Veja nas instruções abaixo que verifico se estou fazendo umainclusão de registros, se tiver, chamo a function passando comoparâmetro o nome do generator e depois o retorno da function euatribuo para o campo que é o código sequencial.

procedure TDM.CDSMasterBeforePost(DataSet:

TDataSet);

begin

if DataSet.State = dsInsert then

CDSMasterCODMASTER.AsInteger :=

GeraCodigo(‘MASTER_CODMASTER_GEN’);

end;

Listagem - Evento BeforePost do CDSMaster

procedure TDM.CDSDetalheBeforePost(DataSet:

TDataSet);

begin

if DataSet.State = dsInsert then

CDSDetalheCODDETALHE.AsInteger :=

GeraCodigo(‘DETALHE_CODDETALHE_GEN’);

end;

Listagem - Evento BeforePost do CDSDetalhe

Pronto, terminamos as alterações em nosso projeto, veja queforam bem simples. Agora ao incluir um registros no CDSMasterou no CDSDetalhe o código sequencial já estará visível logo após oPost.

O projeto de exemplo contendo as alterações está disponívelem nosso site:

http://www.theclub.com.br/revista/download/DBXMasterDetailIB.zip

Sobre o autorAndré ColaviteConsultor Técnico do The [email protected]

Page 16: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 61 61 61 61 6

Caro leitor da THE CLUB MeGAZINE,

É com grande satisfação que estamos entrando no nosso décimo ano deexistência. Nestes 10 anos o THE CLUB acessorou inúmeras pessoas,ajudou milhares de programadores e difundiu várias linguagens deprogramação, entre elas o Clipper, Visual Objects, o nosso querido Delphi,e também linguagens da Microsoft como o Visual Basic.NET e o C#, danova plataforma .NET.

Nestes 10 anos acumulamos uma vasta experiência, sendo que járespondemos mais de 100.000 questões que foram reportadas ao suportetécnico! Toda esta base de conhecimento sempre esteve disponível à você,que nos acompanha no dia-a-dia, seja pelo seu contato conosco portelefone, e-mail, carta ou pela web, agora com o novíssimo recurso desuporte on-line, onde você mesmo pode achar tudo o que precisa com anossa ferramenta de pesquisa.

A partir deste mês, você acompanhará uma contagem regressiva, ondevamos lembrar toda a história do THE CLUB nestes 10 anos, e estaremospublicando as revistas que foram lançadas no mês de setembro, ano aano, até chegarmos a edição número 1, onde estaremos republicando elainteira, da mesma maneira que foi publica há 10 anos atrás!

Este é um presente que o THE CLUB oferece à você, que tem nosprestigiado ao longo de todos estes anos. Boa leitura, e boas recordações!

Em setembro de 2002, estávamos publicando uma matéria sobre olançamento do Delphi 7, as suas diversas mudanças, e o suporte ao RaveReports, ModelMaker e muito mais. Também tratamos das aplicaçõesWAP com banco de dados, que estava no auge nesta época. A matériaprincipal tratou do DataSnap, escrita por Anderson Haertel Rodrigues.

RetrospectivaRetrospectivaRetrospectivaRetrospectivaRetrospectiva

The Club MegazineThe Club MegazineThe Club MegazineThe Club MegazineThe Club Megazine

Page 17: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log
Page 18: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 81 81 81 81 8

DelphiDelphiDelphiDelphiDelphi

IntraWeb é um modo visual para desenvolver aplicações paraWeb. Neste artigo, mostraremos como usar IntraWeb 5.1.28 emcombinação com Delphi 7 Profissional e aplicações de WebBrokerpara produzir aplicações Web que trabalham com bancos dedados.

Apesar do IntraWeb não ter sido escrito pela Borland, ele éincluído no Delphi 7 Professional e Enterprise. Contudo, existediferença do pacote IntraWeb entre o que acompanha o Delphi 7,sendo no Professional, o IntraWeb “Page Mode” e no Enterprise oIntraWeb “Application Mode”, o qual é bem mais poderoso,contudo, podemos obter um ótimo resultado em “Page Mode”,fazendo uma mesclagem com o aplicações WebBroker comopoderá acompanhar neste artigo.

Um detalhe importante, neste artigo estamos utilizando aversão 5.1.28 do IntraWeb, e assim sendo recomendo vocêatualizar seu IntraWeb, o que poderá ser feito no site dofabricante, Atozed Software (www.atozedsoftware.com).Reforçando, a atualização mais recente e gratuíta (paraprogramadores Delphi 7) do IntraWeb é a versão 5.1.28. Existetambém a versão 6, porém, esta versão não é gratuíta. Nesteartigo, utilizaremos a versão gratuíta.

WebBroker + IntraWeb Page Mode

Bem, para começar, crie uma aplicação WebBroker simples...Para isso, acesse o menu File | New | Other, e selecione “WebServer Application”. Isso lhe apresentará uma caixa de diálogosemelhante a mostrada na Figura 1, onde você deverá selecionar“CGI Stand-alone executable”.

IntraWebIntraWebIntraWebIntraWebIntraWebDesenvolvendo aplicações web Page Mode

com IntraWeb e WebBroker

Adptação: Alessandro Ferreira, [email protected]

Figura 1 – Nova aplicação WebBroker

Assim, será gerada uma nova aplicação WebBroker, na qualpoderá verificar a existência de um WebModule vazio. Salve aaplicação como IWB.dpr e o WebModule para WebMod.pas.

Agora, adicione dois componentes sendo umTIWModuleController e um TIWPageProducer. O componenteTIWModuleController é responsável em fazer os controles detodas as páginas IntraWeb adicionadas ao projeto, e assim sendo,você irá necessitar de apenas um componente deste em seuWebModule. Já, o componente TIWPageProducer, é responsávelem “produzir” páginas IntraWeb, sendo necessário umcomponente para cada página que necessitarmos apresentar.Nosso WebModule ficará semelhante ao apresentado na Figura 2.

Page 19: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 91 91 91 91 9

DelphiDelphiDelphiDelphiDelphi

Antes de continuarmos, adicione uma WebAction (ação) em nossoWebModule. Para isso, dê um duplo clique no WebModule e adicione anova ação, e configure a propriedade “PathInfo” da mesma com ovalor “/IntraWeb”, pois será esta ação a responsável em chamarnosso IWForm. Confira a Figura 3.

Por enquanto, nosso IWPageProducer não está fazendo nada,porém, porque ainda não está conectado a nenhuma páginaIntraWeb. Para gerar uma página IntraWeb, acesse o menu File| New | Other | IntraWeb, conforme apresentado na Figura 4.

Figura 4

Figura 3 – WebActions

Figura 2 – WebModule

Agora, selecione a opção “New Form” o qual lhe apresentaráum Wizard para criação de forms IntraWeb, no qual você deveráselecionar a opção “Page Forms”, conforme apresentado na Figura5.

Figura 5 – Wizard para seleção de Forms

Obviamente, quando trabalhamos com IntraWeb em “PageMode”, devemos ignorar as opções referentes “Application Form”.Outro detalhe, você poderá observar que existem opções “3.2”, aqual é restringindo a HTML 3.2 e oferece suporte a dispositivosPDA, como exemplo celulares. Agora, salve este novo “PageForm” com o nome de IWformMain.pas e retorne ao WebModule.

IntraWeb 5.1 – 1º bug encontrado emnossa abordagem

Observe que depois que você adicionou onovo “Page Form” o qual salvamos comoIWformMain.pas, se abrir o arquivo de projetoIWB.dpr, ele ainda está fazendo referência a“Unit1”, mesmo após termos alterado e gravadonosso “Page Form” como IWfrmMain.pas. Emresumo, para resolver, altere “Unit1”manualmente para “IWformMain.pas”, comoexemplo:

IWformMain in ‘IWformMain.pas’

{IWForm1: TIWPageForm};

Bem, voltando ao nosso WebModule, declare aunit IwformMain na lista de units abaixo da

sessão implementation de nossa unit WebMod (referente ao

Page 20: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 02 02 02 02 0

DelphiDelphiDelphiDelphiDelphi

WebModule). Após isso, declare as units IWApplication eIWPageForm à cláusula “uses” abaixo da sessão interface. Agora,iremos conectar o componente IWPageProducer ao nosso “PageForm”, utilizando para isso o evento OnGetForm do próprioIWPageProducer, conforme poderá acompanhar na Listagem 1.

procedure TIntraWeb.IWPageProducer1GetForm(

ASender: TIWPageProducer;

AWebApplication: TIWApplication;

var VForm: TIWPageForm);

begin

VForm := TIWfrmMain.Create(AWebApplication)

end;

Listagem 1

Implementando nosso IntraWeb Page Form

Você poderá acrescentar todos os tipos de componentesdisponibilizados nas palhetas “IntraWeb” à este novo “PageForm”, o qual posteriormente estará sendo chamado por nossaaplicação WebBroker, de forma bastante simples!

Como exemplo, iremos construir uma aplicação bastantesimples que tem a finalidade de converter graus Celsios paraFahrenheit e vice-versa. Para isso, adicione dois componentesTIWEdit, e ajuste a propriedade “name” para IWEditCelsius eITEditFahrenheit, depois, apenas limpe o conteúdo dapropriedade “text” dos mesmos. Continuando, adicione doiscomponentes TIWButton e ajuste sua propriedade “name” paraIWButtonCelsiusToFahrenheit e IWButtonFahrenheitToCelsiuse sua propriedade “caption” para “Celsius to Fahrenheit” e“Fahrenheit to Celsius”, respectivamente. Nosso IwfrmMaindeverá ficar semelhante a Figura 6.

Figura 6 – IWFrmMain

Note que este form se parece com um form convencional doDelphi, o qual você já está acostumado a trabalhar, há não serpelo fundo branco... Além das aparências, o código à serimplementado para os botões IWButtonCelsiusToFahrenheit eIWButtonFahrenheitToCelsius não trás nenhuma novidade,

como poderá acompanhar na Listagem 2.

// evento OnClick do IWButtonCelsiusToFahrenheit

procedure

TIWfrmMain.IWButtonCelsiusToFahrenheitClick(Sender:

TObject);

begin

IWEditFahrenheit.Text := Format(‘%.2f’,

[StrToFloatDef(IWEditCelsius.Text,0) * 9/5 + 32])

end;

// evento OnClick do IWButtonFahrenheitToCelsius procedure

TIWfrmMain.IWButtonFahrenheitToCelsiusClick(Sender:

TObject);

begin

IWEditCelsius.Text := Format(‘%.2f’,

[(StrToFloatDef(IWEditFahrenheit.Text,0)-32) * 5/

9])

end;

Listagem 2 – Eventos do botão.

Bem, tudo parece estar OK! Assim sendo, o próximo passo écompilar e executar nossa aplicação em browser de internet,então, compile a aplicação e copie o arquivo “IWB.EXE” gerandopela compilação para uma pasta com permissão para execução deCGIs e Scripts de seu servidor WEB, IIS ou PWS, e execute aaplicação via seu browser.

IntraWeb 5.1 – 2º bug encontrado em nossa abordagem

Para quem já está acostumado a trabalhar com aplicaçãoCGI WebBroker, para acessar uma determinada URL bastachamá-la, como exemplo a URL deste exemplo, que poderia serhttp://localhost/scripts/IWB.exe/IntraWeb. Contudo, quandoadicionamos “Page Forms” à nossa aplicação CGI WebBroker, eesta irá necessitar executar alguma ação, mesmo algo simplescomo este projeto, ao invés desta chamar a URL correta, comoexemplo http://localhost/scripts/IWB.exe/IntraWeb, ela apenasposta http://localhost/IntraWeb, o que irá resultar em erro!

Aparentemente o IntraWeb não consegue recuperar o nomecorreto do módulo de executável (aplicações) CGI. Para resolver(mais uma vez manualmente) podemos especificar o caminhocompleto de nosso CGI na propriedade FormAction de nosso “PageForm” e ainda, ajustar a propriedade PostToSelf para False.

Após configurar a propriedade FormAction para http://localhost/scripts/IWB.exe/IntraWeb e a propriedade PostToSelfpara False, recompile sua aplicação e faça o teste da mesma

Page 21: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 12 12 12 12 1

DelphiDelphiDelphiDelphiDelphi

novamente via browser e verá que agora irá funcionar semproblemas, confira a Figura 7.

Figura 7 – Aplicação rodando no browser.

Acessando banco de dados via Page Mode

A seguir, iremos desenvolver mais uma aplicação exemplotrabalhando com “Page Forms” fazendo acesso à um banco dedados Interbase/Firebird. Para isso, certifique-se de ter oInterbase/Firebird instalado em sua máquina para podemosprosseguir.

Bem, crie um novo projeto, seguindo passo-a-passo tudo quejá foi sugerido anteriormente, e neste novo “Page Form” adicioneos seguintes componentes apresentados no Quadro 1.

Componente

sqlConnection

Faça as devidas configurações, acessando obanco de dados EMPLOYEE.GDB que é umbanco de dados exemplo que você deve terem sua máquina.Dica: Utilize a configuração do path do bancode dados da seguinte forma:localhost:c:\pasta\employee.gdb

sqlDataSet

Ajuste sua propriedade sqlConnection para ocomponente sqlConnection adicionadoanteriormente... e sua propriedadeCommandText para:Select * From Customer

DataSetProvider Ligue sua propriedade DataSet ao sqlDataSetanteriormente adicionando.

ClientDataSet Ligue sua propriedade ProviderName aoDataSetProvider anteriormente adicionado.

DataSource Ligado ao ClientDataSet.

Quadro 1 – Componentes para acesso a dados.

Continuando, como estamos trabalhando com o componenteClientDataSet para manutenção nos dados, temos que

programar os eventos AfterDelete e AfterPost domesmo, para que os dados sejam postados aoservidor de banco de dados, veja a Listagem 3.

// evento AfterPost

procedure

TIWfrmMain.ClientDataSet1AfterPost

(DataSet: TDataSet);

begin

ClientDataSet1.ApplyUpdates(0)

end;

// evento AfterDeleteprocedure

TIWfrmMain.ClientDataSet1AfterDelete

(DataSet: TDataSet);

begin

ClientDataSet1.ApplyUpdates(0)

end;

Listagem 3 – Eventos do ClientDataSet

Outro detalhe importante quando trabalhamos com ocomponente ClientDataSet, é em relação ao tratamento de errosque possam ocorrem no momento que os dados forem postados aoservidor de banco de dados. O ClientDataSet oferece um eventochamado OnReconcileError o qual tem exatamente a finalidade dereceber erros gerados durante a atualização, conformeapresentado na Listagem 4.

procedure TIWfrmMain.ClientDataSet1ReconcileError(

DataSet: TCustomClientDataSet; E: EReconcileError;

UpdateKind: TUpdateKind; var Action:

TReconcileAction);

begin

WebApplication.ShowMessage(E.Message)

end;

Listagem 4 – Evento OnReconcileError do ClientDataSet

Bem, agora adicione os controles visuais ao “Page Form”,sendo basicamente alguns TIWDBEdit e TIWLabels, umTIWDBNavigator e um TIWDBGrid. Poderá ver na Figura 8 o“Page Form” já configurado.

Bem, agora adicione os controles visuais ao “Page Form”,sendo basicamente alguns TIWDBEdit e TIWLabels, umTIWDBNavigator e um TIWDBGrid. Poderá ver na Figura 8 o“Page Form” já configurado.

Page 22: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 22 22 22 22 2

DelphiDelphiDelphiDelphiDelphi

Figura 8 – Page Form contendo os componentes

Ajuste a propriedade bgIndicator dentro da propriedade Optionsdo componente IWDBGrid, a qual irá mostrar um pequenoindicador de registros ao lado do registro quando a aplicação forexecutada.

Outro detalhe importante, certifique-se de que oscomponentes ClientDataSet e sqlDataSet estejam com a propriedade“Active” setada para False em tempo de desenvolvimento, pois, oClientDataSet deverá ser ativado via programação no momento queo “Page Form” for executado.

Estando tudo OK, salve e compile a aplicação e novamentecopie o arquivo “IWB.EXE” gerado para seu servidor web ouservidor pessoal para podermos executar um teste com nossanova aplicação, se tudo correu bem, você verá uma telasemelhante a apresentada na Figura 9.

IntraWeb 5.1 – 3º bug encontrado em nossaabordagem

Quando utilizamos esta abordagem de trabalhar com“IntraWeb Page Forms” em conjunto com aplicações WebBroker,ao navegar entre os registros é gerada uma exceção com amensagem “Key Violation” ou simplesmente “HTTP 500 Internalserver error”, dependendo das configurações de seu browser. Este

problema ocorre tanto utilizando executáveis CGI, quanto emDLLs ISAPI, porém, iremos demonstrar uma forma alternativapara solucionar este problema a seguir.

Fixando problemas na navegação de registros em “PageMode”

Na realidade, o problema durante a navegação ocorre porquenão existe uma sessão ou algo semelhante mantendo um estadoda página atual e com isso, o ponteiro do registro se perdedurante a navegação. O “segredo” aqui, será armazenar oponteiro do registro e informá-lo manualmente (mais uma vez?!)ao ClientDataSet e com isso podemos navegar para o próximoregistro e registros anteriores sem problemas, para isso, iremosutilizar o evento OnRender de nosso “Page Form”, conformeapresentado na Listagem 5.

// evento OnCreate

procedure TIWfrmMain.IWPageFormCreate(Sender:

TObject);

var

CustNo: String;

begin

ClientDataSet1.Active := True;

Page 23: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 32 32 32 32 3

DelphiDelphiDelphiDelphiDelphi

CustNo := WebApplication.Request.

ContentFields.Values[‘CUST_NO’];

if CustNo <> ‘’ then

ClientDataSet1.Locate(‘CUST_NO’, CustNo, [])

end;

// evento OnRender

procedure TIWfrmMain.IWPageFormRender(Sender:

TObject);

begin

HiddenFields.Add(‘CUST_NO=’ +

ClientDataSet1CUST_NO.AsString);

end;

Listagem 6 – eventos de nosso “Page Form”

Para que esta solução funcione corretamente, o campo/valorinformado deverá corresponder a um ID único de sua tabela,sugiro utilizar o campo referente sua chave primária para isso,que com certeza não terá problemas.

Conclusão

Você (que possui o Delphi 7Enterprise) pode estar seperguntando qual a vantagem deutilizar o IntraWeb como “PageMode”, sendo que a abordagem“Application Mode” é bem maispoderosa?!

A princípio, aplicaçõesdesenvolvidas como “ApplicationMode” permitem gerar apenas DLLsISAPI, o que é um inconvenientequando não temos um servidor webpróprio, principalmente quando aaplicação já está em produção enecessitamos fazer atualização dareferida DLL, o que já não acontececom aplicações executáveis CGI.

Além de tudo, com um pouquinhomais de trabalho, conseguimos obterquase os mesmos resultados de uma

aplicação “Application Mode”, mesclandouma aplicação WebBroker com IntraWeb.

Outro detalhe importante, é que programadores que possuemo Delphi 7 “Professional”, não tem acesso a desenvolvimento“Application Mode”, restando apenas o “Page Mode”, mas, comopuderam ver neste simples artigo, é possível implementarpoderosas aplicações, com acesso a banco de dados e tudo maisque for necessário, mesmo em “Page Mode”, espero ter ajudado ecaso tenham sugestões, críticas ou dúvidas, sintam-se a vontadepara entrar em contato, abraços e até a próxima!

Download

O projeto de exemplo referente este artigo está disponível paradownload em:

http://www.theclub.com.br/revista/downloads/IntraWebBroker.zip

Figura 9 – Aplicação acessando banco de dados rodando no browser.

Sobre o autor

Alessandro Ferreira,Consultor Técnico do The [email protected]

Page 24: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 42 42 42 42 4

DelphiDelphiDelphiDelphiDelphi

Salve, salve Delphianos!

Vocês já imaginaram a união das melhores tecnologias Webnuma aplicação? A intenção deste artigo é demonstrar a uniãodas tecnologias WebBroker, Mobile, Intraweb e WebServices, demaneira simples e objetiva.

Este artigo foi demonstrado na Borcon 2003, e deu paraperceber a satisfação do público, e o famoso caso do WAP – ame-oou deixe-o.

Visão geral da aplicaçãoAplicação para gerenciamento de veículos na Matrix,

utilizando as seguintes tecnologias:

. WebBroker (base para aplicação)

. WebServices (webservice para consulta de veículos)

. WAP (aplicação para multas)

. Intraweb (cadastro de veículos)

. dbExpress (tecnologia de acesso a dados)

Ferramentas para testar a aplicação:

. Apache 2.036 Servidor Web (www.apache.org)

. Deck – It (emulador wap-browser) www.pyweb.com

Configurações iniciais

. Crie a seguinte estrutura de diretório

Delphi Web HardCoreDelphi Web HardCoreDelphi Web HardCoreDelphi Web HardCoreDelphi Web HardCore

Servidor Web

. Após a instalação do Apache, configure o arquivo httpd.conf(normalmente localizado no diretório “C:\Arquivos deprogramas\Apache Group\Apache2\conf”), como segue:

. localize a seção DocumentRoot e altere para:

DocumentRoot “C:/borcon_matrix/html”

Neste ponto definimos a raiz do nosso servidor principal.. localize a seção ScriptAlias, e insira a linha que segue:

ScriptAlias /scripts/ “c:/borcon_matrix/scripts/”

<Directory “C:/borcon/scripts”>

AllowOverride None

Options None

Order allow,deny

Allow from all

</Directory>

Neste ponto estamos configurando o subdiretório virtual (/scripts) para execução de scripts CGI.

No final do arquivo, insira a configuração para o nosso

<VirtualHost localhost>

ServerAdmin [email protected]

DocumentRoot “c:/borcon_matrix/html”

ServerName nome_do_seu_computador

</VirtualHost>

Salve o arquivo e reinicie o Apache.

Script do Banco

No exemplo estamos utilizando o SGDB Interbase 6.02. Figura 1 – Estrutura de Diretórios

por Emerson Facunte

Page 25: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 52 52 52 52 5

DelphiDelphiDelphiDelphiDelphi

SET SQL DIALECT 3;

/* CREATE DATABASE ‘c:\borcon\matrixdb.gdb’

PAGE_SIZE 4096

DEFAULT CHARACTER SET */

/* Table: MULTAS, Owner: SYSDBA */

CREATE TABLE “MULTAS”

(

“MLT_CODIGO” INTEGER,

“MLT_PLACA” VARCHAR(7),

“MLT_DATA” DATE

);

/* Table: VEICULOS, Owner: SYSDBA */

CREATE TABLE “VEICULOS”

(

“VEI_PLACA” VARCHAR(7) NOT NULL,

“VEI_MODELO” VARCHAR(30),

“VEI_PROPRIETARIO” VARCHAR(30),

“VEI_ANO” INTEGER,

“VEI_COR” VARCHAR(20),

PRIMARY KEY (“VEI_PLACA”)

);

Criando a aplicação1ª. Fase – criação da base e aplicação wapWebBroker

. Iniciar aplicação Other.../WebServices.

. Selecione o modelo Soap Server Application.

. Em seguida, selecione a opção do modelo CGI para facilitar oaprendizado.

. Grave a unit como um_wmMatrix.pas e o projeto comoMatrixDriver.DPR

. Altere o nome do container para wmMatrixV.

Repare que utilizamos o assistente do WebServices para criaro nosso WebBroker com os objetos-base para criação doWebServices.

Objetos de Dados

. Insira um objeto SQLConnection [dbExpress], e altere asseguintes propriedades:

. Através do duplo-clique, entre no assistente.

. Crie uma nova conexão Interbase clicando no botão [ + ]. . Database = localhost:c:\borcon_matrix\matrixdb.gdb. SQLDialect = 3. Login Prompt = False. Name = conexao. Connected = True. Insira um objeto SQLDataSet [dbExpress], e altere as

propriedades que seguem:. SQLConnection = conexão. CommandText = INSERT INTO MULTAS VALUES (:CODIGO, :PLACA,

:DATA). Agora vamos criar o documento WML para interagir com o

celular. Através das opções File.../New.../Other.../Web Documents,

selecione a opção WML Document. Insira o código que segue.

<wml>

<card id=”inclusao”>

<p align=”center”>

Matrix Multas

<br/>

<br/>

</p>

<p>

placa <input type=”text” name=”placa”/>

<select name=”multa” title=”codigo multa”>

<optgroup title=”multa”>

<option value=”1">rodizio </option>

<option value=”2">velocidade</option>

<option value=”3">vermelho</option>

</optgroup>

</select>

<do type=”accept” label=”CONFIRMA”>

<go href=”wapconfirma” method=”post”>

<postfield name=”placa” value=”$placa”/>

<postfield name=”multa” value=”$multa”/>

</go>

</do>

</p>

</card>

</wml>

. Grave o documento no subdiretório

C:\Borcon_Matrix\HTML com o nome:MULTA.WML

Neste ponto vamos inserir o objeto responsável pela produção

Page 26: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

Figura 2 – Testando o módulo WAP

Figura 3 – Tipo da Multa

Page 27: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 72 72 72 72 7

DelphiDelphiDelphiDelphiDelphi

de mensagens para clientes WAP.

. Insira um objeto do PageProducer [Internet] e configure asseguintes propriedades:

HTMLFile = C:\borcon_matrix\html\multa.wmlName = PPWAP.

Com isso concluímos as definições iniciais da nossa aplicação.

Ações para o cliente WAP

Neste ponto iremos criar as ações necessárias para o móduloWAP.

.Através do duplo-clique no wmMatrixV adicione uma Action(primeiro speed button, ou tecla INS), alterando as seguintespropriedades:

Name = actWAPPathInfo = /wap. Insira o código a seguir no evento OnAction deste objeto:

Response.ContentType:=’text/vnd.wap.wml’;

Response.Content:=ppWap.Content;

Neste ponto criamos a ação que dispara a tela para aplicaçãode multas no através do celular, embutida no arquivo WML,criado anteriormente.

Agora iremos criar a ação para gravar a operação do usuário:

.Através do duplo-clique no wmMatrixV adicione uma Action(primeiro speed button, ou tecla INS), alterando as seguintespropriedades:

Name = actWAPConfirmaPathInfo = /wapconfirma. Insira o código a seguir no evento OnAction deste objeto:

Response.ContentType:=’text/vnd.wap.wml’;

try

with sqlWapInsere do

begin

ParamByName(‘codigo’).Value:=StrtoInt

(Request.ContentFields.Values[‘multa’]);

ParamByName(‘placa’).Value:=

Request.ContentFields.Values[‘placa’];

ParamByName(‘data’).Value:=Now;

ExecSQL();

end;

Response.Content:=’<wml><card

id=”mensagem”><p>multa aplicada</p></card></wml>’;

except

On E:Exception do

begin

Response.Content:=’<wml><card

id=mensagem><p>falhou [‘+E.Message+’]</p></card></

wml>’;

end;

end;

Testando a primeira fase da aplicação

Através das opções Project/Options...Directories/Conditionals,configure o parâmetro Output Directory apontando paraC:\Borcon_Matrix\Scripts.

Salve e compile a aplicação.

Através do utilitário Deck-It, teste a aplicação, digitando aseguinte URL:

http://localhost/scripts/MatrixDriver.exe/WAP

A figura 2 ilustra nossa aplicação.

Utilize os controles do celular para informar a placa e o tipode multa (figura 3)

Selecionando o tipo da multa... (ver figura 3)

Confirme a operação e veja o resultado.

Com isso concluímos a primeira parte do artigo.

No próximo mês teremos o cadastro de veículos utilizando atecnologia Intraweb.

Forte abraço à todos.

Sobre o autorEMERSON FACUNTE ([email protected]

Consultor de Tecnologia com diversos livros publicados,especialista em desenvolvimento de aplicações e-Busi-ness utilizando a ferramenta Delphi, baseado emWebSnap, DataSnap, BizSnap e ISAPI/Apache Modules.

Page 28: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 82 82 82 82 8

DelphiDelphiDelphiDelphiDelphi

Introdução

Entre várias novidades, o Delphi 7 trouxe um gerador derelatórios chamado Rave Reports, o qual é bastante poderoso,porém, o modo de trabalhar é bastante diferente em relação aoQuickReport, pois ele possui um projeto próprio de relatório o qualgera um arquivo externo ao projeto, apesar de ser possívelembutir junto ao executável, porém, nosso foco neste pequenoartigo será em relação a carga dinâmica de imagens em nossorelatório Rave.

Criando um novo relatório

Neste exemplo, vamos utilizar como fonte de dados, umaruqivo XML chamado Country, o qual está disponível na pasta...\Borland Shared\Data.

Então, crie um novo projeto no Delphi e salve-o como“RvJpg” e sua unit para “unRvJpg” e adicione os seguintes

Rave ReportsRave ReportsRave ReportsRave ReportsRave ReportsCarregando Imagens DinâmicanteCarregando Imagens DinâmicanteCarregando Imagens DinâmicanteCarregando Imagens DinâmicanteCarregando Imagens Dinâmicante

componentes à este novo form, como mostra a Figura 1.

Agora, partiremos para ajustar as propriedades destescomponentes, onde iremos abordar apenas os mais significativos,visto algumas configurações serem triviais...

RvProject* Engine ->RvSystem* Name -> RvProject* ProjectFile ->RvJPEG.ravClientDataSet* Name -> cdsCountry* FileName -> country.xml* Active -> true

TRvDataSetConnection* Name -> rvdsCountry* DataSet -> cdsCountry

Figura 1 – Nosso formulário

Alessandro Ferreira, [email protected]

Page 29: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 92 92 92 92 9

Estando feitas estas configurações, partiremos para o designde nosso relatório. Para isso, dê um duplo-clique no componenteRvProject para acessar o Rave Designer.

Estando no Rave Designer, vá ao menu File | New paraadicionar um novo relatório e após isso, salve o mesmo com onome de RvJPEG.rav. Agora, novamente no menu File, cliquena opção New Data Object e selecione a opção “Direct Data View”e “Next” e se você seguiu os passos anteriores, verá nossocomponente rvdsCountry, bastando clicar em Finish paraconcluir.

Para aceleramos a confecção de nosso relatório, vá ao menuTools | Report Wizard, opção esta que irá abrir um form deconfiguração semelhante a Figura 2.

Clique em “Next” e o próximo passo será selecionar os camposque irão aparecer no relatório, conforme apresenta a Figura 3.

Vá clicando “Next” até chegar em “Report Layout Options”,conforme mostra a Figura 4.

Clicando mais um vez em “Next”, chegaremos ao últimopasso sugerido pelo Wizard, onde você poderá configurar a fonte deletra dos “texts” disponibilizados sobre as bandas, onde parafinalizar, bastará clicar em “Generate” e com isso nosso relatórioestará criado. Em nosso exemplo, mostraremos apenas o campo“Name” e ao lado do mesmo iremos adicionar um componentechamado Bitmap disponível na aba Standard do Rave Designer.

A Figura 5 apresenta o layout sugerido para nosso relatório.

Figura 2 – Primeiro passo do Wizard

Figura 4 – Report Layout Options

Figura 3 – Selecionando campos no Wizard

Figura 5 – Layout sugerido

DelphiDelphiDelphiDelphiDelphi

Page 30: Revista The Club Megazine - 09/2003 - O maior clube de ... · - “Triggers” - excelente para melhorar autorizações de segurança mais complexas e para fornecer eventos de log

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE3 03 03 03 03 0

Salve tudo e aqui finalizamos nosso trabalho dentro do Rave Designer,podendo fechá-lo por enquanto.

Mostrando a Imagem DinâmicamenteEstando agora na IDE do Delphi, iremos implementar o código responsável

em mostrar a imagem no componente Bitmap existente em nosso relatório. Paraesta abordagem, iremos utilizar o evento OnGetRow do componentervdsCountry, conforme poderá acompanhar na Listagem 1.

procedure TForm1.rvdsCountryGetRow(Connection: TRvCustomConnection);

var B: TRaveBitmap; P: TRavePage; Jpg: TJpegImage;begin{Cria Objeto JPEGImage para carregar o arquivo Jpeg.} Jpg := TJpegImage.Create; try {Pesquisa componentes dentro do projeto rave.} P := RvProject.ProjMan.FindRaveComponent

(‘Report2.MainPage’, nil) as TRavePage; B := RvProject.ProjMan.FindRaveComponent

(‘rvImage’, P) as TRaveBitmap;{verifica se existe um JPG referente ao país atual.} if FileExists(cdsCountry.FieldByName

(‘Name’).AsString+’.jpg’) then begin {Carrega o arquivo do disco.} Jpg.LoadFromFile(cdsCountry.FieldByName

(‘Name’).AsString+’.jpg’); {Atribui ao Rave Bitmap component.} B.Image.Assign(Jpg); end else {senão encontrar a imagem, insere umagenérica} begin Jpg.LoadFromFile(‘pirata.jpg’); B.Image.Assign(Jpg); end; { Recall the event.} Connection.DoGetRow; finally Jpg.Free; end;end;

Listagem 1 – Código do evento OnGetRow.

Para melhor explicarmos, iremos analisar os pontos mais significativosapresentados na Listagem 1. Observe que declaramos três variáveis, sendo:

B: TRaveBitmap -> variável que irá conter a referência do componenteBitmap existente em nosso relatório;

P: TRavePage; -> variável que irá conter a referência da página onde ocomponente Bitmap foi disponibilizado no relatório;

Jpg: TJpegImage ->Responsável em carregar a imagem JPG existente emdisco;

Continuando, instânciamos o objeto TJPegImage na variável Jpg. Após isso,vem um ponto muito importante em nossa abordagem onde através do métodoFindRaveComponent do componente RvProject, iremos “pegar” a referência dapágina existente em nosso relatório e logo em seguida, tendo a referência dapágina atribuída à variável “P”, iremos dentro desta página “pegar” a referênciaao componente Bitmap disponibilizado sobre a mesma. As próximas instruçõesbasicamente irão apenas buscar a imagem (JPG) em disco e atribuir aocomponente Bitmap. Observe que ao término desta abordagem, chamamos ométodo DoGetRow do parâmetro Connection existente neste evento, o qualtem a finalidade de forçar o processamento deste evento.

Importante: Declare as seguintes units abaixo da sessão implementation:uses RVClass, RVProj, RVCsStd, Jpeg;

Dica: O evento OnGetRow será executado a cadaregistro processado em nosso relatório.

Finalizando, apresentamos na Listagem 2 o código utilizado na chamada denosso relatório.

procedure TForm1.Button1Click(Sender: TObject);

begin

with RvProject do

begin

// Carrega o projeto de relatório Rave.

ProjectFile := ‘RvJPEG.rav’;

// Executa o relatório.

Execute;

end;

end;

Listagem 2 – Chamada do relatório

ConclusãoApresentamos neste pequeno artigo, um macete que podemos empregar afim

de aproveitar melhor os recursos do Rave Reports, que é uma excelenteferramenta, porém, pecando ainda no quesito documentação, o que obriga-nos aefetuar testes e em cima de tentativas e erros ir desvendando o caminho daspedras... Espero que esta dica possa ser últil à você, lembrando que além deimagens, você poderá efetuar outras abordagens através deste evento e, qualquerdúvida ou sugestão, sinta-se a vontade em nos enviar. Até a próxima!

DownloadO projeto de exemplo referente este artigo está disponível para download no

seguinte endereço: http://www.theclub.com.br/revista/downloads/RaveJPeg.zip.

Sobre o autorAlessandro Ferreira, Consultor Técnico do TheClub - [email protected]

DelphiDelphiDelphiDelphiDelphi