Ajouter une couleur de ligne alternée au rapport des services SQL Server Reporting

142

Comment ombrer les lignes alternées dans un rapport SQL Server Reporting Services?


Edit: Il y a un tas de bonnes réponses énumérées ci-dessous - de rapide et simple à complexe et complet . Hélas, je ne peux en choisir qu'un ...

Michael Haren
la source
2
= IIf (RowNumber (Nothing) Mod 2 = 0, "No Color", "# DDEBF7")
Stefan Steiger
Si vous sélectionnez plusieurs cellules, vous ne pouvez pas modifier les propriétés de la zone de texte, mais vous pouvez accéder à la couleur de remplissage dans le panneau des propriétés et y définir une expression!
kitsu.eb

Réponses:

213

Accédez à la propriété BackgroundColor de la ligne du tableau et choisissez "Expression ..."

Utilisez cette expression:

= IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", "Transparent")

Cette astuce peut être appliquée à de nombreuses zones du rapport.

Et dans .NET 3.5+, vous pouvez utiliser:

= If(RowNumber(Nothing) Mod 2 = 0, "Silver", "Transparent")

Je ne cherche pas de représentant - j'ai juste recherché cette question moi-même et j'ai pensé partager.

Michael Haren
la source
10
Cela échoue dans certaines circonstances, en particulier dans les tableaux et les objets de matrice avec de nombreux sous-totaux. La réponse de Catch22 n'a pas les mêmes limites. En outre, la méthode de Catch22 peut être utilisée pour forcer les colonnes d'une matrice à avoir des couleurs de colonne alternées, ce qui est utile une fois dans une lune bleue.
Utilisateur enregistré
16
Je m'assure toujours de voter pour quelqu'un qui répond à sa propre question. Trop souvent, le demandeur trouve une réponse par lui-même et ne revient jamais la poster, laissant le reste d'entre nous qui pourrait avoir la même question dans le noir. Une bosse pour vous, monsieur.
Matt DiTrolio
4
Lorsque j'utilise le code ci-dessus, j'obtiens un message d'avertissement du type [rsInvalidColor] The value of the BackgroundColor property for the textbox ‘active’ is “Transparent”, which is not a valid BackgroundColor. Il semble que l'expression correcte serait =IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", Nothing). Merci pour le tuyau, cependant.
Russell B
2
Cela pose le problème en cas de regroupement et de vue détaillée
3
certains navigateurs ne peuvent pas gérer "Transparent" ou "Rien". Le mieux serait d'utiliser "White"
Nate S.
89

L'utilisation de IIF (RowNumber ...) peut entraîner des problèmes lorsque les lignes sont groupées et une autre alternative consiste à utiliser une simple fonction VBScript pour déterminer la couleur.

C'est un peu plus d'effort mais quand la solution de base ne suffit pas, c'est une belle alternative.

Fondamentalement, vous ajoutez du code au rapport comme suit ...

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

Ensuite, sur chaque cellule, définissez le BackgroundColor comme suit:

=Code.AlternateColor("AliceBlue", "White", True)

Tous les détails sont sur cet article de Wrox

Catch22
la source
Le code ci-dessus est ajouté à la section Code du rapport ou à une page code-behind dans un projet VB.NET, compilé et déployé en tant que DLL qui fait référence en tant qu'assembly. Je recommande de faire un effort supplémentaire pour le déployer en tant que dll puisque vous y faites généralement référence dans de nombreux rapports.
Utilisateur enregistré le
C'est ma façon préférée de gérer le problème de regroupement, après avoir essayé quelques autres hacks. Il ne se décompose pas lorsque le tri interactif est appliqué à une colonne. +1 et merci beaucoup.
Rex Miller
Les couleurs sont décalées lorsque vous avez un nombre impair de lignes.
K Richard
20
N'oubliez pas de changer "True" en "False" pour toutes les colonnes de la ligne après la première, sinon vous verrez un effet de damier! Merci pour la solution - cela fonctionne très bien!
Peter Mularien
Peter Mularien: J'ai ce problème, pouvez-vous expliquer comment le résoudre?
Bill Software Engineer
65

J'ai eu l'effet d'échecs lorsque j'ai utilisé la solution de Catch22, je pense que ma matrice a plus d'une colonne en conception. cette expression a bien fonctionné pour moi:

=iif(RunningValue(Fields![rowgroupfield].Value.ToString,CountDistinct,Nothing) Mod 2,"Gainsboro", "White")
ahmad
la source
13
Cette réponse mérite beaucoup plus d'attention - c'est une solution propre qui fonctionne parfaitement dans une matrice avec des groupes de lignes et des groupes de colonnes et ne nécessite aucun code personnalisé pour fonctionner. Belle!
Stefan Mohr
9
En fait, cela fonctionne bien même pour plusieurs colonnes - mais pas si vous avez des données «manquantes» dans un regroupement. Donc, si vous avez des données qui ont 12 mois de données de données en 2007 mais aucune donnée de janvier en 2006, et groupées par mois sur les lignes et par année sur les colonnes, la coloration 2006 sera désactivée de un car la RunningValue est désynchronisée car même s'il y a encore une boîte dans la matrice pour "janvier 2006" il n'y a pas de données dans le jeu de données et la RunningValue reste la même, pas de changement de couleur, etc.
Kyle Hale
2
@ahmad c'est si proche. J'ai le problème où les boîtes vides utilisent la couleur opposée. comment m'assurer que les boîtes vides sont bien colorées?
FistOfFury
@KyleHale avez-vous un correctif pour la coloration de la boîte manquante?
FistOfFury
2
@FistOfFury La seule solution que je connais est de m'assurer qu'une valeur est définie (généralement 0) pour les données manquantes.
Kyle Hale
20

J'ai changé la solution de @ Catch22 Un peu car je n'aime pas l'idée de devoir entrer dans chaque champ si je décide que je veux changer l'une des couleurs. Ceci est particulièrement important dans les rapports dans lesquels de nombreux champs nécessiteraient une modification de la variable de couleur.

'*************************************************************************
' -- 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

Remarqué que j'ai changé la fonction de celle qui accepte les couleurs à celle qui contient les couleurs à utiliser.

Ensuite, dans chaque champ, ajoutez:

=Code.AlternateColor(rownumber(nothing))

C'est beaucoup plus robuste que de changer manuellement la couleur de la couleur d'arrière-plan de chaque champ.

Michael Eakins
la source
1
Bel ajout à ce fil! J'aime ne pas avoir à définir «True» ou «False» dans chaque colonne. J'aime aussi l'option "mod 3" donc je ne peux ombrer que tous les 3 rangs.
Baodad
J'aime aussi cette solution. Cependant, cela ne fonctionne pas pour moi lorsque j'utilise le regroupement de lignes. La solution de @ ahmad ci-dessus a fonctionné pour moi cependant.
Baodad
C'est une excellente solution pour un tablix si vous ne souhaitez pas ajouter de champs supplémentaires à votre DataSet!
clamchoda
16

Une chose que j'ai remarquée est qu'aucune des deux méthodes principales n'a la moindre idée de la couleur de la première ligne dans un groupe; le groupe commencera simplement avec la couleur opposée à la dernière ligne du groupe précédent. Je voulais que mes groupes commencent toujours par la même couleur ... la première ligne de chaque groupe devrait toujours être blanche et la ligne suivante colorée.

Le concept de base était de réinitialiser la bascule lorsque chaque groupe démarre, j'ai donc ajouté un peu de code:

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

J'ai donc trois types différents d'arrière-plans de cellules maintenant:

  1. La première colonne de la ligne de données a = Code.AlternateColor ("AliceBlue", "White", True) (C'est la même chose que la réponse précédente.)
  2. Les colonnes restantes de la ligne de données ont = Code.AlternateColor ("AliceBlue", "White", False) (Ceci est également identique à la réponse précédente.)
  3. La première colonne de la ligne de regroupement a = Code.RestartColor ("AliceBlue") (Ceci est nouveau.)
  4. Les colonnes restantes de la ligne de regroupement ont = Code.AlternateColor ("AliceBlue", "White", False) (Ceci était utilisé auparavant, mais aucune mention de celui-ci pour le regroupement de lignes.)

Cela fonctionne pour moi. Si vous voulez que la ligne de regroupement soit non colorée ou d'une couleur différente, il devrait être assez évident de la changer.

N'hésitez pas à ajouter des commentaires sur ce qui pourrait être fait pour améliorer ce code: je suis tout nouveau à la fois dans SSRS et VB, donc je soupçonne fortement qu'il y a beaucoup de place pour l'amélioration, mais l'idée de base semble bonne (et c'était utile pour moi) alors je voulais le jeter ici.

Beska
la source
Vous pouvez également réinitialiser la numérotation des lignes pour chaque groupe comme décrit dans cette réponse .
StackOverthrow
10

pour les en-têtes / pieds de page de groupe:

=iif(RunningValue(*group on field*,CountDistinct,"*parent group name*") Mod 2,"White","AliceBlue")

Vous pouvez également l'utiliser pour «réinitialiser» le nombre de couleurs de ligne dans chaque groupe. Je voulais que la première ligne de détail de chaque sous-groupe commence par White et cette solution (lorsqu'elle est utilisée sur la ligne de détail) a permis que cela se produise:

=IIF(RunningValue(Fields![Name].Value, CountDistinct, "NameOfPartnetGroup") Mod 2, "White", "Wheat")

Voir: http://msdn.microsoft.com/en-us/library/ms159136(v=sql.100).aspx

John Saunders
la source
8

La solution de Michael Haren fonctionne très bien pour moi. Cependant, j'ai reçu un avertissement disant que "Transparent" n'est pas un BackgroundColor valide lors de la prévisualisation. Nous avons trouvé une solution rapide à partir de la définition de BackgroundColor des éléments de rapport dans SSRS . N'utilisez rien au lieu de "Transparent"

= IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", Nothing)
nonetaku
la source
Le blanc serait mieux que rien.
Nate S.
6

Le seul moyen efficace de résoudre ce problème sans utiliser VB est de "stocker" la valeur du module de groupement de lignes dans le groupement de lignes (et en dehors du groupement de colonnes) et de la référencer explicitement dans ton groupement de colonnes. J'ai trouvé cette solution à

http://ankeet1.blogspot.com/2009/02/alternating-row-background-color-for.html

Mais Ankeet n'est pas le meilleur travail pour expliquer ce qui se passe, et sa solution recommande l'étape inutile de créer un regroupement sur une valeur constante, alors voici mon processus étape par étape pour une matrice avec un seul groupe de lignes RowGroup1:

  1. Créez une nouvelle colonne dans RowGroup1. Renommez la zone de texte pour cela en quelque chose comme RowGroupColor.
  2. Définissez la valeur de la zone de texte de RowGroupColor sur

    =iif(RunningValue(Fields![RowGroupField].Value ,CountDistinct,Nothing) Mod 2, "LightSteelBlue", "White")

  3. Définissez la propriété BackgroundColor de toutes vos cellules de ligne sur

    "=ReportItems!RowGroupColor.Value"

  4. Définissez la largeur de la colonne RowGroupColor sur 0pt et définissez CanGrow sur false pour le masquer des clients.

Voila! Cela résout également de nombreux problèmes mentionnés dans ce fil:

  • Réinitialisations automatiques pour les sous-groupes: ajoutez simplement une nouvelle colonne pour ce groupe de lignes, en effectuant un RunningValue sur son valeurs de groupe.
  • Pas besoin de s'inquiéter des basculements Vrai / Faux.
  • Les couleurs ne sont conservées qu'au même endroit pour une modification facile.
  • Peut être utilisé de manière interchangeable sur des groupes de lignes ou de colonnes (définissez simplement la hauteur sur 0 au lieu de la largeur)

Ce serait génial si SSRS exposait des propriétés en plus de Value sur les zones de texte. Vous pouvez simplement remplir ce type de calcul dans une propriété BackgroundColor des zones de texte du groupe de lignes, puis le référencer comme ReportItems! RowGroup.BackgroundColor dans toutes les autres cellules.

Ahh bien, on peut rêver ...

Kyle Hale
la source
5

Mon problème était que je voulais que toutes les colonnes d'affilée aient le même arrière-plan. J'ai regroupé à la fois par ligne et par colonne, et avec les deux premières solutions ici, j'ai obtenu toutes les lignes de la colonne 1 avec un fond coloré, toutes les lignes de la colonne 2 avec un fond blanc, toutes les lignes de la colonne 3 avec un fond coloré , etc. C'est comme si RowNumberetbOddRow (de la solution de Catch22) faites attention à mon groupe de colonnes au lieu d'ignorer cela et d'alterner uniquement avec une nouvelle ligne.

Ce que je voulais, c'est que toutes les colonnes de la ligne 1 aient un fond blanc, puis toutes les colonnes de la ligne 2 aient un fond coloré, puis toutes les colonnes de la ligne 3 aient un fond blanc, et ainsi de suite. J'ai obtenu cet effet en utilisant la réponse sélectionnée mais au lieu de passer Nothingà RowNumber, j'ai passé le nom de mon groupe de colonnes, par exemple

=IIf(RowNumber("MyColumnGroupName") Mod 2 = 0, "AliceBlue", "Transparent")

J'ai pensé que cela pourrait être utile à quelqu'un d'autre.

Sarah Vessels
la source
4

Je pense que cette astuce n'est pas discutée ici. Alors voilà,

Dans tout type de matrice complexe, lorsque vous voulez des couleurs de cellule alternatives, soit par ligne, soit par colonne, la solution de travail est la suivante:

Si vous voulez une couleur alternative de cellules, alors,

  1. Dans le coin inférieur droit d'une vue de conception de rapport, dans "Groupes de colonnes", créez un faux groupe parent sur 1 (à l'aide d'une expression), nommé "FakeParentGroup".
  2. Ensuite, dans la conception du rapport, pour les cellules à colorier alternativement, utilisez l'expression de couleur d'arrière-plan suivante

= IIF (RunningValue (Fields! [ColumnGroupField] .Value, countDistinct, "FakeParentGroup") MOD 2, "White", "LightGrey")

C'est tout.

Idem pour la ligne de couleur alternative, il vous suffit de modifier la solution en conséquence.

REMARQUE: Ici, vous devez parfois définir la bordure des cellules en conséquence, généralement elle disparaît.

N'oubliez pas non plus de supprimer la valeur 1 dans le rapport qui est entrée en photo lorsque vous avez créé un faux groupe parent.

Aditya
la source
1
Cette réponse est définitivement une excellente trouvaille pour ceux qui doivent créer des bandes de lignes dans des tableaux complexes! S'il existe un groupe parent, utilisez-le. Sinon, créez FakeParentGroup. Les valeurs manquantes dans les tableaux matriciels contenant à la fois des groupes de colonnes et de lignes annulent généralement la mise en forme. Voir ma réponse qui s'appuie sur @ Aditya pour tenir compte des valeurs manquantes dans la première cellule.
rpyzh
2

Si, pour l'ensemble du rapport, vous avez besoin d'une couleur alternative, vous pouvez utiliser le DataSet auquel votre tableau matriciel est lié pour un numéro de ligne d'identité à l'échelle du rapport sur le rapport et l'utiliser dans la fonction RowNumber ...

=IIf(RowNumber("DataSet1")  Mod 2 = 1, "White","Blue")
Mat
la source
2

La réponse de @ Aditya est excellente, mais il y a des cas où la mise en forme sera rejetée si la toute première cellule de la ligne (pour la mise en forme de l'arrière-plan de la ligne) a une valeur manquante (dans les tableaux complexes avec des groupes de colonnes / lignes et des valeurs manquantes).

La solution de @ Aditya exploite intelligemment le countDistinctrésultat de la runningValuefonction pour identifier les numéros de ligne dans un groupe de tableaux matriciels (lignes). Si vous avez des lignes de tableau matriciel avec une valeur manquante dans la première cellule, runningValuen'incrémentera pas le countDistinctrésultat et renverra le numéro de la ligne précédente (et, par conséquent, affectera la mise en forme de cette cellule). Pour tenir compte de cela, vous devrez ajouter un terme supplémentaire pour compenser la countDistinctvaleur. Ma prise était de vérifier la première valeur courante dans le groupe de lignes lui-même (voir la ligne 3 de l'extrait ci-dessous):

=iif(
    (RunningValue(Fields![RowGroupField].Value, countDistinct, "FakeOrRealImmediateParentGroup")
    + iif(IsNothing(RunningValue(Fields![RowGroupField].Value, First, "GroupForRowGroupField")), 1, 0)
    ) mod 2, "White", "LightGrey")

J'espère que cela t'aides.

rpyzh
la source
Merci @rpyzh, c'était la solution qui fonctionnait pour mon groupe à plusieurs lignes avec un rapport de groupe de lignes parent commun!
Niallty
1

Quelqu'un pourrait-il expliquer la logique derrière la transformation du reste des champs en faux dans le code ci-dessous (à partir du post ci-dessus)

Une chose que j'ai remarquée est qu'aucune des deux méthodes principales n'a la moindre idée de la couleur de la première ligne dans un groupe; le groupe commencera simplement avec la couleur opposée à la dernière ligne du groupe précédent. Je voulais que mes groupes commencent toujours par la même couleur ... la première ligne de chaque groupe doit toujours être blanche et la ligne suivante colorée.

Le concept de base était de réinitialiser la bascule lorsque chaque groupe démarre, j'ai donc ajouté un peu de code:

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

J'ai donc trois types différents d'arrière-plans de cellules maintenant:

  1. La première colonne de la ligne de données a = Code.AlternateColor ("AliceBlue", "White", True) (C'est la même chose que la réponse précédente.)
  2. Les colonnes restantes de la ligne de données ont = Code.AlternateColor ("AliceBlue", "White", False) (Ceci est également identique à la réponse précédente.)
  3. La première colonne de la ligne de regroupement a = Code.RestartColor ("AliceBlue") (Ceci est nouveau.)
  4. Les colonnes restantes de la ligne de regroupement ont = Code.AlternateColor ("AliceBlue", "White", False) (Cela a été utilisé auparavant, mais aucune mention de celui-ci pour la ligne de regroupement.)

Cela fonctionne pour moi. Si vous voulez que la ligne de regroupement soit non colorée ou d'une couleur différente, il devrait être assez évident de la changer.

N'hésitez pas à ajouter des commentaires sur ce qui pourrait être fait pour améliorer ce code: je suis tout nouveau à la fois dans SSRS et VB, donc je soupçonne fortement qu'il y a beaucoup de place pour l'amélioration, mais l'idée de base semble bonne (et c'était utile pour moi) alors je voulais le jeter ici.

misha
la source
1

J'ai essayé toutes ces solutions sur un tableau matriciel groupé avec des espaces de ligne et aucune n'a fonctionné dans tout le rapport. Le résultat était des lignes colorées en double et d'autres solutions ont donné lieu à des colonnes alternées!

Voici la fonction que j'ai écrite qui a fonctionné pour moi en utilisant un nombre de colonnes:

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

Pour un tableau à 7 colonnes, j'utilise cette expression pour Backcolour de ligne (de cellules):

=Code.AlternateColorByColumnCount("LightGrey","White", 7)
Jeremy Thompson
la source
0

Mes données matricielles contenaient des valeurs manquantes, je n'ai donc pas pu faire fonctionner la solution d'Ahmad, mais cette solution a fonctionné pour moi

L'idée de base est de créer un groupe enfant et un champ sur votre groupe le plus interne contenant la couleur. Définissez ensuite la couleur de chaque cellule de la ligne en fonction de la valeur de ce champ.

FistOfFury
la source
Consultez @ Aditya et ma réponse pour gérer les valeurs manquantes dans la matrice. Utile si vous avez déjà (ou souhaitez créer un faux) groupe de parents. Vous n'aurez pas à créer un champ séparé de cette façon.
rpyzh
0

Légère modification des autres réponses d'ici qui ont fonctionné pour moi. Mon groupe a deux valeurs sur lesquelles regrouper, donc j'ai pu simplement les mettre toutes les deux dans le premier argument avec un + pour qu'il alterne correctement

= Iif ( RunningValue (Fields!description.Value + Fields!name.Value, CountDistinct, Nothing) Mod 2 = 0,"#e6eed5", "Transparent")
Sauce soja Johnson
la source
0

Lors de l'utilisation des deux groupes de lignes et de colonnes, j'ai eu un problème où les couleurs alternaient entre les colonnes même s'il s'agissait de la même ligne. J'ai résolu cela en utilisant une variable globale qui alterne uniquement lorsque la ligne change:

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

Maintenant, dans la première colonne de la ligne que vous souhaitez alterner, définissez l'expression de couleur sur:

= Code.AlternateColor ()

-

Dans les colonnes restantes, définissez-les toutes sur:

= Code.BGColor

Cela devrait faire alterner les couleurs seulement après le dessin de la première colonne.

Cela peut également (de manière non vérifiable) améliorer les performances, car il n'est pas nécessaire de faire un calcul mathématique pour chaque colonne.

Eneerge
la source