Gerando Relatório Dinâmicos usando QuickRep

Veja o projeto que ensina como criar um relatório dinamicamente no QuickReport.

Gerando Relatórios Dinâmicos usando QuickRep

 

Neste Artigo o objetivo é criar uma aplicação onde é possível gerar relatórios no QuickRep que o próprio usuário possa escolher os campos desejados e sua ordem de impressão. Vamos utilizar um tabela Funcionarios do tipo Dbase IV com a seguinte estrutura:

 

Figura 1.

Obs: Este exemplo pode ser utilizado com qualquer banco de dados.

Crie uma Aplicação Delphi e adicione um Data Module com o Nome = Dm. No Data Module coloque um componente Query (paleta BDE). Em DataBaseName coloque o alias ou caminho onde se encontra nossa tabela, no meu caso ficará assim: DataBaseName = C:\Artigo.

 

Figura 2.

Pré-configurando o Relatório

Como nosso objetivo é utilizar o QuickRep vamos deixar algumas coisas pré-configuradas, para isso adicione um novo Form ao Projeto com Name = FrmRelatorios. Coloque nesse formulário um QuickRep (paleta QReport), em Bands ative HasColumnHeader, HasDetail e HasPageHeader. No Detail e ColumnHeader mude a propriedade Heigth para 20.

 

Figura 3.

No Page Header vamos colocar um dois QrLabel e dois QrSysData mude suas propriedades conforme mostrado abaixo:

QrLabel1

Caption = Gerador de Relatórios

Top = 2

Left = 4

QrLabel2

 

Top = 21

Left = 4

QrSysData1

 

Top = 2

Alignment = taRightJustify

AlignToBand = True

Data = qrsPageNumber

Text = Pagina:

QrSysData2

 

Top = 2

Alignment = taRightJustify

AlignToBand = True

Data = qrsDate

Text = Data:

 

Ainda no Page Header na propriedade Frame Ative DrawBottom, DrawLeft, DrawTop, DrawRigth. Com isso seu QuickRep deve esta com mostrado abaixo.

 

Figura 4.

Obs: O QRLabel2 será usado para o Titulo do Relatório.

Coloque na sessão USES a unit do Data Module e na propriedade DataSet do QuickRep coloque Dm.Query1.

Criando o Editor de Relatórios

Volte para o formulário principal, mude seu nome para FrmMenu, coloque no formulário um componente PageControl (paleta Win32). Crie duas paginas “Definindo Campos” e “Ordenando”.

 

Figura 5.

Na Pagina “Definindo Campos” coloque os Componentes: dois Listbox, três Label (ambos da paleta Standard), 4 SpeedButton (Paleta Additional). Organize conforme mostrado abaixo:

 

Figura 6.

Na pagina “Ordenando” coloque um Label (paleta Standard), um CheckListbox e dois SpeedButton (ambos da paleta Additional). Organize conforme abaixo:

 

Figura 7.

Para facilitar nosso trabalho vamos mudar os nomes dos SpeedButton:

SpeedButton1 = IncluirCampo

SpeedButton2 = RemoverCampo

SpeedButton3 = CampoUp

SpeedButton4 = CampoDown

SpeedButton5 = OrdemUp

SpeedButton6 = OrdemDown

No formulário logo abaixo ao PageControl coloque um Label, um Edit e um BitBtn e Organize conforme abaixo:

 

Figura 8.

Mude o nome do BitBtn1 para Gerar. Agora vamos declarar na sessão Public as variáveis abaixo:

 

public

  { Public declarations }

  Pagina:Integer;

  QrLabel:array[1..8] of TQrLabel;

  QrDbText:array[1..8] of TQrDbtext;

  Desc,Campo:array[1..8] of String;

  Largura:Array[1..8] of Integer;

end;

 

Observe que estamos criamos dois array de 8 posições (Nº Maximo de Campos da Tabela) do tipo TQrLabel e TQrDbText. Os QrLabel são os componentes que mostraram as descrições das colunas nos relatórios e os QrDbText são os componentes que mostraram as informações de cada coluna. Assim temos que incluir a QRCtrls na sessão USES.

O Array DESC terá os títulos de cada coluna, o CAMPO o nome dos campos que se deseja usar da tabela e LARGURA aguardará a largura de cada coluna. A variável PAGINA terá a quantidade de caracteres utilizados na pagina, com isso podemos definir se o relatório será impresso em PAISAGEM ou RETRATO.

Vamos até o evento OnCreate do formulário para definirmos os valores dos array e os itens de seleção (ListBox e CheckListBox). Digite o código abaixo:

 

procedure TFrmMenu.FormCreate(Sender: TObject);

var

 i:integer;

begin

 // Matriz com Nome de Campo da Tabela

 Campo[1] := 'CODIGO';

 Campo[2] := 'NOME';

 Campo[3] := 'ENDERECO';

 Campo[4] := 'BAIRRO';

 Campo[5] := 'CIDADE';

 Campo[6] := 'UF';

 Campo[7] := 'SALARIO';

 Campo[8] := 'CARGO';

 // Matriz Com Descrição das Colunas do Relatório

 Desc[1] := 'Nº Código';

 Desc[2] := 'Nome';

 Desc[3] := 'Endereço';

 Desc[4] := 'Bairro';

 Desc[5] := 'Cidade';

 Desc[6] := 'UF';

 Desc[7] := 'Salário';

 Desc[8] := 'Cargo';

 // Matriz Com a Largura das Colunas

 Largura[1] := 9;

 Largura[2] := 40;

 Largura[3] := 40;

 Largura[4] := 20;

 Largura[5] := 20;

 Largura[6] := 2;

 Largura[7] := 10;

 Largura[8] := 15;

 // Colocamos as Descrições dos Campos para Seleção no Listbox e CheckListbox

 for i := 1 to 8 do

   begin

CheckListBox1.Items.Add(Desc[i]);

ListBox1.Items.Add(Desc[i]);

   end;

 

end;

 

Obs: O Array Largura deve conter o tamanho que se deseja para cada coluna do relatório, podendo ser o mesmo tamanho os campos na tabela ou tamanhos pré-definidos.

Agora vamos criar a função PosCampo que retornará a posição dentro dos arrays dos campos selecionados.

 

function TFrmMenu.PosCampo(Campo:String):Integer;

var

 i:integer;

begin

 for i := 1 to 8 do

   begin

   if Campo = Desc[i] then

begin

Result := i;

Break;

end;

   end;

end;

 

Obs: não esquece de declara a função na sessão public ou private.

Agora vamos colocar o código para a escolha dos campos nos relatórios. Vá até o evento OnClick do botão IncluirCampo e digite o código abaixo:

 

// Verificamos se existem itens

if Listbox1.ItemIndex >= 0 then

  begin

   // Verificamos se o nº de caracteres do campo não ultrapassa o total da pagina

   if Pagina + Largura[PosCampo(Listbox1.Items.Strings[ListBox1.ItemIndex])] > 125 then

ShowMessage('Campo Supera o Tamanho da Pagina')

else

begin

// Adiciona o Campo escolhido na lista de seleção

Pagina :=  Pagina + Largura[PosCampo(Listbox1.Items.Strings[ListBox1.ItemIndex])];

ListBox2.Items.Add(ListBox1.Items.Strings[ListBox1.ItemIndex]);

ListBox1.Items.Delete(ListBox1.ItemIndex);

end;

  end;

Obs: Estamos definindo 125 como o total de caracteres para o tamanho do papel em paisagem e 94 em retrato.

Digite agora o código do botão RemoverCampo.

 

if Listbox2.ItemIndex >= 0 then

  begin

Pagina :=  Pagina - Largura[PosCampo(Listbox2.Items.Strings[ListBox2.ItemIndex])];

ListBox1.Items.Add(ListBox2.Items.Strings[ListBox2.ItemIndex]);

ListBox2.Items.Delete(ListBox2.ItemIndex);

  end;

 

Digitando os código dos botões de Organização.

Botão CampoUp.

 

var

 i: integer;

begin

 if Listbox2.ItemIndex > 0 then

  begin

i := ListBox2.ItemIndex;

ListBox2.Items.Move(i,i-1);

ListBox2.ItemIndex := i-1;

  end;

end;

 

Botão CampoDown.

var

 i:integer;

begin

 if Listbox2.ItemIndex < ListBox2.Items.Count - 1  then

  begin

i := ListBox2.ItemIndex;

ListBox2.Items.Move(i,i+1);

ListBox2.ItemIndex := i+1;

  end;

end;

 

Botão OrdemUp.

var

 i:integer;

begin

 if CheckListbox1.ItemIndex > 0 then

  begin

i := CheckListBox1.ItemIndex;

CheckListBox1.Items.Move(i,i-1);

CheckListBox1.ItemIndex := i-1;

  end;

end;

 

Botão OrdemDown.

var

 i:integer;

begin

 if CheckListbox1.ItemIndex < CheckListBox1.Items.Count - 1  then

  begin

i := CheckListBox1.ItemIndex;

CheckListBox1.Items.Move(i,i+1);

CheckListBox1.ItemIndex := i+1;

  end;

end;

 

Agora é a parte mais importante para a nossa aplicação o código do botão Gerar.

procedure TFrmMenu.BtnGerarClick(Sender: TObject);

var

 i, Col, Tamc:integer;

 NCampo,Ordem:String;

begin

 

//Verificamos se existem Campos Selecionados

 if Listbox2.Items.Count > 0 then

 begin

 

// Posição inicial da coluna

 Col := 5;

 

 // Informamos o Titulo do Relatório

 Form2.QRLabel2.Caption := Edit1.Text;

 

 for i := 0 to listbox2.Items.Count -1 do

   begin

 

//Obtendo o Tamanho e Nome do Campo

Tamc   := Largura[PosCampo(ListBox2.Items.Strings[i])] ;

NCampo := Campo[PosCampo(ListBox2.Items.Strings[i])];

 

//Criando Componentes Para os Títulos das Colunas

QrLabel[i+1] := TQrLabel.Create(Form2.QuickRep1.Bands.ColumnHeaderBand);

QrLabel[i+1].Parent:= Form2.QuickRep1.Bands.ColumnHeaderBand;

QrLabel[i+1].Left:= Col;

QrLabel[i+1].Top:= 4;

QrLabel[i+1].Caption:= ListBox2.Items.Strings[i];

QrLabel[i+1].Font.Style := [fsunderline,fsbold];

 

//Criando Componentes de Exibição de Dados das Colunas

QrDbtext[i+1] := TQrDbtext.Create(FrmRelatorios.QuickRep1.Bands.DetailBand);

QrDbText[i+1].Parent:=  Form2.QuickRep1.Bands.DetailBand;

QrDbText[i+1].Left:= Col;

QrDbText[i+1].Top:= 8;

QrDbText[i+1].DataSet   := Dm.Query1;

QrDbText[i+1].DataField := NCampo;

 

 //Obtendo o Valor da próxima Coluna. Como o valor precisa ser em pixel multiplicamos por

//  5 o tamanho do Campo.

Col := Col + (5 * Tamc);

 

// Alinhamos a direita o Campo Salario

if NCampo = 'SALARIO' then

begin

QrDbText[i+1].AutoSize  := False;

QrDbText[i+1].Alignment := taRightJustify;

end;

   end;

 

 // Criando Ordenação

 Ordem := '';

 for i := 0 to CheckListBox1.Items.Count - 1 do

   begin

if CheckListBox1.Checked[i] = True then

begin

if Ordem = '' then

Ordem := Ordem +' Order by ' + Campo[PosCampo(CheckListBox1.Items.Strings[i])]

else

Ordem := Ordem +' , ' + Campo[PosCampo(CheckListBox1.Items.Strings[i])];

end;

   end;

 

//Passamos as instruções SQL

 Dm.Query1.Close;

 Dm.Query1.SQL.Clear;

 Dm.Query1.SQL.Add('select * from funcionarios.dbf');

 if Ordem <> '' then

Dm.Query1.SQL.Add(Ordem);

 

 Dm.Query1.Open;

 

 //Chamamos o Relatório

 FrmRelatorios.QuickRep1.Preview;

 

 //Liberamos os Componentes utilizados

 for i := 0 to listbox2.Items.Count -1 do

begin

QrLabel[i+1].free;

QrDbText[i+1].free;

end;

 end;

end;

 

Agora precisamos definir se o relatório será impresso em paisagem ou retrato. Para isso vamos até o formulário FrmRelatorios e no evento OnBeforePrint do QuickRep digite o código abaixo:

 

if FrmMenu.Pagina <= 94 then

  QuickRep1.Page.Orientation := poPortrait

else

  QuickRep1.Page.Orientation := poLandscape;

 

Inclua a PRINTERS na sessão USES. Pronto agora é só fazer alguns testes.

Selecionado Campos

Figura 9.

Ordenando Por Salário

Figura 10.

Visualizando Relatório

Figura 11.

Conclusão

Mostrei aqui uma forma de como desenvolver um gerador de relatórios onde o próprio usuário pode escolher os dados desejados acredito que seja muito útil em diversas aplicações. Abraços T+

 

Walbert Castro (walbertsc@hotmail.com) Coordenador de Informática Revenda Ambev do Amapá.

 

 

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados