====== Relatórios ====== ===== Introdução ===== É possível desenhar relatórios num editor em separado, gravá-los a um arquivo .RDL e depois importar diretamente no KRATOM o seu conteúdo para geração final da aplicação. O KRATOM ao sincronizar o conteúdo do código API também sincroniza os relatórios de origem das respectivas pastas. ===== Editor de relatório ===== {{:genericas:fyireporting.png?900|}} O RdlDesigner.exe (FyiReporting Designer) é um editor especial para os relatórios que serão exportados para o KRATOM, ele vem como parte da distribuição padrão do ProtoBase e serve para criar todos os relatórios da aplicação. ===== Roteiro para criação e instalação de relatório no KRATOM ===== - Abra o editor RdlDesigner e carregue um arquivo de relatório modelo qualquer - Use "Salvar Como" e mude o nome para o novo relatório - Altere o DataSource com a string de conexão e senha (detalhe no próximo tópico) - Remova os DataSets do relatório (Data/Dataset) - Adicione um novo DataSet com a pesquisa do relatório (Data/Dataset/New): Em DataSet e parâmetros da Query use "@". Em Query Parameters adicione os nomes de parâmetros inseridos na Query com Value apontando para uma variável de filtro vindo da aplicação (Ex. ={?CODEMPRESA) Vide Imagem abaixo. - Clique na area em branco do Body e vá em propriedades, clique Parameters, adicione os parâmetros usados na Query ou outros que necessitar para imprimir no relatório. Estes parâmetros serão recebidos da aplicação KRATOM para uso no gerador de relatório. - Faça as alterações no relatório e teste usando a opção PREVIEW dele. - Depois de tudo ok, remova a string DataSource e coloque no lugar ={?ConnectionString} - Salve o arquivo - No KRATOS adicione um relatório Tupla ao pacote e importe o relatório salvo anteriormente, anote o número da Tupla do relatório - Na Aplicação use a função GerarEAbrirRelatorio para abrir o relatório e passar os parâmetros conforme modelo ao final da página. {{:genericas:queryparam.png?500|}} ===== Adicionando campos de totais ===== Para adicionar campos de totais ou de média ao relatório: - Habilite o rodapé da tabela marcando a opção Footer Rows em Table Properties (componente Table). - Na coluna que se deseja a totalização digite Sum(Fields!CAMPO.Value) * Estão disponíveis funções agregadas como "sum", "avg", "count", "max", "min", "stdev", "stdevp", "var", "varp". Vide manual. ===== Adicionando Filtros no DATASOURCE do relatório ===== * Em DataSet/Filters adicione filtros específicos como : {{:genericas:datasetfiltro.png?500|}} Observação importante: A filtragem será executada localmente (no PC do usuário), ponderar o trade-off entre performance x facilidades. ===== Diversos ===== ==== Configurando a conexão com o banco de dados durante o design do relatório ==== {{:genericas:conexstring.png?500|}} Entre em Data / DataSources e adicione um DataSource de qualquer nome, depois no campo __Connection string__ digite os dados corretos para poder acessar a base de dados. A string correta é a seguinte: * UserID=SYSDBA;Password=xu6Za111; DataBase=G:\KRATOMNG\Apps\Atom\bin\Debug\WorkBase.fdb; Port=4449; DataSource=localhost; Charset=ISO8859_1 * UserID=SYSDBA;Password=1xu6Za11; DataBase=x:\kratomsuit\WorkBase.fdb; Port=4449; DataSource=localhost; Charset=ISO8859_1 Após digitar a string, clique no botão Test Connection para ver se a conexão foi feita corretamente. Observação: Este procedimento deve ser feito toda a vez que se quiser acessar uma base para poder formatar um relatório. Tag: ConnectionString, {?ConnectionString} ==== Configurando a conexão com o banco de dados após relatório finalizado ==== Após o relatório estar finalizado em testes e design deve-se trocar o conteúdo de __Connection string__ para a variável que aponta para a string de conexão da aplicação , a janela de DataSources ficará desta forma: {{:genericas:datasourcefinal.png?500|}} Após fazer isso o relatório estará pronto para ser definitivamente importado pelo KRATOS e usado pela aplicação KRATOM. ==== Manual do Editor ==== https://github.com/psoares33/FyiReporting-Docs/wiki === Dica Editor 1 === Para criar um relatório 1-N: * crie um dataset com sql agrupando os registros 1-N (group by) * Adicione uma tabela visual e adicione na combo de group o campo que vai ser usado para o agrupamento. (pode-se adicionar mais campos usando Edit group da tabela depois) * Para ampliar a capacidade do header/datarow de uma tabela use colspan * Para colocar campos textbox onde quiser na header ou na linha de registro use rectangle e depois solte em cima um textbox. ==== Executando um relatório via c# ==== Para passar parâmetros para um relatório contido na tupla 2622 e executá-lo use o seguinte código. CoreApp.RepParametros p = new CoreApp.RepParametros(); int IdProduto = CoreApp.ParamManager.Instance().GetParamInteiro(2617); if (IdProduto > 0) { p.AdParam("IdProduto", IdProduto); CoreApp.RepManager.Instance().GerarEAbrirRelatorio(2622, p); } else throw new Exception(DefMessages.errNecSelProdGerEstoq); Obs 1. O relatório tem um parâmetro IdProduto requerido do tipo Inteiro que será usado para o Query interno. Obs 2. O Relatório .rdl deve estar importado no KRATOS e já acondicionado na base de execução. ==== Passando um Datatable diretamente ==== Às vezes a complexidade de Querys e variações de relatórios resultantes podem nos obrigar a criar vários relatórios .RDL o que acaba sendo trabalhoso. Uma alternativa é via C# gerar um DataTable e passar para o gerador do relatório, substituindo a Query interna do relatório pela alternativa. Desta forma você só passa parâmetros (caso necessários) para o relatório que não alimentem diretamente as Queries, pois elas estarão sendo supridas de outra forma via Datatable. O resultado é que um único modelo .RDL pode-se emitir um relatório filtrado de infinitas formas, preservando a formatação. Ex.: DataTable dt = bo.GetLctosContaCxMov( CoreApp.Global.gl_IDEMP, IdConta, DataIni, DataFin); CoreApp.RepManager.Instance().GerarEAbrirRelatorio(idTuplaRelatorio, p, dt , "ExtratoContaCaixa" ); <<--- ExtratoContaCaixa é o nome do DATASET dentro do relatório para ser substituido. public DataTable GetLctosContaCxMov(int gl_IDEMP, int idConta, DateTime dataIni, DateTime dataFin) { var dbc = CoreApp.DBdirect.DBdirectCore.Instance().NovaConexao(true); try { CoreApp.DBdirect.SelecaoComplexa sc = new CoreApp.DBdirect.SelecaoComplexa(dbc, 3014); sc.TipoDataFill = TipoDataFill.FillDataTable; sc.SetParamInt("@EMP", CoreApp.Global.gl_IDEMP); sc.SetParamInt("@IDCONTA", idConta); sc.SetParamLogico("@ATIVO", true); sc.SetParamData("@dataini", dataIni); sc.SetParamData("@datafin", dataFin); sc.Exec(); return sc.GetDataTable(); } finally { dbc.Close(); } } ==== Erros Internos (Exceptions) ==== === System.NullReferenceException === Dados adicionais: System.NullReferenceException Message=Referência de objeto não definida para uma instância de um objeto. Source=RdlEngine StackTrace: fyiReporting.RDL.RenderBase.RunPages(Pages pgs) Motivo: Um Parâmetro string passado como null ou em branco pode disparar este erro. Resolução: Setar o ALLOW BLANK na configuração do parâmetro dentro do editor CASO A STRING POSSA SER PASSADA SEM CONTEÚDO.