Rave Reports Code Based
por Fábio Miaco.
Quando utilizamos o Rave Reports para gerar algum relatório em nossa aplicação, podemos fazê-lo de duas formas, uma é utilizar o Rave Designer (forma mais conhecida), uma outra é utilizar o Code Based (Baseado em Código), é esta ultima forma que veremos neste artigo. Mãos á obra!!!
Criando a aplicação
Crie uma nova aplicação no Delphi, insira e configure os seguintes componentes:
Componente |
Database |
Paleta |
BDE |
AliasName |
Alias apontando para DBDemos.gdb |
DataBaseName |
Rave |
LoginPrompt |
False |
|
|
Componente |
Query |
Paleta |
BDE |
DataBaseName |
Rave |
SQL |
Select * from CUSTOMER |
Carregue os Fields no FieldsEditor da Query1.
Agora vamos montar o form para demonstrar os registros. Insira no form os seguintes componentes:
Componente |
DataSource |
Paleta |
DataAccess |
DataSet |
Query1 |
|
|
Componente |
DBGrid |
Paleta |
DataControls |
Align |
alTop |
DataSource |
DataSource1 |
|
|
Componente |
DBNavigator |
Paleta |
DataControls |
Align |
alTop |
DataSource |
DataSource1 |
|
|
Componente |
Panel |
Align |
alClient |
Caption |
Vazio |
Query1.Open;
Neste momento já temos nossa aplicação acessando e demonstrando os registros da tabela Customer.
Criando o Relatório
Insira um componente RVSystem no formulário e altere as seguintes propriedades:
(SystemPreview) FormState |
wsMaximized |
(SystemPrinter) MarginBottom |
1 |
(SystemPrinter) MarginLeft |
1 |
(SystemPrinter) MarginTop |
1 |
(SystemPrinter) MarginRight |
1 |
(SystemPrinter) Units |
unCM |
Este relatório irá demonstrar as seguintes colunas:
Company (Companhia)
Addr1 (Endereço)
City (Cidade)
State (UF)
No evento OnBeforePrint do RVSystem insira o seguinte código:
with Sender as TBaseReport do
begin
SetPaperSize(DMPAPER_A4,0,0);
ClearTabs;
SetTab(1.0,pjLeft,6.0,0,BOXLINENONE,0);
SetTab(NA ,pjLeft,6.0,0,BOXLINENONE,0);
SetTab(NA ,pjLeft,5.0,0,BOXLINENONE,0);
SetTab(NA ,pjLeft,2.0,0,BOXLINENONE,0);
SaveTabs(1);
end;
O Comando SetPaperSize, configura qual tamanho de página iremos trabalhar, vale lembrar que se você preferir informar o tamanho da página, ao invés de usar a constante como fizemos, é necessário fazer da seguinte maneira:
SetPaperSize(0, 21, 29.7)
No código acima montamos a estrutura do nosso relatório. Vamos entender o que é cada parâmetro informado no SetTab.
SetTab(Posição de Impressão, Alinhamento do Texto, Tamanho da Coluna, Margem, Borda, Contraste)
O SaveTabs, salva essa estrutura para podermos utilizar quando formos montar o relatório.
Agora no evento OnPrintHeader insira o seguinte código para montarmos o cabeçalho do relatório:
with Sender as TBaseReport do
begin
SetFont('Arial',12);
Bold := True;
PrintCenter('Relatório Code Based',PageWidth/2);
NewLine;NewLine;
SetFont('Arial',10);
Bold := True;
RestoreTabs(1);
PrintTab('Companhia');
PrintTab('Endereço');
PrintTab('Cidade');
PrintTab('UF');
NewLine;NewLine;
MoveTo(1.0,2.5);
LineTo(20,2.5);
end;
No código acima foi configurada uma fonte para o cabeçalho (Arial, 12), deixamos a fonte como negrito, o PrintCenter tem como parâmetro uma String e a Posição a ser impressa, o MoveTo e LineTo são responsáveis por traçar uma linha nas coordenadas passadas em seu parâmetro, o RestoreTabs restaura a configuração salva no BeforePrint e o PrintTab imprime a string que recebe como parâmetro de acordo com a seqüência da configuração do Tab salvo.
Insira um botão no panel do form, modifique o Caption do Botão para Imprimir e no evento OnClick insira o seguinte código:
with Sender as TBaseReport do
begin
SetFont('Arial',9);
Bold := False;
Query1.First;
Query1.DisableControls;
while not Query1.Eof do
begin
RestoreTabs(1);
PrintTab(Query1COMPANY.AsString);
PrintTab(Query1ADDR1.AsString);
PrintTab(Query1CITY.AsString);
PrintTab(Query1STATE.AsString);
Query1.Next;
NewLine;
end;
Query1.EnableConstraints;
end;
Essa tela de Output pode ser configurada, ou simplesmente retirada quando geramos o relatório. No componente RvSystem verifique a propriedade SystemSetups, essa propriedade é composta por várias propriedades que influenciam na tela de Output, por exemplo altere as propriedades ssAllowDestPrinter , ssAllowDestFile e ssAllowSetup para False, execute novamente o programa e clique no botão.
Você verá que o relatório abriu diretamente na tela de Preview sem mostrar a tela de Output.
Neste evento montamos o corpo do relatório.
Agora vamos montar o rodapé do relatório, clique sobre o evento OnPrintFooter e insira o seguinte código:
with Sender as TBaseReport do
begin
MoveTo(1.0,28.5);
LineTo(20,28.5);
YPos := 29.0;
SetFont('Arial',8);
Bold := False;
PrintRight('Pág. ' + Macro(midCurrentPage) + ' de ' + Macro(midTotalPages),PageWidth - MarginRight);
PrintLeft('Data de Impressão : ' + Macro(midCurrDateShort) + ' - ' + Macro(midCurrTimeShort),MarginLeft);
end;
Você pode notar que utilizamos uma função chamada Macro para montar a Página e a Data de Impressão do relatório, essa função recebe como parâmetro um objeto do tipo TMacroID, segue algumas macros que conseguimos utilizar:
midCurrDateShort
midCurrDateLong
midCurrDateUS
midCurrDateInter
midCurrTimeShort
midCurrTimeLong
midCurrTimeAMPM
midCurrTime24
midFirstPage
midLastPage
midTotalPages
midCurrentPage
É interessante montar um relatório demonstrando todas essas macros, para que você fique familiarizado com o que retorna cada macro acima.
Salve, execute a aplicação e gere o relatório. Se tudo deu certo ele deve ser gerado como a figura abaixo:
Vá até o fim do relatório para verificar o rodapé gerado.
Incrementando o Relatório
Imagem
Agora vamos incrementar um pouco nosso relatório, vamos inserir uma imagem no cabeçalho do relatório.
Volte ao código do evento PrintHeader e altere conforme código abaixo:
var
Bitmap : TBitmap;
begin
with Sender as TBaseReport do
begin
BitMap := TBitmap.Create;
try
Bitmap.LoadFromFile('logo_codegear.bmp');
PrintBitmapRect(1.0,1.0,2.0,2.0, Bitmap);
finally
FreeAndNil(Bitmap);
end;
SetFont('Arial',12);
Bold := True;
...
end
Basicamente o que foi feito??? Foi declarado uma variável do tipo TBitMap, instanciada a variável, carregamos a imagem na mesma, após isso o método PrintBitmapRect foi utilizado passando, o x e y de localização e o x e y de tamanho, poderíamos também utilizar o método PrintBitmap onde ao invés de passar o x e y de tamanho, passaríamos o x e y de escala da imagem.
Execute novamente o relatório, e se continuar correndo tudo bem você poderá visualizar a imagem no cabeçalho.
Memo
Agora vamos utilizar o Memo dentro do nosso relatório, imagine que o cliente solicitou uma alteração nesse relatório, inserir uma coluna pra mostrar o histórico cadastrado no sistema. Muito bem, após a emissão da proposta e aprovação do cliente, vamos ao trabalho!!!
Altere o tamanho dos tabs declarados no evento beforeprint do rvsystem, conforme código abaixo:
SetTab(1.0,pjLeft,4.0,0,BOXLINENONE,0);
SetTab(NA ,pjLeft,4.0,0,BOXLINENONE,0);
SetTab(NA ,pjLeft,3.0,0,BOXLINENONE,0);
SetTab(NA ,pjLeft,2.0,0,BOXLINENONE,0);
Altere o evento OnPrint do rvSystem conforme o código abaixo:
var
Memo : TMemoBuf;
begin
with Sender as TBaseReport do
begin
SetFont('Arial',9);
Bold := False;
qryClientes.First;
qryClientes.DisableControls;
try
Memo := TMemoBuf.Create;
Memo.BaseReport := (Sender as TBaseReport);
while not qryClientes.Eof do
begin
RestoreTabs(1);
PrintTab(qryClientesOCCUPATION.AsString);
PrintTab(qryClientesADDRESS_1.AsString);
PrintTab(qryClientesCITY.AsString);
PrintTab(qryClientesSTATE.AsString);
Memo.Insert(0, 'Teste de Utilizacao do Memo, nos relatorios construidos utilizando Rave Code Based');
Memo.Justify := pjBlock; //pjCenter pjLeft pjRight pjBlock
Memo.PrintStart := 13;
Memo.PrintEnd := 20;
Memo.PrintLines(0, True);
qryClientes.Next;
NewLine;
end;
finally
qryClientes.EnableConstraints;
FreeAndNil(Memo);
end;
end;
Entendendo o que foi feito: Foi declarado uma variável do tipo TMemoBuf (não esqueça de declarar a biblioteca RPmemo no uses), instanciado a variável e informado qual o BaseReport do memo, ou seja, onde o memo irá inserir o texto, feito isso faça um insert no memo com o texto que será demonstrado no relatório, passando como parâmetro a posição (índice) do buffer, se preferir informe qual será a justificação da fonte.
Configure a coluna inicial (PrintStart) e a final (PrintEnd).
Pronto, agora é só executar o PrintLine, passando o valor Zero e True para que sejam impressas todas as linhas do Memo.
LinesLeft
Para finalizar apresentamos o método LinesLeft, esse método é muito importante, pois ele retorna o número de linhas que faltam para serem impressas até o final da folha, visualize o código abaixo:
...
while not qryClientes.Eof do
begin
if LinesLeft < 4 then
NewPage;
RestoreTabs(1);
...
Sempre antes de escrever um novo registro no relatório é interessante verificar o Linesleft, se você não executar esse método para verificar quantas linhas faltam para acabar a página, nunca saberá o momento de chamar uma nova página. Imagine um relatório de demonstrativo financeiro, com certeza não ficará só na primeira página.
Conclusão
Finalizamos aqui o relatório no Rave Code Based, é importante lembrar que o que foi mostrado é o básico do resultado que se pode ter utilizando esta ferramenta, utilizando o Rave Code Based a manutenção do relatório fica muito simples.