Como você sombreia linhas alternadas em um relatório do SQL Server Reporting Services?
Edit: Existem várias respostas boas listadas abaixo - de rápidas e simples a complexas e abrangentes . Infelizmente, eu posso escolher apenas um ...
Como você sombreia linhas alternadas em um relatório do SQL Server Reporting Services?
Edit: Existem várias respostas boas listadas abaixo - de rápidas e simples a complexas e abrangentes . Infelizmente, eu posso escolher apenas um ...
Respostas:
Vá para a propriedade BackgroundColor da linha da tabela e escolha "Expressão ..."
Use esta expressão:
= IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", "Transparent")
Esse truque pode ser aplicado a muitas áreas do relatório.
E no .NET 3.5+ você pode usar:
= If(RowNumber(Nothing) Mod 2 = 0, "Silver", "Transparent")
Não estou procurando representante - acabei de pesquisar essa pergunta e pensei em compartilhar.
[rsInvalidColor] The value of the BackgroundColor property for the textbox ‘active’ is “Transparent”, which is not a valid BackgroundColor.
Parece que a expressão correta seria =IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", Nothing)
. Obrigado pela dica, no entanto.
O uso de IIF (RowNumber ...) pode causar alguns problemas quando as linhas estão sendo agrupadas e outra alternativa é usar uma função simples do VBScript para determinar a cor.
É um pouco mais de esforço, mas quando a solução básica não é suficiente, é uma boa alternativa.
Basicamente, você adiciona código ao relatório da seguinte maneira ...
Private bOddRow As Boolean
'*************************************************************************
' -- Display green-bar type color banding in detail rows
' -- Call from BackGroundColor property of all detail row textboxes
' -- Set Toggle True for first item, False for others.
'*************************************************************************
Function AlternateColor(ByVal OddColor As String, _
ByVal EvenColor As String, ByVal Toggle As Boolean) As String
If Toggle Then bOddRow = Not bOddRow
If bOddRow Then
Return OddColor
Else
Return EvenColor
End If
End Function
Em cada célula, defina o BackgroundColor da seguinte maneira:
=Code.AlternateColor("AliceBlue", "White", True)
Detalhes completos estão neste artigo da Wrox
Tive o efeito do xadrez quando usei a solução da Catch22, acho que porque minha matriz possui mais de uma coluna no design. essa expressão funcionou bem para mim:
=iif(RunningValue(Fields![rowgroupfield].Value.ToString,CountDistinct,Nothing) Mod 2,"Gainsboro", "White")
Alterei a solução do @ Catch22 Um pouco porque não gosto da ideia de entrar em cada campo se decidir mudar uma das cores. Isso é especialmente importante nos relatórios em que existem vários campos que precisam ter a variável de cor alterada.
'*************************************************************************
' -- Display alternate color banding (defined below) in detail rows
' -- Call from BackgroundColor property of all detail row textboxes
'*************************************************************************
Function AlternateColor(Byval rowNumber as integer) As String
Dim OddColor As String = "Green"
Dim EvenColor As String = "White"
If rowNumber mod 2 = 0 then
Return EvenColor
Else
Return OddColor
End If
End Function
Notei que alterei a função de uma que aceita as cores para uma que contém as cores a serem usadas.
Em cada campo, adicione:
=Code.AlternateColor(rownumber(nothing))
Isso é muito mais robusto do que alterar manualmente a cor na cor de fundo de cada campo.
Uma coisa que notei é que nenhum dos dois métodos principais tem noção de que cor a primeira linha deve ter em um grupo; o grupo começará apenas com a cor oposta à última linha do grupo anterior. Eu queria que meus grupos sempre começassem com a mesma cor ... a primeira linha de cada grupo sempre deve ser branca e a próxima linha colorida.
O conceito básico era redefinir a alternância quando cada grupo inicia, então adicionei um pouco de código:
Private bOddRow As Boolean
'*************************************************************************
' -- Display green-bar type color banding in detail rows
' -- Call from BackGroundColor property of all detail row textboxes
' -- Set Toggle True for first item, False for others.
'*************************************************************************
Function AlternateColor(ByVal OddColor As String, _
ByVal EvenColor As String, ByVal Toggle As Boolean) As String
If Toggle Then bOddRow = Not bOddRow
If bOddRow Then
Return OddColor
Else
Return EvenColor
End If
End Function
'
Function RestartColor(ByVal OddColor As String) As String
bOddRow = True
Return OddColor
End Function
Então, eu tenho três tipos diferentes de fundos de células agora:
Isso funciona para mim. Se você deseja que a linha de agrupamento seja sem cor ou com uma cor diferente, deve ser bastante óbvio, como alterá-la.
Por favor, sinta-se à vontade para adicionar comentários sobre o que poderia ser feito para melhorar esse código: sou novato no SSRS e no VB, então suspeito fortemente que há muito espaço para melhorias, mas a idéia básica parece sólida (e foi útil para mim) então eu queria jogá-lo aqui.
para cabeçalhos / rodapés de grupo:
=iif(RunningValue(*group on field*,CountDistinct,"*parent group name*") Mod 2,"White","AliceBlue")
Você também pode usar isso para "redefinir" a contagem de cores da linha em cada grupo. Eu queria que a primeira linha de detalhes de cada subgrupo iniciasse com White e essa solução (quando usada na linha de detalhes) permitiu que isso acontecesse:
=IIF(RunningValue(Fields![Name].Value, CountDistinct, "NameOfPartnetGroup") Mod 2, "White", "Wheat")
Consulte: http://msdn.microsoft.com/en-us/library/ms159136(v=sql.100).aspx
A solução de Michael Haren funciona bem para mim. No entanto, recebi um aviso dizendo que "Transparente" não é um BackgroundColor válido ao visualizar. Foi encontrada uma correção rápida em Configurando elementos BackgroundColor of Report no SSRS . Use Nothing em vez de "Transparente"
= IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", Nothing)
A única maneira eficaz de resolver isso sem usar o VB é "armazenar" o valor do módulo de agrupamento de linhas dentro do agrupamento de linhas (e fora do agrupamento de colunas) e referenciá-lo explicitamente no seu agrupamento de colunas. Encontrei esta solução em
http://ankeet1.blogspot.com/2009/02/alternating-row-background-color-for.html
Mas Ankeet não explica melhor o que está acontecendo, e sua solução recomenda a etapa desnecessária de criar um agrupamento em um valor constante, então aqui está o meu processo passo a passo para uma matriz com um único grupo de linhas RowGroup1:
Defina o valor da caixa de texto do RowGroupColor como
=iif(RunningValue(Fields![RowGroupField].Value
,CountDistinct,Nothing) Mod 2, "LightSteelBlue", "White")
Defina a propriedade BackgroundColor de todas as suas células de linha como
"=ReportItems!RowGroupColor.Value"
Voila! Isso também resolve muitos dos problemas mencionados neste segmento:
Seria incrível se o SSRS expusesse propriedades além de Valor em caixas de texto. Você pode simplesmente preencher esse tipo de cálculo em uma propriedade BackgroundColor das caixas de texto do grupo de linhas e referenciá-lo como ReportItems! RowGroup.BackgroundColor em todas as outras células.
Ahh bem, podemos sonhar ...
Meu problema era que eu queria que todas as colunas seguidas tivessem o mesmo plano de fundo. Agrupei por linha e por coluna e, com as duas principais soluções, obtive todas as linhas da coluna 1 com fundo colorido, todas as linhas da coluna 2 com fundo branco, todas as linhas da coluna 3 com fundo colorido , e assim por diante. É como se RowNumber
e bOddRow
(da solução de Catch22) prestasse atenção ao meu grupo de colunas em vez de ignorá-lo e alternando apenas com uma nova linha.
O que eu queria era que todas as colunas da linha 1 tivessem um plano de fundo branco, depois todas as colunas da linha 2 tivessem um plano de fundo colorido, depois todas as colunas da linha 3 tivessem um plano de fundo branco e assim por diante. Eu obtive esse efeito usando a resposta selecionada, mas em vez de passar Nothing
para RowNumber
, passei o nome do meu grupo de colunas, por exemplo
=IIf(RowNumber("MyColumnGroupName") Mod 2 = 0, "AliceBlue", "Transparent")
Achei que isso poderia ser útil para outra pessoa.
Em qualquer tipo de matriz complexa, quando você deseja cores de célula alternativas, em linhas ou em colunas, a solução de trabalho é:
Se você quiser uma cor alternativa de células, então,
= IIF (RunningValue (Campos! [ColumnGroupField] .Value, countDistinct, "FakeParentGroup") MOD 2, "Branco", "LightGrey")
Isso é tudo.
O mesmo para as linhas de cores alternativas, basta editar a solução de acordo.
NOTA: Aqui, às vezes você precisa definir a borda das células adequadamente, geralmente ela desaparece.
Também não se esqueça de excluir o valor 1 no relatório que entrou na foto quando você criou um grupo pai falso.
@ A resposta de Aditya é ótima, mas há casos em que a formatação será iniciada se a primeira célula da linha (para formatação de plano de fundo da linha) tiver um valor ausente (em tablixes complexos com grupos de colunas / linhas e valores ausentes).
A solução da @ Aditya aproveita inteligentemente o countDistinct
resultado da runningValue
função para identificar números de linhas em um grupo tablix (linha). Se você tiver linhas tablix com valor ausente na primeira célula, runningValue
não aumentará o countDistinct
resultado e retornará o número da linha anterior (e, portanto, afetará a formatação dessa célula). Para explicar isso, você precisará adicionar um termo adicional para compensar o countDistinct
valor. Minha opinião foi verificar o primeiro valor em execução no próprio grupo de linhas (consulte a linha 3 do snippet abaixo):
=iif(
(RunningValue(Fields![RowGroupField].Value, countDistinct, "FakeOrRealImmediateParentGroup")
+ iif(IsNothing(RunningValue(Fields![RowGroupField].Value, First, "GroupForRowGroupField")), 1, 0)
) mod 2, "White", "LightGrey")
Espero que isto ajude.
Alguém poderia explicar a lógica por trás de transformar o restante dos campos em false no código abaixo (da postagem acima)
Uma coisa que notei é que nenhum dos dois métodos principais tem noção da cor da primeira linha de um grupo; o grupo começará apenas com a cor oposta à última linha do grupo anterior. Eu queria que meus grupos sempre começassem com a mesma cor ... a primeira linha de cada grupo sempre deve ser branca e a próxima linha colorida.
O conceito básico era redefinir a alternância quando cada grupo inicia, então adicionei um pouco de código:
Private bOddRow As Boolean
'*************************************************************************
'-- Display green-bar type color banding in detail rows
'-- Call from BackGroundColor property of all detail row textboxes
'-- Set Toggle True for first item, False for others.
'*************************************************************************
'
Function AlternateColor(ByVal OddColor As String, _
ByVal EvenColor As String, ByVal Toggle As Boolean) As String
If Toggle Then bOddRow = Not bOddRow
If bOddRow Then
Return OddColor
Else
Return EvenColor
End If
End Function
'
Function RestartColor(ByVal OddColor As String) As String
bOddRow = True
Return OddColor
End Function
Então, eu tenho três tipos diferentes de fundos de células agora:
Isso funciona para mim. Se você deseja que a linha de agrupamento seja sem cor ou com uma cor diferente, deve ser bastante óbvio, como alterá-la.
Por favor, sinta-se à vontade para adicionar comentários sobre o que poderia ser feito para melhorar esse código: sou novato no SSRS e no VB, então suspeito fortemente que há muito espaço para melhorias, mas a idéia básica parece sólida (e foi útil para mim) então eu queria jogá-lo aqui.
Tentei todas essas soluções em um Tablix agrupado com espaços de linha e nenhum funcionou em todo o relatório. O resultado foram linhas coloridas duplicadas e outras soluções resultaram em colunas alternadas!
Aqui está a função que escrevi que funcionou para mim usando uma Contagem de colunas:
Private bOddRow As Boolean
Private cellCount as Integer
Function AlternateColorByColumnCount(ByVal OddColor As String, ByVal EvenColor As String, ByVal ColCount As Integer) As String
if cellCount = ColCount Then
bOddRow = Not bOddRow
cellCount = 0
End if
cellCount = cellCount + 1
if bOddRow Then
Return OddColor
Else
Return EvenColor
End If
End Function
Para um Tablix de 7 colunas, uso esta expressão para o Backcolour Row (of Cells):
=Code.AlternateColorByColumnCount("LightGrey","White", 7)
Só porque nenhuma das respostas acima parecia funcionar na minha matriz, estou postando isso aqui:
http://reportingservicestnt.blogspot.com/2011/09/alternate-colors-in-matrixpivot-table.html
Meus dados matriciais tinham valores ausentes, então não consegui fazer a solução do ahmad funcionar, mas essa solução funcionou para mim
A idéia básica é criar um grupo filho e um campo no seu grupo mais interno que contenha a cor. Em seguida, defina a cor para cada célula na linha com base no valor desse campo.
Ligeira modificação de outras respostas daqui que funcionaram para mim. Meu grupo tem dois valores para agrupar, então pude colocar os dois no primeiro argumento com um + para alternar corretamente
= Iif ( RunningValue (Fields!description.Value + Fields!name.Value, CountDistinct, Nothing) Mod 2 = 0,"#e6eed5", "Transparent")
Ao usar os dois grupos de linhas e colunas, tive um problema em que as cores alternavam entre as colunas, mesmo que fosse a mesma linha. Eu resolvi isso usando uma variável global que alterna apenas quando a linha é alterada:
Public Dim BGColor As String = "#ffffff"
Function AlternateColor() As String
If BGColor = "#cccccc" Then
BGColor = "#ffffff"
Return "#cccccc"
Else
BGColor = "#cccccc"
Return "#ffffff"
End If
End Function
Agora, na primeira coluna da linha que você deseja alternar, defina a expressão de cor para:
= Code.AlternateColor ()
-
Nas colunas restantes, defina todos eles para:
= Code.BGColor
Isso deve alternar as cores somente depois que a primeira coluna for desenhada.
Isso pode (inverificável) melhorar o desempenho também, uma vez que não é necessário fazer um cálculo matemático para cada coluna.