Hoje vou mostrar como imprimir um gráfico em um relatório FWMSPrinter via Job / Scheduler.
Há um bom tempo atrás, eu mostrei como criar gráficos em AdvPL (link aqui – https://terminaldeinformacao.com/2016/09/06/criando-graficos-advpl-fwchartbar/ ). Inclusive nesse link eu já mostro como gerar um relatório em FWMSPrinter com o gráfico dentro de uma página.
Mas como fazer isso de maneira automática? O grande problema, é que como utiliza recursos gráficos, não podemos utilizar via Scheduler do Protheus, então temos que fazer uma pequena “gambiarra”.
Primeiramente temos que criar uma user function que conterá o agendamento. Ai nessa user function, iremos chamar a execução de uma segunda user function que gera o relatório, porém iremos fazer a chamada pelo sistema operacional. Abaixo um exemplo:
//Primeiro iremos montar os parametros que serão enviados para a segunda user function cArqGrafico := "grafico_"+dToS(Date())+".pdf" xParams := "D:\TOTVS\PRODUCAO\Protheus_Data\x_relatorios;"+cArqGrafico+";"+dToS(Date()) //Agora iremos montar onde será executado nosso smartclient no servidor, e qual comando que ele irá executar lWait := .T. cDirSmart := "D:\TOTVS\PRODUCAO\Protheus\bin\smartclient\" cCommand := "SmartClient.exe -q -p=u_zGrafRel a="+xParams+" -c=job -e=PRODUCAO_JOB -m -l" //Agora iremos chamar a função WaitRunSrv, passando o diretório do smarclient, e o comando acima WaitRunSrv(cDirSmart + cCommand , lWait , "C:\" )
Feito isso, agora nosso agendamento está chamando a função u_zGrafRel. Agora nessa função, o que iremos fazer, ao receber o parâmetro enviado, via a=, iremos criar primeiramente uma janela com o gráfico, que irá fechar automaticamente ao abrir, e gerar o png do gráfico.
Após isso, com o png gerado, iremos conseguir colocar em um FWMSPrinter, gerando com o nome do pdf passado, e assim poderemos usar o gráfico tranquilamente.
Abaixo o exemplo citado:
User Function zGrafRel(xParams) //... Criação de variáveis e validações para preparar o ambiente //Aqui iremos dar um valor default para os parametros vindos Default xParams := "C:\Spool\;grafico.pdf;"+dToS(DaySub(dData, 1)) //Iremos quebrar os parâmetros vindos através do ponto e vírgula aParams := StrTokArr(xParams, ';') cDiretorio := aParams[01] cArquivo := aParams[02] dDataRef := sToD(aParams[03]) //... Aqui você pode montar os dados para os gráficos, no caso no exemplo abaixo iremos usar variáveis com nome aSaldos01 e aSaldos02 //Cria a Janela nAltur := 700 nLargur := 1200 DEFINE MSDIALOG oDlgChar PIXEL FROM 0,0 TO nAltur,nLargur //Cria o grafico oChart := FWChartBarComp():New() oChart:Init(oDlgChar, .T.) //Adiciona as series no grafico oChart:addSerie("Empresa 01", aSaldos01) oChart:addSerie("Empresa 02", aSaldos02) oChart:setLegend( CONTROL_ALIGN_BOTTOM ) //Define o titulo oChart:SetTitle("Posição do Estoque - "+MesExtenso(Month(dDataRef))+"/"+cValToChar(Year(dDataRef)), CONTROL_ALIGN_CENTER) //Definindo as mascaras oChart:setMask(" *@* ") oChart:setPicture(cPict) //Define as cores que serao utilizadas no grafico (azul e laranja) aAdd(aRand, {"084,120,164", "007,013,017"}) aAdd(aRand, {"207,136,077", "020,020,006"}) oChart:oFWChartColor:aRandom := aRand oChart:oFWChartColor:SetColor("Random") //Constroi o grafico oChart:Build() oChart:nLabelWidth := 0 //Ao iniciar o dialog, ele irá salvar um png do gráfico e depois irá encerrar a janela ACTIVATE MSDIALOG oDlgChar CENTERED ON INIT (oChart:SaveToPng(0, 0, nLargur, nAltur, cDiretorio+"grafico.png"), oDlgChar:End()) //Criando o objeto de impressao oPrintPvt := FWMSPrinter():New(cArquivo, IMP_PDF, .F., '', .T., .F., , ,.T., .T., ,.F.) oPrintPvt:cPathPDF := cDiretorio oPrintPvt:SetResolution(72) oPrintPvt:SetLandscape() oPrintPvt:SetPaperSize(DMPAPER_A4) oPrintPvt:SetMargin(60, 60, 60, 60) oPrintPvt:StartPage() //Imprime o grafico oPrintPvt:SayBitmap(100, 100, cDiretorio+"grafico.png", nLargur/2, nAltur/1.6) //Gera o arquivo pdf oPrintPvt:EndPage() oPrintPvt:Print() Return
Abaixo um exemplo do pdf gerado com o gráfico:
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Sou seu fã mano!!!
Opa, valeu pelo comentário jovem. Bondade sua.
Grande abraço.