31 08 2016
Formatação condicional no Crystal Reports
O que seria um relatório sem regras que alterem a sua formatação dependendo de condições de negócios? Muito provavelmente seria um relatório bem “chato“, somente listando alguns valores e deixando 100% da sua interpretação a cargo do usuário. Se você está acostumado a entregar os seus relatórios dessa maneira “sem graça“, já passou da hora de mudar essa realidade. Uns tempos atrás eu mostrei como trabalhar com expressões no Report Viewer e hoje é a vez do Crystal Reports. No artigo de hoje, confira como adicionar formatação condicional no Crystal Reports.
Criando o projeto e a classe de domínio
Para entendermos a formatação condicional no Crystal Reports, temos que primeiramente criar um relatório. Para simplificar o entendimento, o nosso relatório será uma simples listagem, porém, com algumas formatações dependendo de regras de negócios.
Primeiramente, vamos começar criando um novo projeto do tipo “Windows Forms Application“. No final das contas, não importa a plataforma que você escolha, uma vez que trabalharemos a formatação no próprio relatório (arquivo .rpt), que seria igual para qualquer plataforma que você estiver trabalhando. Eu só escolhi Windows Forms por ser mais fácil e por ser a plataforma mais utilizada.
Dentro do projeto, vamos criar uma pequena classe de domínio chamada “Produto“. Essa classe terá algumas propriedades, que serão todas posteriormente listadas no relatório:
// C# public class Produto { public int ProdutoId { get; set; } public string Nome { get; set; } public decimal Preco { get; set; } public int EstoqueMinimo { get; set; } public int EstoqueAtual { get; set; } public bool Descontinuado { get; set; } }
' VB.NET Public Class Produto Public Property ProdutoId As Integer Public Property Nome As String Public Property Preco As Decimal Public Property EstoqueMinimo As Integer Public Property EstoqueAtual As Integer Public Property Descontinuado As Boolean End Class
Criando o esqueleto do relatório
Com a classe de domínio criada, vamos partir para a criação do esqueleto do relatório. Para isso, adicione no projeto um novo item do tipo “Crystal Reports“. Esse tipo de item fica dentro da categoria “Reporting“. Dê o nome de “RelatorioProdutos” para este novo item:
A partir daqui, temos duas opções: ou criamos o relatório em branco ou utilizamos o assistente. Neste artigo eu vou prosseguir com o relatório em branco, mas, se você quiser seguir com o assistente, não fará diferença alguma.
Uma vez criado o relatório, temos que configurar a fonte de dados do relatório. Para isso, vamos até a janela de “Field Explorer“, clicamos com o botão direito em “Database Fields” e escolhemos a opção “Database Expert“:
Em seguida, temos que encontrar a nossa classe “Produto” para jogarmos para o lado “Selected Tables“. Encontramos essa classe dentro da categoria “.NET Objects“:
Por fim, vamos arrastar os campos da janela “Field Explorer” para dentro da área de detalhes do relatório e vamos adicionar um título ao relatório, de forma que ele fique parecido com a imagem abaixo:
Exibindo o relatório
Agora que já temos o nosso relatório em mãos, vamos exibir esse relatório no nosso formulário. Para isso, temos que arrastar um controle do Crystal Reports para dentro do formulário e, em seguida, temos que escolher o relatório que acabamos de criar:
Feito isso, vamos adicionar um pouquinho de código no code-behind do formulário para criarmos e passarmos uma lista de Produtos para o relatório. Faremos isso com um laço “for” e alguns dados aleatórios. Obviamente, no seu projeto “de verdade“, você teria que recuperar os dados do banco:
// C# public Form1() { InitializeComponent(); var rand = new Random(); var lista = new List<Produto>(); for (int contador = 1; contador <= 100; contador++) { lista.Add(new Produto() { ProdutoId = contador, Nome = "Produto " + contador, Preco = Convert.ToDecimal(rand.NextDouble() * 100), EstoqueMinimo = rand.Next(1, 1000), EstoqueAtual = rand.Next(1, 1000), Descontinuado = Convert.ToBoolean(rand.Next(-1, 1)) }); } RelatorioProdutos1.SetDataSource(lista); RelatorioProdutos1.Refresh(); }
' VB.NET Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim Rand As Random = New Random() Dim Lista As List(Of Produto) = New List(Of Produto) For Contador As Integer = 1 To 100 Lista.Add(New Produto() With { .ProdutoId = Contador, .Nome = "Produto " & Contador, .Preco = Convert.ToDecimal(Rand.NextDouble() * 100), .EstoqueMinimo = Rand.Next(1, 1000), .EstoqueAtual = Rand.Next(1, 1000), .Descontinuado = Convert.ToBoolean(Rand.Next(-1, 1)) }) Next RelatorioProdutos1.SetDataSource(Lista) RelatorioProdutos1.Refresh() End Sub
Execute o projeto e veja o resultado do relatório sem a formatação condicional:
Nota: se você receber uma “FileNotFoundException” vindo do controle do Crystal Reports ao executar o projeto, isso quer dizer que falta uma configuração no seu arquivo app.config. Eu mostrei como fazer essa configuração no artigo: Trabalhando com o Crystal Reports no WPF.
Adicionando formatação condicional
E agora, André? Como é que eu adiciono formatação condicional nesse relatório? Não se preocupe. É justamente isso que eu vou mostrar para você a partir daqui. Que tal alterarmos a cor da fonte de “Estoque mínimo” para vermelho caso ele seja menor que o “Estoque atual“?
O Crystal Reports é extremamente flexível no que diz respeito à formatação condicional. Diferente do Report Viewer, ele suporta a criação de fórmulas para praticamente qualquer propriedade do relatório. Todo lugar onde você encontrar um botão com um símbolo “x2” quer dizer que você pode adicionar uma fórmula para aquela propriedade.
Por exemplo, para adicionarmos a formatação do “Estoque mínimo“, temos que abrir a formatação do controle clicando com o botão direito e escolhendo a opção “Format Object“:
Em seguida, temos que ir até a aba “Font“. Veja só os botões “x2” que eu mencionei anteriormente:
No nosso caso, como queremos adicionar uma lógica referente à cor da célula, temos que clicar no botão “x2” da propriedade “Color“. Quando clicamos no botão, a janela de edição de fórmula do Crystal Reports será aberta. Dentro dessa janela, temos que colocar a expressão que deverá retornar “vermelho” caso o “Estoque atual” seja menor que o “Estoque mínimo” ou preto caso contrário.
As fórmulas do Crystal Reports podem ser escritas de duas maneiras: utilizando a sintaxe do próprio Crystal Reports (que é tipo um Pascal misturado com Basic e C) ou utilizando a sintaxe Basic. Eu nunca vi ninguém utilizar a sintaxe Basic em relatórios do Crystal Reports, mas, é totalmente possível. Essa opção pode ser bem útil caso você esteja acostumado a desenvolver relatórios no Report Viewer ou caso você trabalhe com VB.NET.
Para implementarmos essa lógica da cor, utilizamos a seguinte fórmula:
if ({CrystalFormatacaoCustomizada_Produto.EstoqueAtual} < {CrystalFormatacaoCustomizada_Produto.EstoqueMinimo}) then crRed else crBlack
Ou, caso você prefira trabalhar com a sintaxe em Basic, a fórmula seria esta:
formula = IIf({CrystalFormatacaoCustomizada_Produto.EstoqueAtual} < {CrystalFormatacaoCustomizada_Produto.EstoqueMinimo}, crRed, crBlack)
Para escolher a sintaxe da fórmula, utilize esse dropdown:
Dentro do mesmo relatório você pode ter algumas fórmulas com a sintaxe do Crystal Reports e outras fórmulas com sintaxe Basic.
Escondendo linhas baseando-se em uma condição
Agora que já vimos como trabalhar a formatação de textos baseando-se em uma fórmula, vamos ver como podemos esconder registros utilizando uma regra de negócio. No nosso exemplo, vamos supor que queiramos esconder os produtos descontinuados.
É possível adicionarmos lógicas de negócio para cada seção do relatório (cabeçalho do relatório, cabeçalho de página, detalhes, rodapés, etc). Para isso, basta clicarmos na seção desejada (no nosso caso, a seção de detalhes) e então, temos que clicar na opção “Section Expert“:
Note que, dentro da janela “Section Expert“, temos os famosos botões “x2” para as propriedades da seção:
No nosso caso, vamos adicionar uma fórmula na propriedade “Suppress“. A fórmula deverá retornar “true” caso o registro deva ser escondido, e “false” caso contrário. Dessa forma, para escondermos os produtos descontinuados, nós só temos que utilizar o campo “Descontinuado” da nossa tabela de produtos:
{CrystalFormatacaoCustomizada_Produto.Descontinuado}
Execute a aplicação e veja o resultado:
Como você pode notar, nos produtos em que “Estoque atual” é menor que “Estoque mínimo“, a célula correspondente ao “Estoque atual” está pintada de vermelho. Além disso, note que alguns produtos foram escondidos (Ids 3, 5, 6, etc). Esses produtos foram escondidos porque estão descontinuados.
Concluindo
O Crystal Reports é extremamente flexível no que diz respeito à adição de lógicas de negócio para as propriedades dos seus controles e seções. Nós podemos adicionar fórmulas em praticamente todas as propriedades de todos os controles. Essas fórmulas podem ser escritas tanto utilizando a sintaxe do próprio Crystal Reports quanto a sintaxe em Basic.
Neste artigo você conferiu como trabalhar com formatação condicional no Crystal Reports, adicionando uma fórmula na propriedade “Color” de uma célula, de forma que ela seja pintada de vermelho em algumas situações. Além disso, você aprendeu também a esconder registros do relatório baseando-se em uma fórmula.
E você, já utilizou as fórmulas do Crystal Reports? Qual foi a fórmula mais maluca que você já teve que implementar nos seus relatórios? Você costuma utilizar a sintaxe do Crystal Reports ou a sintaxe em Basic? Estamos todos curiosos para saber, então, conte-nos mais detalhes na caixa de comentários!
Por fim, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário logo abaixo.
Até a próxima!
André Lima
Photo by Pixabay used under Creative Commons
https://pixabay.com/en/typography-geschtaltung-fonts-1069409/
Expondo PDFs gerados pelo Report Viewer com Web API Acessando os web services dos Correios com C# e VB.NET (consulta de CEPs e preços)
Ola Sr. André, é um prazer poder acompanhar seus posts sempre muito bons. Tenho um projeto em access e gostaria de saber se há uma maneira de converter da linguagem vba para c# do visual studio 2015. Desde já agradeço sua atenção.
Olá Welligton, obrigado pelo comentário!
Que eu saiba, não existe uma ferramenta que converta diretamente do VBA para C#.. O que você poderia tentar fazer é converter primeiramente para VB.NET (manualmente, mas, não deve ser muito difícil porque tem muita similaridade) e depois do VB.NET para o C# você encontra ferramentas que fazem a conversão (como esta aqui).. Acredito que a parte que vai ser mais desafiadora na conversão do VBA para o VB.NET é a questão do acesso a dados (se você utiliza ADO no VBA, você terá que migrar para ADO.NET no VB.NET)..
Abraço!
André Lima