Escolar Documentos
Profissional Documentos
Cultura Documentos
final criar seus prprios relatrios (se eles saberiam explorar o potencial da ferramenta era
um outro problema!).
A integrao dessas ferramentas com as aplicaes desenvolvidas era (e ainda ) uma
experincia traumtica. A aplicao torna-se elemento secundrio e a ferramenta de
relatrios a maior consumidora de recursos.
Sem alternativas, os desenvolvedores partiram para o uso massivo de ferramentas de
relatrios visuais baseados na tcnica "Point and Click, Drag and Drop:". Funcionava? Sim,
desde que se limitassem ao desenvolvimento baseado em listagens, queries, agrupamentos
e bandas de dados e, colocassem na cabea de seu exigente usurio que aquele relatrio
era tudo o que ele sabia (ou podia) fazer. Cabe aqui citar aquela mxima do
desenvolvimento: "A complexidade do programa cresce tanto at exceder a competncia
do programador". Nesse contexto a competncia era limitada ausncia de flexibilidade da
ferramenta adotada.
A misso tendia a tornar-se impossvel quando o relatrio pretendido no seguia nenhuma
conveno no layout, extrao, processamento e gerao dos dados finais. A complexidade
era tanta que o uso de um QuickReport ou ReportSmith (ahh ReportSmith! algum se
lembra dele?) costumava consumir mais horas de desenvolvimento dos relatrios do que o
tempo alocado codificao do projeto. Sem contar que eles geravam um modelo chamado
"no-me-toque... seno estraga tudo". Quem de ns nunca arrastou acidentalmente um
campo de um relatrio altamente sobrecarregado e sofreu para recoloc-lo no lugar de
origem?
Na minha modesta opinio, o mal das ferramentas de construo de relatrios puramente
baseadas no mtodo visual reside na errnea assertiva de que elas podem abstrair toda e
qualquer complexidade do processamento de regras de negcios envolvendo um conjunto
de dados. Elas se propem a ser uma espcie de remdio genrico para qualquer mal. Uma
bala de prata...
Sou desenvolvedor Delphi desde a verso 1.0 (passei por todas as verses conhecidas do
Turbo Pascal). Hoje estou me adaptando verso 7.0. Nessa seta do tempo, experimentei
vrias solues para a criao de relatrios, indo do canvas da impressora ao Crystal
Reports (excelente ferramenta, diga-se de passagem). Avaliei inclusive solues de Cubo e
Business Intelligence sem nunca ter adotado uma soluo definitiva, pois conforme a
complexidade do projeto (e da cabea do usurio), ferramentas distintas seriam utilizadas,
chegando em alguns casos adoo de ferramentas mltiplas para propsitos similares.
Na poca do Delphi 1.0 (e Delphi 2.0) me aprofundei no QuickReport (ReportSmith era um
elefante branco, umas dez vezes mais pesado que sua aplicao!). QuickReport, ferramenta
interessante, pequena, leve, drag'n drop, stand-alone, 100% Delphi, boa opo? Acreditei
que sim. Comprei o pacote full com a "turma" da QuSoft, peguei o cdigo fonte e comecei
a "aventura".
Misso: Criar minha prpria biblioteca de rotinas que aliasse o poder da criao de
relatrios via cdigo runtime com a facilidade da interface grfica, seria o melhor de dois
mundos. Foi uma tima experincia, cheguei a escrever alguns artigos (procure ai pela Net.
Com um pouco de sorte voc achar algo nos mecanismos de busca, com meu nome
invariavelmente ligado ao QuickReport).
QuickReport, decepo total, era bug atrs de bug, comportamento instvel e bastante
problemtico. A quantidade de problemas detectados foi uma barreira. Semanalmente
mandava e-mail pros noruegueses pedindo uma soluo. Pasmem, existem bugs j
detectados no Delphi 1.0 e at hoje no foram corrigidos (Acho que virou feature). Foi uma
beno a Borland ter se livrado dele. No d nem para dizer que foi bom estar com voc,
brincar com voc...
O pacote do ReportBuilder da Digital-Metaphors sempre foi uma seduo, j imaginou uma
variante do Crystal Reports embutido nos meus sistemas? O usurio criando seus prprios
relatrios? uma sute realmente profissional, porm puramente visual, a tcnica de
controle de cdigo muito trabalhosa e muito presa aos objetos do relatrio. A reutilizao
de solues em outros projetos extremamente difcil, contudo isso no chega a ofuscar o
brilho do produto, suas qualidades cobrem seus defeitos.
O site do Torry me conduziu uma empresa pequena que estava comeando o
desenvolvimento de um novo produto para relatrios no Delphi 1.0, a Nevrona. Eles
lanaram no mercado um pacote de componentes sem recursos visuais. Se assemelhava
uma espcie de Printer.Canvas com preview de impresso. A soluo me chamou a ateno
pelo fato deles terem feito o caminho inverso dos outros componentes: Ao invs de partir
do modo grfico para chegar ao modo cdigo, ele partiram do modo cdigo at chegar ao
grfico. Prepararam previamente um arsenal de rotinas bsicas (tratamento de fontes,
posicionamento, cores, grficos, primitivas grficas, controle de cursor, paginao, ...) para
ento projetarem o mdulo baseado em tcnicas visuais ( a utilizada na IDE do RAVE ). O
desenvolvedor era incentivado a usar cdigo (!), a parte grfica estava implcita e s fazia
diferena no resultado final. O propsito desta soluo no era DESENHAR relatrios e sim
ESCREV-LOS.
Esse componente no era interessante, era fantstico pois dava ao desenvolvedor Delphi o
poder que faltava: usar uma linguagem poderosa para criar relatrios e assumir o controle
total do seu processamento e regras de negcios envolvidas no tratamento do conjunto de
dados. Era praticamente impossvel trabalhar com ele sem se sentir tentado a criar sua
prpria biblioteca de desenvolvimento de relatrios. Sua arquitetura era um convite
espontneo sua expanso.
Consegui enfim desenvolver minha biblioteca de criao de relatrios e a tenho utilizado ao
longo de 7 anos (ei, essa no a idade do Delphi?) sem nunca ter me deparado com
problemas de impresso de relatrios sem soluo. Muitos amigos seguiram tambm o
mesmo caminho e nem sentiram a "presena da ausncia" (parafraseando Saint-Exuperry)
do QuickReport. A adoo do RAVE pela Borland denota alis uma grande maturidade de
ambos os produtos.
O RAVE, que se chamava na poca ReportPrinter Pro, sempre concorreu juntamente com o
ReportBuilder ao prmio de melhor ferramenta de relatrios para o Delphi durante vrios
anos seguidos. Creio que chegou a ganhar alguns Delphi Informant Reader's Choice.
Com relao s tcnicas do RAVE, nada de novo foi inventado, foi apenas resgatado o
conhecimento do desenvolvedor mais experiente j acostumado a escrever relatrios que
extrapolam os limites de simples listagem de dados. Essa ser, talvez, a maior dificuldade
a ser enfrentada pelos desenvolvedores presos s tcnicas puramente visuais. Ser exigido
um conhecimento maior de algoritmos de extrao, tratamento e agrupamento de dados.
PS: O material exposto expressa a opinio pessoal do autor baseado numa longa experincia de
desenvolvimento de solues corporativas em Delphi e ferramentas de criao de relatrios
(independentes e/ou integradas IDE da linguagem).
Percebi alguns pequenos bugs na verso 5.0 do RAVE, principalmente na sua IDE de
criao de relatrios. A Nevrona est prometendo para breve um patch de correo.
Um bug interessante (se que Bugs podem ser interessantes) acontece na verso 98 do
Windows. quando o usurio tenta salvar um relatrio criado na IDE. Uma mensagem de
erro o informar que no existe espao livre no disco rgido (!). O relatrio s ser salvo se
voc apont-lo para a pasta raiz do drive. Cheguei a essa concluso depois de perder
vrios trabalhos desenvolvidos na IDE.
O desenvolvedor inicialmente enfrentar o problema da falta de documentao e demos
atualizados para a verso adotada pelo Delphi 7.0. Isto ser apenas uma questo de
tempo, pois esta ser a soluo oficial para criao de relatrios em Delphi partir da
verso 7.0.
No percebi mudanas substanciais na engine bsica do componente. Acredito que essa
evoluo tenha caminhado basicamente para o lado do design de relatrios usando a IDE
do RAVE.
Os legionrios do ReportBuilder (http://www.digital-metaphors.com) a acharo muito
confusa, e realmente . Levem em considerao que essa IDE bastante nova, se
comparada ao ReportBuilder, que j est no mercado desde o Delphi 2.0. A Nevrona ainda
tem muito o que aprender com a Digital-Metaphors.
A
propsito,
nos
fruns
"borland.public.delphi.thirdparty-tools"
e
"borland.public.delphi.reporting-charting" est acontecendo um duelo de tits entre os
criadores do RAVE e do ReportBuilder. Vale a pena acompanh-la, uma discusso de altonvel onde cada um expe os recursos de sua ferramenta em comparao com a
concorrente. Se voc no usa News, procure pelas palavras "Delphi" "RAVE"
"ReportBuilder" no http://groups.google.com.
Para conhecer melhor o produto RAVE, recomendo o download da documentao oficial da
Nevrona nos endereos abaixo. So dois arquivos PDF (mais de 600 pginas) com uma
excelente descrio tcnica e funcional das classes do pacote.
Para exemplificar, vamos fazer um pequeno projeto que imprime na posies 1cm x 1cm
(linha e coluna) da pgina a palavra Hello World com fonte Arial, tamanho 20 na cor
vermelha:
Coloque no Form um componente RVSystem, um Boto e escreva o cdigo abaixo no
evento onClick desse boto:
procedure TForm1.Button1Click(Sender: TObject);
begin
RVSystem1.SystemPreview.FormState := wsMaximized;
RVSystem1.DefaultDest := rdPreview; { poderia ser rdPrinter para impressora }
RVSystem1.SystemPrinter.Units := unCM; { Vamos trabalhar em Centimetoros }
RVSystem1.Execute;
end;
Execute seu projeto e veja que j conseguimos criar um relatrio com uma pgina em
branco.
D uma olhada com mais tempo nas propriedades do componente TRVSystem e ver que
muitas configuraes podero ser realizadas em tempo de projeto visualmente no Object
Inspector do Delphi.
Antes de partir para o cdigo do "Hello World", convm esclarecer um fato muito
importante para a criao de relatrios usando esse componente.
No tempo das linguagens texto (sweet remembers), os desenvolvedores usava como
coordenadas para a impresso de textos as linhas e colunas do papel (ou do vdeo), e a
medida era sempre baseada em um padro de fonte de tamanho fixo, ou seja, a letra "i"
ocupava o mesmo espao da letra "W", assim podia-se precisar que uma pgina A4
comportava no mximo 80 colunas (a 10 CPI) e em torno de 60 linhas (a 6 LPI). Podamos
afirmar sem medo de errar que uma string de 40 caracteres ocuparia 50% da largura da
pgina. Dentro dessa premissa, era possvel efetuar o alinhamento da cabea de impresso
simplesmente enviando espaos vazios at chegar posio desejada, e ai ento, imprimir
o prximo contedo. Era uma forma rpida de se conseguir tabulao. Algumas linguagens,
como o Clipper permitiam o posicionamento absoluto via coordenadas de impresso,
contudo ainda era baseada numa quantidade de caracteres de tamanho fixo.
No Windows a tcnica bem diferente. Existe um negcio chamado Fontes TrueType que
jogou por terra o projeto de relatrios estruturados em espaamento fixo de caracteres.
Nessa nova modalidade de impresso no possvel afirmar que o espao ocupado pelas
palavras "relatrio" ou "impresso" sero idnticas, apesar de ambas possurem a mesma
quantidade de caracteres. A diferena que nesse novo ambiente a letra "i" no ocupar o
mesmo espao imprimvel da letra "m" pois os caracteres possuem tamanho varivel.
Quem j tentou alinhar textos no Microsoft Word usando apenas a barra de espaos sabe
do que estou falando.
Nada impede contudo o uso de fontes mono-espaadas nos relatrios (aquelas em que
qualquer caracter possui o mesmo tamanho), por exemplo a Courier new. Essa no uma
boa tcnica, porm no regra.
Para permitir a tabulao da impresso, o RVSystem utiliza o posicionamento em uma
unidade de medida definida pelo usurio. O default Polegadas. Isto configurado atravs
da propriedade RVSystem1.SystemPrinter.Units. No meu exemplo, definirei que trabalharei
em Centmetros (unCM). Assim todas as vezes que eu referenciar uma impresso em uma
determinada posio da pgina estarei falando:
Imprima o texto "Hello World" na linha 1, coluna 1, eqivale a: desa o cursor 1 centmetro
abaixo da margem superior e desloque 1 centmetro partir da margem esquerda para
ento imprimir o texto. Parece confuso mas na prtica bastante simples. Para nossa
sorte, o RVSystem bastante completo e j incorpora internamente rotinas para controle
da pgina e posicionamento do cursor.
Para facilitar o mapeamento das colunas, o RVSystem dispe de uma rgua que pode ser
apresentada no Preview de Impresso, assim no ser necessrio adivinhar as
coordenadas. Para mostrar a rgua acrescente o cdigo abaixo antes do mtodo Execute:
RVSystem1.SystemPReview.RulerType := rtBothCm;
PS: a rotina de converso possua um pequeno bug na converso de polegadas para
centmetros o que provocava alguns posicionamentos errados na impresso de campos do
tipo memo. No sei se foi corrigido nesta verso (eu uso a verso anterior, e realizei
minhas prprias modificaes nos arquivos fontes).
Voltando ao nosso projeto, ao disparar o mtodo Execute, iremos utilizar o evento onPrint
para escrever o nosso "Hello World".
Uma vez disparado o mtodo Execute, e instanciado o objeto TRVSystem, o desenvolvedor
contar com uma classe interna do objeto extremamente rica em recursos, a
TBaseReport. Ela est disponvel no nosso projeto usando a seguinte sintaxe:
RVSyste1.BaseReport. Veja na documentao quantas centenas de rotinas estaro
disponveis para trabalharmos o relatrio. Essa classe nossa porta de entrada para o
mundo da escrita de relatrios.
Um cuidado a ser observado que nenhum mtodo dessa classe poder ser chamado antes
de ser acionado o mtodo Execute do RVSystem. Qualquer tentativa errnea provocar
"Access Violation", desta maneira, s utilize-a dentro dos eventos do objeto.
Veja como configurar o evento onPrint do RVSystem para imprimir o Hello World na posicao
1,1, na fonte Arial, tamanho 20, cor vermelha.
procedure TForm1.RvSystem1Print(Sender: TObject);
begin
With Sender as TBaseReport do Begin
GotoXY(1,1); // Coluna 1cm, linha 1cm
FontColor := clRed; // Modifica a fonte padro
FontSize := 20;
FontName := 'Arial';
FontColor := clRed;
Print('Hello World'); // Imprime o texto
End;
end;
Esse cdigo poderia ter sido escrito de outra forma (vide abaixo), porm optei por escrevlo da forma que a Nevrona recomenda em seus exemplos.
procedure TForm1.RvSystem1Print(Sender: TObject);
begin
RVSystem1.BaseReport.GotoXY(1,1);
RVSystem1.BaseReport.FontColor := clRed;
RVSystem1.BaseReport.FontSize := 20;
RVSystem1.BaseReport.FontName := 'Arial';
RVSystem1.BaseReport.FontColor := clRed;
RVSystem1.BaseReport.Print('Hello World');
end;
No primeiro artigo eu disse que a estrutura do RAVE era um convite tentador criao de
bibliotecas personalizadas. Veja o cdigo acima... Voc no se sente tentado a escrever
uma procedure para imprimir um texto, na posio e caractersticas visuais desejadas
usando apenas uma linha de programao? Eu no resisti... desculpe... j transformei-o
em uma procedure chamada PrintString. Veja o resultado:
Procedure PrintString(
RVSystem:TRVSystem; // Objeto do RAVE
Row: Double; // Linha
Column:Double; // Coluna
TextToPrint:String; // Texto a ser impresso
NewFontName:String; // Fonte
NewFontSize:Integer; // Tamanho
NewFontColor:TColor // Cor
);
Begin
With RVSystem.BaseReport do Begin
GotoXY(Column,Row);
FontColor := NewFontColor;
FontSize := NewFontSize;
FontName := NewFontName;
Print(TextToPrint);
End;
End;
A chamada agora no evento onPrint ser apenas:
procedure TForm1.RvSystem1Print(Sender: TObject);
begin
PrintString(RVSystem1,1,1,'Hello World','Arial',20,clRed);
end;
No est acreditando? Rode ento... Imagine as possibilidades... o RVSystem possui
centenas de mtodos prontos e voc pode criar quantos quiser e montar suas prprias
bibliotecas.
Isso foi apenas um aperitivo. Nos prximos artigos estarei abordando o controle da pgina,
impresso e bancos de dados.