Artigo Clube Delphi Edição 12 - Relatório com Múltiplas Quebras

Artigo da Revista Clube Delphi Edição 12.

Esse artigo faz parte da revista Clube Delphi edição 12. Clique aqui para ler todos os artigos desta edição



Atenção: por essa edição ser muito antiga não há arquivo PDF para download. Os artigos dessa edição estão disponíveis somente através do formato HTML.

Relatório com Múltiplas Quebras

 

Na minha opinião, o QuickReport é uma ferramenta excelente para a criação de relatórios com o Delphi. Considero-o bastante poderoso devido a sua flexibilidade na manipulação de eventos e componentes. Porém, muitos usuários, por desconhecerem o funcionamento da ferramenta, se contentam com relatórios sem muita complexidade ou se rendem as famosas "marretas" para forçar um determinado resultado.  Este tipo de técnica (?), na maioria dos casos, pode ser evitada simplesmente alterando algumas propriedades.

Para exemplificar isso, vamos criar um relatório que, apesar de pequeno, possui uma estrutura que servirá perfeitamente como referência para vários outros relatórios maiores e mais complexos. Nosso relatório abrange conceitos como agrupamentos, múltiplos níveis, subtotais, totais, e possui a seguinte hierarquia:

 

figura1

 

 

Antes de iniciar a construção do relatório, crie as tabelas necessárias para este exemplo, conforme a listagem abaixo:

 

EMPRESA.DB

CodEmpresa   +*

NomeA50

 

FUNCIONARIO.DB

CodFuncionario+*

CodEmpresa   I

NomeA50

Salário$

 

FILHO.DB

CodFilho+*

CodFuncionario   I

NomeA

 

As tabelas se relacionam da seguinte forma:

 

[gráfico]

 

 

Crie um alias para o diretório no qual as tabelas foram salvas, nomeando-o qrExemplo. Vamos agora iniciar a construção do relatório:

 

Em um novo formulário do QR insira dois objetos  TQuery (palheta data access), quatro objetos TQRBand (palheta QReport), um objeto TQRGroup (palheta QReport) e um objeto TQRSubDetail. Configure suas propriedades conforme a listagem a seguir:

 

Query1

DatabaseNameQRExemplo

SQLselect

empresa.codempresa, empresa.nome as nomeempresa,

funcionario.codfuncionario, funcionario.nome as nomefuncionario,

funcionario.salario

from empresa, funcionario

where funcionario.codempresa = empresa.codempresa

order by nomeempresa, nomefuncionario

 

Query2

DatabaseNameQRExemplo

SQLselect nome

from filho

where codfuncionario = :MCodFunc

order by nome

 

Nota: É importante definir o tipo do parâmetro (MCodFunc) declarado na query acima, que será Integer (ftInteger). Para isto, clique na propriedade Params, selecione o item McodFunc e altere a propriedade

DataType.

 

QuickReport

DataSet  Query1

ReportTitleRelação de Empresa/Funcionário/Dependente

 

QRBand1

BandTyperbPageHeader

Height32

Frame.DrawTopTRUE

Frame.DrawLeftTRUE

Frame.DrawRightTRUE

Frame.DrawBottom   TRUE

 

QRBand2

BandTyperbDetail

HasChildTrue

Height17

Frame.DrawTopTRUE

Frame.DrawLeftTRUE

Frame.DrawRightTRUE

Frame.DrawBottom   FALSE

 

ChildBand1

Frame.DrawTopFALSE

Frame.DrawLeftTRUE

Frame.DrawRightTRUE

Frame.DrawBottom   FALSE

 

 

QRBand3

BandTyperbGroupFooter

Color$00DFDFDF

HasChildTrue

Height17

Frame.DrawTopTRUE

Frame.DrawLeftTRUE

Frame.DrawRightTRUE

Frame.DrawBottom   TRUE

 

ChildBand2

Frame.DrawTopTRUE

Frame.DrawLeftTRUE

Frame.DrawRightTRUE

Frame.DrawBottom   TRUE

 

 

QRBand4

BandTyperbSummary

Height32

Frame.DrawTopTRUE

Frame.DrawLeftTRUE

Frame.DrawRightTRUE

Frame.DrawBottom   FALSE

 

QRGroup1

Color$00DFDFDF

ExpressionQuery1.CodEmpresa

FooterBandQRBand3

Height22

Frame.DrawTopTRUE

Frame.DrawLeftTRUE

Frame.DrawRightTRUE

Frame.DrawBottom   TRUE

 

 

Nota: O QRGroup é a band responsável pela quebra do relatório. Portanto, o valor definido na propriedade Expression é considerado a chave dos agrupamentos.

 

QRSubDetail1

DataSetQuery2

Height14

Frame.DrawTopFALSE

Frame.DrawLeftTRUE

Frame.DrawRightTRUE

Frame.DrawBottom   FALSE

 

 

Ao final desta etapa nosso relatório ficará basicamente com o seguinte visual (em tempo de edição):

 

figura2

 

Em seguida, vamos inserir os objetos (todos da palheta QReport) para a exibição dos títulos das colunas e dos valores gravados no banco, conforme a listagem abaixo:

 

QrBand1-1 TqrSysData

QrGroup1-1 TqrDbText

QrBand2-2 TqrLabel e 2 TqrDbText

ChildBand1-1 TqrLabel

QrSubDetail1  -1 TqrLabel

QrBand3-1 TqrLabel e 1 TqrExpr

ChildBand2-não tem objeto

QrBand4-1 TqrLabel e 1 TQrExpr

 

 

QRSysData1 (QRBand1)

AlignmenttaCenter

AlignToBand   True

DataqrsReportTitle

font.StyleBold

Font.Size12

 

QRDBText1 (QRGroup1)

AlignmenttaCenter

AlignToBand   True

Color$00DFDFDF

DataFieldnomeempresa

DataSetQuery1

 

QRLabel1 (QRBand2)

CaptionFuncionario:

Left16

 

QRDBText2 (QRBand2)

DataFieldnomefuncionario

DataSetQuery1

Left96

 

QRLabel2 (QRBand2)

CaptionSalario:

Left264

 

QRDBText3 (QRBand2)

DataFieldsalario

DataSetQuery1

Left 320

 

QRLabel3 (ChildBand1)

CaptionFilho(s):

Left40

Font.StyleBold

 

QRLabel4 (QRSubDetail1)

Captionnome do filho

Left56

 

QRLabel5 (QRBand3)

CaptionSubTotal de Salários:

Left424

Font.StyleBold

 

QRExpr1 (QRBand3)

Expressionsum(Query1.Salario)

ResetAfterPrintTRUE

Left576

Font.StyleBold

 

QRLabel7 (QRBand4)

CaptionTotal Geral de Salários:

Left424

Font.StyleBold

 

QRExpr2 (QRBand4)

Expressionsum(Query1.Salario)

Left576

Font.StyleBold

 

Agora nosso relatório já está com uma boa forma:

 

figura3

 

Abaixo o código do relatório:

 

 

unit ReEmpFun;

 

interface

 

uses Windows, SysUtils, Messages, Classes, Graphics, Controls,

  StdCtrls, ExtCtrls, Forms, Quickrpt, QRCtrls, Db, DBTables;

 

type

  TqrEmpFun = class(TQuickRep)

Query1: TQuery;

QRBand1: TQRBand;

QRGroup1: TQRGroup;

QRDBText1: TQRDBText;

QRBand2: TQRBand;

QRDBText2: TQRDBText;

QRSubDetail1: TQRSubDetail;

QRLabel4: TQRLabel;

ChildBand1: TQRChildBand;

QRLabel3: TQRLabel;

Query2: TQuery;

QRBand3: TQRBand;

QRExpr1: TQRExpr;

QRDBText3: TQRDBText;

QRLabel1: TQRLabel;

QRLabel2: TQRLabel;

QRLabel5: TQRLabel;

QRShape1: TQRShape;

ChildBand2: TQRChildBand;

QRBand4: TQRBand;

QRLabel7: TQRLabel;

QRExpr2: TQRExpr;

QRSysData1: TQRSysData;

procedure QRBand2BeforePrint(Sender: TQRCustomBand;

var PrintBand: Boolean);

procedure QRSubDetail1BeforePrint(Sender: TQRCustomBand;

var PrintBand: Boolean);

  private

 

  public

 

  end;

 

var

  qrEmpFun: TqrEmpFun;

 

implementation

 

{$R *.DFM}

 

procedure TqrEmpFun.QRBand2BeforePrint(Sender: TQRCustomBand;

  var PrintBand: Boolean);

begin

  //atribui valor ao parâmetro da query filho para filtar o(s) filho(s) do funcionário corrente

  with Query2 do

  begin

Close;

ParamByName('MCodFunc').Value := Query1.FieldByName('codfuncionario').AsInteger;

Open;

  end;

end;

 

procedure TqrEmpFun.QRSubDetail1BeforePrint(Sender: TQRCustomBand;

  var PrintBand: Boolean);

begin

  //testa se query de filho esta vazia para o funcionário corrente

  if Query2.IsEmpty then

QRLabel4.Caption := 'Não Possui Filho(s)'

  else

QRLabel4.Caption := Query2.FieldByName('nome').AsString;

end;

 

end.

 

 

 

Conforme comentado, esta é uma estrutura que dá uma base para criar relatórios mais completos/complexos no Delphi. Não existe um segredo para a criação de relatórios que possuam agrupamentos, múltiplos níveis, subtotais, totais, etc. E nem muito menos a necessidade de escrever várias linhas de código para obter tal resultado, o importante é explorar ao máximo as propriedades dos componentes do QR.

Após esses passos, nosso relatório está basicamente pronto. Ao executá-lo, teremos como resultado todos os funcionários agrupados por empresa que por sua vez terão todos os seus dependentes listados (se houverem). O total de salários pagos por empresa e o total geral de salários pagos também serão exibidos. Desta forma, teremos o relatório abaixo:

 

figura4

 

Como você pode observar, foram criados dois grupos separados (Business Tech e Wam Corporation), na mesma página. Caso você queira colocar um grupo em cada página, basta mudar a propriedade ForceNewPage do QRGroup1 para True. Através deste artigo, meu objetivo foi mostrar como é fácil construir relatórios no QuickReport, sem a necessidade de páginas de digitação de código. Este exemplo pode ser baixado no endereço http://www.clubedelphi.com.br/edicao12/qr.zip

Artigos relacionados