Páginas

Mostrando postagens com marcador Relatórios. Mostrar todas as postagens
Mostrando postagens com marcador Relatórios. Mostrar todas as postagens

Criando sub-reports através do Reporting Services

Esses dias precisei criar um sub-report para um determinado relatório que estava desenvolvendo, como já havia passado por um projeto onde vi alguns relatórios feitos dessa maneira fui atrás para saber como funciona e como fazer, não achei nenhuma referência na web além do MSDN Library e por isso estou escrevendo esse novo post.

Os sub-reports são relatórios que o usuário abre clicando em um item relacionado no relatório principal abrindo um detalhamento do registro.

Para exemplificar vou criar algo bem prático e simples que é o relatório baseado em  Diários.

Criei uma query simples apenas com a LedgerJournalTable, ordenado pelo JournalNum e uma query com a LedgerJournalTrans ordenado pelo AccountNum:



Em seguida no Visual Studio criei um novo projeto em C# com o template Dynamics AX Reporting Project, renomeei o projeto para AeDX_SubReport. 

Utilizei um layout padrão que existe no AX, para isso precisamos fazer o seguinte: 
  1. No menu File > Add > Existing Project from Dynamics AX. 
  2. Uma nova janela abrirá com os Report Library que existem na AOT. 
  3. Vamos selecionar Shared Library. 
  4. No Solution Explorer, vamos clicar com o botão direito no projeto AeDX_SubReport e selecionar AddReference.  
  5. Na tab Projects, vamos selecionar o projeto Shared Library, clicar em Add e depois em OK.
Em seguida vamos criar nossos relatórios: um relatório de nível superior e um relatório de detalhamento. O relatório superior irá conter uma lista com todos os diários da tabela LedgerJournalTable. E o relatório de detalhamento sera um relatório mais detalhado que irá exibir as informações das linhas dos diários selecionado no relatório de nível superior. Vamos adicionar um parâmetro e um filtro para o relatório de detalhamento. O filtro vai filtrar os dados no relatório de análise com base no valor do parâmetro.

Para criar o relatório de nível superior:
  1. Na Solution Explorer no projeto AeDX_SubReport vamos renomear o relatório Report1.moxl para LedgerJournalTable.moxl.
  2. Vamos adicionar um novo Dataset.
  3. Dê um duplo clique e vamos selecionar a nossa query AeDX_LedgerJournalTable e os campos que iremos utilizar, nesse exemplo vou selecionar os campos JournalNum, JournalName, JournalTotalCredit, JournalTotalDebit.
  4. Selecione o Dataset  e clique com o botão direto e vá em Properties e vamos alterar a propriedade Name para: LedgerJournalTable.
  5. Agora vamos gerar o design do nosso relatório arrastando nosso Dataset para o nó Design, o design automaticamente é nomeado AutoDesign1.
  6. Selecione o nó AutoDesign1, clique com o botão direito e selecione Properties.
  7. Na propriedade LayoutTemplate vamos selecionar ReportLayoutStyleTemplate e na propriedade Title vamos alterar para Diários.
  8. Agora vamos expandir o nó AutoDesign1 e selecionar o nó table LedgerJournalTableTable e em Properties, defina o modelo Style Template para TableStyleTemplate e alterar para LedgerJournalTable a propriedade Title.
Para criar o relatório de detalhamento:
  1. Na Solution Explorer vamos clicar com o botão direito no projeto AeDX_SubReport > Add > New Item.
  2. Vamos selecionar Report e renomeá-lo para LedgerJournalTrans.moxl e clicar em Add.
  3. Vamos adicionar um novo Dataset.
  4. Dê um duplo clique e vamos selecionar a nossa query AeDX_LedgerJournalTrans e os campos que iremos utilizar, nesse exemplo vou selecionar os campos JournalNum, AccountNum, BankAccountId, AmountCurCredit, AmountCurDebit.
  5. Selecione o Dataset  e clique com o botão direto e vá em Properties e vamos alterar a propriedade Name para: LedgerJournalTrans e a propriedade Default Layout para TopDownList.
  6. Agora vamos gerar o design do nosso relatório arrastando nosso Dataset para o nó Design, o design automaticamente é nomeado AutoDesign1.
  7. Selecione o nó AutoDesign1, clique com o botão direito e selecione Properties.
  8. Na propriedade LayoutTemplate vamos selecionar ReportLayoutStyleTemplate e na propriedade Title vamos alterar para Linhas do Diário.
  9. Agora vamos expandir o nó AutoDesign1 e selecionar o nó table LedgerJournalTransList e em Properties, defina o modelo Style Template para ListStyleTemplate e alterar para LedgerJournalTrans a propriedade Title.
Para criar o parâmetro que será usado para transmitir os dados para o relatório de detalhamento:
  1. No relatório LedgerJournalTrans.moxl selecione o nó Parameters e clique com o botão direito e Add Parameter.
  2. Selecione o parâmetro criado e clique com o botão direito em Propriedades altere as propriedades Data Type para System.String, Name para JournalNum, e Prompt String para Número do Diário:.
Para definir um filtro para o relatório de detalhamento:
  1. Vamos expandir o nó Design em seguida expandir o nó LedgerJournalTransList e adicionar um novo filtro clicando com o botão direito sobre Filter > Add Filter.
  2. Selecione o novo filtro e com o botão direito selecione Properties e especifique nas propriedades Expression =Fields!JournalNum.Value,  Name para JornalNum, Operator para Equals e na propriedade Value =Parameters!JournalNum.Value.
Adicionando ao relatório Drill Through Action:

Agora que criamos o relatório de nível superior e o relatório de detalhamento, vamos adicionar uma ação drill through, através de uma ação para ligar os dois relatórios. Uma ação drill through é definida sobre o relatório de nível superior.

Para adicionar a ação drill through:
  1. Na Solution Explorer vamos dar um duplo clique no relatório LedgerJournalTable.moxl.
  2. Vamos expandir o nó Designs, expandir o nó AutoDesign1, expandir o nó LedgerJournalTable e expandir o nó Data.
  3. Vamos selecionar o campo JournalNum e clicar com o botão direito Add > Report Drill Through Action.
  4. Selecione o nó criado e clique com o botão direito em Properties.
  5. Na propriedade ReportDesign clique no botão (…) selecione o relatório de detalhamento (LedgerJournalTrans) e selecione o design AutoDesing1 e em seguida clique em OK.
  6. Selecione o parâmetro JournalNum e especifique na propriedade Value =Fields!JournalNum.Value.
  7. Selecione o parâmetro AX_CompanyName e especifique na propriedade Value =Parameters! AX_CompanyName.Value.
Essa é a visão dos relatórios de nível superior e detalhamento:

  
Para visualizarmos o relatório de detalhamento:
  1. Dê um duplo clique no relatório LedgerJournal.moxl clique com o botão direito no AutoDesign1 > Preview. O relatório é exibido com todos os diários criados.
  2. Clique no número do diário e o relatório de detalhamento é exibido. O relatório de detalhamento exibe os detalhes do diário selecionado.
O resultado é o seguinte:

Diário (Relatório de Nível Superior)
Quando clico no Journal Num 000002_008:

Linhas do Diário (Relatório Detalhamento)
PS. Deixo uma dica, no momento em que estiver criando a query aproveite para criar o range ao invés de criá-lo no Visual Studio pois melhora e muito a performance, pois no momento em que executa a query ele retorna os resultados filtrados.

[]'s 
Alexssander

Exibir relatório com totais por data (dia, mês ou ano).

Tive que fazer um relatório outro dia em que precisava retornar o total que recebi de despesas no mês de um determinado cliente e o prazo médio de faturamento (vencimento – emissão) e recebimento (recebimento – emissão), para isso fiz um relatório todo baseado no fetch() que guardava uma variável com o total por data e um total geral e fazia uma verificação ao mudar a data ele chamava a seção do relatório que retornava o total.

O relatório que desenvolvi ficou dessa maneira:

Estava hoje fuçando em alguns relatórios do AX e acabei descobrindo algo bem interessante que faz exatamente o que eu precisei fazer, só que de uma maneira muito mais simples.

Para isso fiz um exemplo muito para postar a solução no blog.

Primeiramente criei uma tabela temporária com os campos que quero retornar no relatório:


Em seguida criei um relatório baseado na minha tabela temporária e no Sorting ou Order By do meu Data Source adicionei o campo TransDate e nesse momento vem a grande sacada.

Nas propriedades do campo que quero ordenar existe a propriedade AutoSum é o que vai me retornar a soma com base nesse campo.

A propriedade SumDetailLevel é o que vai nos dizer se queremos retornar o total por ano da data (1), pelo mês e ano (2) ou se retorna o total por dia, por mês e por ano (3).



Em seguida no método run() realizei vários inserts direto na tabela para criar uma um exemplo para demonstrar.

No método prompt(), antes do return utilizei o método setCursor para selecionar o registro atual.
  1. queryRun.setCursor(tmpMediumTerm);
Em seguida criei o design do relatório e ele ficou da seguinte maneira:


O projeto encontra-se no meu SkyDrive.

Caso alguém tenha alguma sugestão ou dúvida, comentem.
[]'s
Alexssander

Utilizar uma Sequência Numérica em um Report ou Web

Hoje pela manha um grande amigo Renato Honório, me passou uma grande dica para complementar o post anterior sobre Sequência Numérica.

Um método simples que recebe o próximo número da sequência criada no post anterior, para ser utilizado diretamente em um report ou web.

O método ficou da seguinte maneira:
  1. static void usingWithNoForm(Args _args)
  2. {
  3.     str aux;
  4.     ;
  5.  
  6.     aux = NumberSeq::newGetNum(NumberSequenceReference::find(typeId2ExtendedTypeId(typeid(MyNumberSequence))),true).num();
  7.     info(strfmt("Seq: %1", aux));
  8. }
Mais uma vez agradecer ao Renato Honório e conceder os créditos desse post para ele.

[]’s
Alexssander

Como trabalhar com relatórios via Reporting Services utilizando a query da AOT

Ontem o meu amigo Leandro Sales me perguntou como criar um relatório no Reporting Services utilizando a query da AOT, já havia postado no blog como chamar de dentro do Visual Studio uma classe do AX para retornar um buffer com os dados. Hoje vou postar como retornar os dados utilizando a quey criada na AOT.

Primeiro devemos criar nossa query, para exemplo vamos criar uma query bem simples, porém podemos utilizar todos os recursos do objeto query.

Objeto Query na AOT

Em seguida vamos criar um novo projeto no Visual Studio em C# com o template Dynamics AX Reporting Project.

Agora com o projeto criado vamos adicionar um novo DataSet e para esse DataSet vamos selecionar a query que criamos no AX, selecionar os campos que iremos utilizar.


Feito isso nossa estrutura do relatório ficará da seguinte maneira.

Estrutura do relatório no Visual Studio

Agora com os dados já filtrados e selecionados, podemos manipular os dados dentro do Visual Studio aproveitando todos os recursos que temos para criar o Design, Parâmetros, Filtros, Agrupamento e tudo mais.

Espero que tenha sido útil.

[]'s
Alexssander

Gerar um relatório a partir de um registro selecionado

Ontem meu amigo Abraão me pediu ajuda pra gerar um relatório de acordo com um registro selecionado em um formulário. E me lembrava que já tinha feito e que era muito simples, porém não me recordava dos detalhes. Então em uma breve conversa com meu amigo Leandro Honório ele me ajudou muito e concluí os detalhes e ajudei o Abraão a solucionar o problema. Como já tinha passado pela mesma situação e não guardei tomei nota da resolução, decidi postar dessa vez para termos mais um auxílio.

Nesse caso tenho o formulário AssetTable e preciso criar um botão no formulário que leve para um relatório, porém as informações do relatório devem ser baseadas no registro selecionado.

Primeiro criei um relatório simples com o DataSource AssetTable e no design adicionei 2 campos apenas para demonstrar, a estrutura do relatório ficou da seguinte maneira:

Estrutura do relatório

Em seguida declarei a tabela como uma variável global:
  1. public class ReportRun extends ObjectRun
  2. {
  3.     AssetTable currentRecord;
  4. }
Depois sobreescrevi o método init, para que no momento que ele iniciar o relatório nossa variável global receba os parâmetro do registro selecionado:
  1. public void init()
  2. {
  3.     super();
  4.     currentRecord = element.args().record();
  5. }
E em seguida vamos sobreescrever o método fetch, para executar nossa query e para que possamos adicionar o range atual ao DataSource, assim preenchendo o DataSource apenas com os dados do registro selecionado:
  1. public boolean fetch()
  2. {
  3. boolean ret;
  4. ;
  5.  
  6. queryRun = new QueryRun(this);
  7. queryRun.query().dataSourceTable(tablenum(AssetTable)).addRange(fieldnum(AssetTable, AssetId)).value(currentRecord.AssetId);
  8. ret = super();
  9. return ret;
  10. }
Feito isso vamos desabilitar a propriedade Interactive do Relatório e na Query.

Com o relatório criado vamos criar um MenuItem do nosso relatório e no nosso formulário criar um botão partindo do MenuItem e passar a propriedade DataSouce para a tabela que estamos utilizando.

E com isso ao selecionar um registro e clicarmos no botão o relatório é gerado a partir do registro selecionado.

[]'s
Alexssander

A diferença entre o AutoDesignSpecs para o Generated Design.

Quando você usa AutoDesignSpecs, o layout do relatório é gerado quando o relatório é executado. O seu conteúdo e o layout é baseado na consulta utilizado para o relatório.

No GeneratedDesign, o layout é ditado pela concepção da estrutura criada no Visual Report Designer e não por uma consulta ou modelo de relatório.

Um relatório que é criado usando a opção GeneratedDesignSpecs tem várias diferenças de uma criada usando AutoDesignSpecs.

• Uma diferença principal é que um design personalizado não é afetado pela estrutura da consulta subjacente. A concepção é definida pelo dono da obra e não gerado automaticamente.

• Outra diferença é que as alterações ao modelo de relatório padrão, se ela é usada, não afeta o desenho de um relatório usando a opção GeneratedDesignSpec.

[]'s
Alexssander