Uma coisa muito comum  nos sistemas, são os relatórios com gráficos estatísticos, os famosos  Charts.
Antigamente eu usava o  QuickReport e o ReportBuilder, porém relatórios com gráficos só precisei fazer  no QuickReport e não tive muitas dificuldade, pois ele já tem um componente que  facilita a vida.
Mas, como agora larguei o  QuickReport e estou usando somente o Rave, houve então a necessidade de saber  como fazer relatórios nele com gráficos. 
Comecei então a fuçar no Rave e  percebi que não existia nenhum componente que facilitasse a vida. Então fiz  algumas pesquisas na internet para saber se não existiam componentes de  terceiros, mas infelizmente não achei nenhum, porém nessas pesquisas, achei duas  soluções para o caso :
1 – Salvar o conteúdo de um  TCustomChart em um BMP e imprimir esse BMP no Rave
2 – Usar o método WriteChartData disponível na unit RPTChart
2 – Usar o método WriteChartData disponível na unit RPTChart
Esta última solução é a indicada  pela Nevrona.
Fiz o teste com as duas soluções  e as duas foram satisfatórias, porém gostei mais da última solução, pois como  disse, é indicada pela própria Nevrona e não aparenta ser uma "gambiarra" :-)  como a primeira solução.
Depois desta pesquisa, resolvi  escrever este artigo para demonstrar como não é um bicho de sete cabeças fazer  isso funcionar.
Então vamos lá...
Antes de iniciarmos, gostaria de  explicar como a "coisa funciona", para depois partirmos para prática.
O método WriteChartData,  "escreve" o conteúdo  de um TCustomChart dentro de um campo do tipo Graphic. Então, a princípio, nosso  gráfico será montado no TChart ou TDBChart do Delphi, e depois disso, iremos  utilizar o WriteChartData  para fazer com que o  conteúdo do gráfico seja impresso, desenhado dentro do nosso  relatório.
Agora vamos colocar em prática  esta teoria...
Irei utilizar um RVCustomConnection, pois não preciso estar conectado a um  DataSet para gerar o gráfico no Rave, só preciso de alguém que me disponibilize  um campo para poder usá-lo na impressão, então o RVCustomConnection é o ideal para isso. Para quem  não sabe para que serve o RVCustomConnection, vale a pena começar a mexer nele,  pois é muito interessante.
Agora é serio, chega de teoria e  vamos para prática...:-)
1 - Insira os seguintes  componentes no Form:
TRVProject
TRVCustomConnection
TRVSystem
TChart
TRVProject
TRVCustomConnection
TRVSystem
TChart
2 – Na clausula uses,  insira a unit  RPTChart. É esta unit que nos  disponibilizará o método WriteChartData
3 - Ajuste a propriedade  Engine do RaveProject, apontando para o RVSystem.
4 - Ajuste o Chart, de forma que  represente algum gráfico, só para podermos visualizar o resultado  final.
5 – Agora iremos ajustar dois  eventos do componente RVCustomConnection:
OnGetCols:
Este evento é chamado quando o Rave necessita extrair os meta-data dos campos. É aqui que criaremos nosso campo do tipo graphic. Para isso, coloque o seguinte código neste evento:
Este evento é chamado quando o Rave necessita extrair os meta-data dos campos. É aqui que criaremos nosso campo do tipo graphic. Para isso, coloque o seguinte código neste evento:
with  Connection do
begin
WriteField('CampoChart', dtGraphic, 0, '', '');
end;
begin
WriteField('CampoChart', dtGraphic, 0, '', '');
end;
OnGetRow:
Este evento é chamado quando o Rave necessita extrair os valores dos campos do registro atual. É aqui que iremos alimentar o valor do campo que criamos acima. Para isso, coloque o seguinte código neste evento:
Este evento é chamado quando o Rave necessita extrair os valores dos campos do registro atual. É aqui que iremos alimentar o valor do campo que criamos acima. Para isso, coloque o seguinte código neste evento:
WriteChartData(Connection,  Chart1);
Chart1  é o nome do TChart  que inserimos no Form.
A parte de codificação já está  pronta, agora vamos para parte visual.
6 – Entre no RaveDesigner
7 – Crie uma Region  e dentro desta  Region crie uma banda simples.
8 – Dentro da Band1(que acabou de ser criada),  insira o componente MetaFile, que está na palheta Standard do  Rave.
9 – Crie uma DataView, da mesma forma que se fosse  criar uma outra qualquer, a diferença é que os dados agora virão de um  RVCustomConnection.
10 - Após ter criado, perceba que  na TreeView o DataView1  está disponível,  porém se clicar no sinal de mais do DataView1 para exibir os campos, perceberá  que o campo que criamos via código(CampoChart) não está disponível, só tem um  campo, que é o que vem de brinde, mas não use-o. Para que o nosso campo possa  ser criado, o evento OnGetCols terá que ser chamado, e como fazer isso em tempo  de projeto ?
O segredo é : O RaveDesigner  tem que estar aberto juntamente com a aplicação e depois  chamar o Refresh do DataView.
Então vamos lá...
11 - Execute a aplicação e volte  para o RaveDesigner, mas não  feche a aplicação  ainda.
12 – Selecione o DataView1 lá na TreeView e clique com o  botão direito do mouse sobre o DataView1.  Aparecerá um item  chamado Refresh, basta clicar nele e...bingo  :-). Pronto, o campo que criamos via código irá aparecer na lista. Quando clicar  pela primeira vez no Refresh, vai aparecer uma mensagem, é uma alerta de que um  campo será excluído, isso ocorre pois quando criamos a DataView, já veio aquele campo de brinde,  mas como não criamos ele no OnGetCols, então a mensagem alertará de que o mesmo  será excluído.
13 – Agora selecione o componente  MetaFile que foi inserindo em  Band1  e altere duas  propriedades dele:
DataField : CampoChart  (nome do campo que  criamos)
DataView : DataView1 (nome da dataview criada)
DataView : DataView1 (nome da dataview criada)
Pronto...Pode executar a  aplicação e fazer o teste.
Caso queira fazer o teste no  próprio preview do RaveDesigner, basta deixar a aplicação aberta, caso  contrário, se a aplicação não estiver aberta e você chamar o  preview do RaveDesigner, receberá de presente um errinho básico, o famoso "Acess  violation..." :-)
Lembre-se, o exemplo que fizemos  foi com um TChart, o mesmo poderá ser feito com um TDBChart.
Outro detalhe, utilizamos um  RVCustomConnection, mas poderíamos utilizar um  RVDataSetConnection sem problemas, porém neste caso,  só fique atento com o seguinte:
No evento OnGetCols, antes de criar o campo, chame o  método DoGetCols  do Connection que vem como parâmetro neste  evento. Isso deve ser feito para que primeiro sejam criadas as colunas do  DataSet que está associado e depois sim poder criar as suas colunas. 
E no evento OnGetRow, antes de chamar o WriteChartData, chame o método DoGetRow do Connection que vem como parâmetro neste  evento. Isso deve ser feito para que primeiro seja alimentando os campos do  DataSet que está associado e depois sim poder alimentar seus campos criados  manualmente.
Espero que um dia possa surgir um  componente para utilizarmos no Rave, pois assim ficará muito mais fácil, mas  enquanto isso não acontece, temos esta solução.
Nenhum comentário:
Postar um comentário