Agregue color de fila alterna al informe de servicios de informes de SQL Server

142

¿Cómo sombrea las filas alternas en un informe de SQL Server Reporting Services?


Editar: Hay un montón de buenas respuestas enumeradas a continuación, desde rápidas y simples hasta complejas y completas . Por desgracia, solo puedo elegir uno ...

Michael Haren
fuente
2
= IIf (RowNumber (Nothing) Mod 2 = 0, "Sin color", "# DDEBF7")
Stefan Steiger
Si selecciona varias celdas, no puede editar las propiedades del cuadro de texto, ¡pero puede acceder al color de relleno en el panel de propiedades y establecer una expresión allí!
kitsu.eb

Respuestas:

213

Vaya a la propiedad BackgroundColor de la fila de la tabla y elija "Expresión ..."

Usa esta expresión:

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

Este truco se puede aplicar a muchas áreas del informe.

Y en .NET 3.5+ podría usar:

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

No busco representante: solo investigué esta pregunta y pensé en compartirla.

Michael Haren
fuente
10
Esto falla bajo ciertas circunstancias, particularmente en tablas y objetos de matriz con muchos subtotales. La respuesta de Catch22 no tiene las mismas limitaciones. Además, el método de Catch22 se puede usar para forzar a las columnas de una matriz a tener colores de columna alternos, lo cual es útil una vez en una luna azul.
Usuario registrado
16
Siempre me aseguro de votar a alguien que responde a su propia pregunta. Con demasiada frecuencia, el autor de la pregunta encuentra una respuesta por su cuenta y luego nunca regresa para publicarla, dejando al resto de nosotros que podrían tener la misma pregunta en la oscuridad. Un golpe para usted, señor.
Matt DiTrolio
44
Cuando uso el código anterior, recibo un mensaje de advertencia como [rsInvalidColor] The value of the BackgroundColor property for the textbox ‘active’ is “Transparent”, which is not a valid BackgroundColor. Parece que sería la expresión correcta =IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", Nothing). Gracias por el consejo.
Russell B
2
Esto da el problema en caso de agrupación y vista de detalles
3
algunos navegadores no pueden manejar "Transparente" o "Nada". La mejor opción sería usar "White"
Nate S.
89

El uso de IIF (RowNumber ...) puede generar algunos problemas cuando se agrupan las filas y otra alternativa es usar una función VBScript simple para determinar el color.

Es un poco más de esfuerzo, pero cuando la solución básica no es suficiente, es una buena alternativa.

Básicamente, agrega código al Informe de la siguiente manera ...

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

Luego, en cada celda, configure el Color de fondo de la siguiente manera:

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

Los detalles completos están en este artículo de Wrox

22 capturas
fuente
El código anterior se agrega a la sección Código del informe o a una página de código subyacente en un proyecto VB.NET, se compila y se implementa como un archivo DLL que se hace referencia como un ensamblado. Recomiendo hacer un esfuerzo adicional para implementar esto como un dll ya que generalmente hace referencia a esto en numerosos informes.
Usuario registrado
Esta es mi forma preferida para manejar el problema de agrupación, después de probar algunos otros hacks. No se descompone cuando se aplica la ordenación interactiva a una columna. +1 y muchas gracias.
Rex Miller
Los colores se compensan cuando tiene un número impar de filas.
K Richard
20
¡No olvide cambiar "Verdadero" a "Falso" para todas las columnas de la fila después de la primera, de lo contrario verá un efecto de tablero de ajedrez! Gracias por la solución, ¡funciona muy bien!
Peter Mularien
Peter Mularien: Tengo este problema, ¿puede explicar cómo solucionarlo?
Ingeniero de software de Bill
65

Obtuve el efecto ajedrez cuando utilicé la solución de Catch22, creo que porque mi matriz tiene más de una columna en diseño. esa expresión funcionó bien para mí:

=iif(RunningValue(Fields![rowgroupfield].Value.ToString,CountDistinct,Nothing) Mod 2,"Gainsboro", "White")
ahmad
fuente
13
Esta respuesta merece mucha más atención: es una solución limpia que funciona perfectamente en una matriz con grupos de filas y grupos de columnas y no requiere ningún código personalizado para funcionar. ¡Hermoso!
Stefan Mohr
9
En realidad, esto funciona bien incluso para varias columnas, pero no si tiene datos "faltantes" en una agrupación. Entonces, si tiene datos que tienen 12 meses de datos en 2007 pero no datos de enero en 2006, y agrupa por mes en filas y año en columnas, la coloración de 2006 se desactivará en uno porque el RunningValue se desincroniza porque aunque haya siendo una caja en la matriz de "enero de 2006" no hay datos en el conjunto de datos y la RunningValue sigue siendo el mismo, no hay cambio de color, etc.
Kyle Hale
2
@ahmad esto está muy cerca. Tengo el problema de que las cajas vacías usan el color opuesto. ¿Cómo me aseguro de que las cajas vacías se coloreen correctamente?
FistOfFury
@KyleHale, ¿tiene una solución para el cuadro que falta para colorear?
FistOfFury
2
@FistOfFury La única solución que conozco es garantizar que se establezca un valor (generalmente 0) para los datos faltantes.
Kyle Hale
20

He cambiado la solución de @ Catch22 un poco, ya que no me gusta la idea de tener que ir a cada campo si decido que quiero cambiar uno de los colores. Esto es especialmente importante en los informes donde hay numerosos campos que necesitarían cambiar la variable de color.

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

Noté que he cambiado la función de una que acepta los colores a una que contiene los colores que se utilizarán.

Luego, en cada campo, agregue:

=Code.AlternateColor(rownumber(nothing))

Esto es mucho más robusto que cambiar manualmente el color en el color de fondo de cada campo.

Michael Eakins
fuente
1
Buena adición a este hilo! Me gusta no tener que configurar "Verdadero" o "Falso" en cada columna. También me gusta la opción de "mod 3" para poder sombrear solo cada 3a fila.
Baodad el
También me gusta esta solución. Sin embargo, no funciona para mí cuando uso la agrupación de filas. Sin embargo, la solución anterior de @ ahmad funcionó para mí.
Baodad
¡Esta es una gran solución para un tablix si no desea agregar campos adicionales a su DataSet!
clamchoda
16

Una cosa que noté es que ninguno de los dos métodos principales tiene noción de qué color debe ser la primera fila en un grupo; el grupo solo comenzará con el color opuesto a la última línea del grupo anterior. Quería que mis grupos siempre comenzaran con el mismo color ... la primera fila de cada grupo siempre debe ser blanca y la siguiente fila coloreada.

El concepto básico era restablecer la palanca cuando se inicia cada grupo, así que agregué un poco 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

Ahora tengo tres tipos diferentes de fondos celulares:

  1. La primera columna de la fila de datos tiene = Code.AlternateColor ("AliceBlue", "White", True) (Esto es lo mismo que la respuesta anterior).
  2. Las columnas restantes de la fila de datos tienen = Code.AlternateColor ("AliceBlue", "White", False) (Esto, también, es lo mismo que la respuesta anterior).
  3. La primera columna de la fila de agrupación tiene = Code.RestartColor ("AliceBlue") (Esto es nuevo).
  4. Las columnas restantes de la fila de agrupación tienen = Code.AlternateColor ("AliceBlue", "White", False) (Esto se utilizó antes, pero no se menciona para agrupar la fila).

Esto funciona para mi. Si desea que la fila de agrupación no tenga color o sea de un color diferente, debería ser bastante obvio a partir de esto cómo cambiarla.

No dude en agregar comentarios sobre lo que podría hacerse para mejorar este código: soy nuevo en SSRS y VB, por lo que sospecho que hay mucho margen de mejora, pero la idea básica parece sólida (y fue útil para mí) así que quería tirarlo aquí.

Beska
fuente
También puede restablecer la numeración de filas para cada grupo como se describe en esta respuesta .
StackOverthrow
10

para encabezados / pies de grupo:

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

También puede usar esto para "restablecer" el recuento de color de fila dentro de cada grupo. Quería que la primera fila de detalles en cada subgrupo comenzara con Blanco y esta solución (cuando se usa en la fila de detalles) permitió que eso sucediera:

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

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

John Saunders
fuente
8

La solución de Michael Haren funciona bien para mí. Sin embargo, recibí una advertencia que decía que "Transparente" no es un Color de fondo válido en la Vista previa. Encontró una solución rápida al establecer elementos de Color de fondo de informe en SSRS . No use nada en lugar de "transparente"

= IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", Nothing)
nonetaku
fuente
Blanco sería mejor que nada.
Nate S.
6

La única forma efectiva de resolver esto sin usar VB es "almacenar" el valor del módulo de agrupación de filas dentro de la agrupación de filas (y fuera de la agrupación de columnas) y hacer referencia explícitamente dentro de su agrupación de columnas. Encontré esta solución en

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

Pero Ankeet no hace el mejor trabajo de explicar lo que está sucediendo, y su solución recomienda el paso innecesario de crear una agrupación en un valor constante, así que aquí está mi proceso paso a paso para una matriz con un solo grupo de filas RowGroup1:

  1. Cree una nueva columna dentro del RowGroup1. Cambie el nombre del cuadro de texto para esto a algo así como RowGroupColor.
  2. Establezca el valor del cuadro de texto RowGroupColor en

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

  3. Establezca la propiedad BackgroundColor de todas sus celdas de fila en

    "=ReportItems!RowGroupColor.Value"

  4. Establezca el ancho de la columna RowGroupColor en 0pt y configure CanGrow en falso para ocultarlo a los clientes.

Voila! Esto también resuelve muchos de los problemas mencionados en este hilo:

  • Restablecimientos automáticos para subgrupos: simplemente agregue una nueva columna para ese grupo de filas, realizando un RunningValue en su valores de grupo.
  • No hay que preocuparse por los conmutadores Verdadero / Falso.
  • Los colores solo se mantienen en un lugar para una fácil modificación.
  • Se puede usar indistintamente en grupos de filas o columnas (solo establezca la altura en 0 en lugar del ancho)

Sería increíble si SSRS exponga propiedades además del valor en cuadros de texto. Simplemente puede rellenar este tipo de cálculo en una propiedad BackgroundColor de los cuadros de texto del grupo de filas y luego hacer referencia a ella como ReportItems! RowGroup.BackgroundColor en todas las demás celdas.

Ahh bueno, podemos soñar ...

Kyle Hale
fuente
5

Mi problema era que quería que todas las columnas seguidas tuvieran el mismo fondo. Agrupé tanto por fila como por columna, y con las dos soluciones principales aquí obtuve todas las filas de la columna 1 con un fondo de color, todas las filas de la columna 2 con un fondo blanco, todas las filas de la columna 3 con un fondo de color , y así. Es como si RowNumberybOddRow (de la solución de Catch22) prestara atención a mi grupo de columnas en lugar de ignorar eso y solo alternando con una nueva fila.

Lo que quería era que todas las columnas de la fila 1 tuvieran un fondo blanco, luego todas las columnas de la fila 2 tuvieran un fondo de color, luego todas las columnas de la fila 3 tuvieran un fondo blanco, y así sucesivamente. Obtuve este efecto usando la respuesta seleccionada, pero en lugar de pasar Nothinga RowNumber, pasé el nombre de mi grupo de columnas, por ejemplo

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

Pensé que esto podría ser útil para otra persona.

Sarah Vessels
fuente
4

Creo que este truco no se discute aquí. Asi que aqui esta,

En cualquier tipo de matriz compleja, cuando desea colores de celda alternativos, ya sea en fila o columna, la solución de trabajo es,

Si desea un color alternativo de las celdas, entonces,

  1. En la esquina inferior derecha de una vista de diseño de informe, en "Grupos de columnas", cree un grupo primario falso en 1 (usando expresión), llamado "FakeParentGroup".
  2. Luego, en el diseño del informe, para las celdas que se van a colorear alternativamente, use la siguiente expresión de color de fondo

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

Eso es todo.

Lo mismo para la fila de color alternativa, solo tiene que editar la solución en consecuencia.

NOTA: Aquí, a veces necesita establecer el borde de las celdas en consecuencia, generalmente desaparece.

Además, no olvide eliminar el valor 1 en el informe que apareció en la imagen cuando creó un grupo de padres falso.

Aditya
fuente
1
¡Esta respuesta es definitivamente un gran hallazgo para aquellos que tienen que crear bandas de fila en tablixes complejos! Si hay un grupo principal existente, úselo. De lo contrario, cree FakeParentGroup. Los valores perdidos en tablixes que tienen grupos de columnas y filas generalmente desechan el formato. Vea mi respuesta que se basa en @ Aditya para tener en cuenta los valores faltantes en la primera celda.
rpyzh
2

Si para todo el informe necesita un color alternativo, puede usar el DataSet al que está vinculado su Tablix para un número de referencia de identidad de todo el informe en el informe y usarlo en la función RowNumber ...

=IIf(RowNumber("DataSet1")  Mod 2 = 1, "White","Blue")
Mate
fuente
2

La respuesta de @ Aditya es excelente, pero hay casos en los que el formato se descartará si la primera celda de la fila (para el formato de fondo de la fila) tiene un valor faltante (en tablixes complejos con grupos de columnas / filas y valores faltantes).

La solución de @Aditya aprovecha inteligentemente el countDistinctresultado de la runningValuefunción para identificar números de fila dentro de un grupo tablix (fila). Si tiene filas de tablix con valor perdido en la primera celda, runningValueno incrementará el countDistinctresultado y devolverá el número de la fila anterior (y, por lo tanto, afectará el formato de esa celda). Para tener en cuenta eso, deberá agregar un término adicional para compensar el countDistinctvalor. Mi decisión fue verificar el primer valor en ejecución en el grupo de filas en sí (consulte la línea 3 del fragmento a continuación):

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

Espero que esto ayude.

rpyzh
fuente
Gracias @rpyzh, esta fue la solución que funcionó para mi grupo de varias filas con un informe de grupo de filas principal común.
Niallty
1

¿Podría alguien explicar la lógica detrás de convertir el resto de los campos en falso en el código a continuación (desde la publicación anterior)

Una cosa que noté es que ninguno de los dos métodos principales tiene noción de qué color debe ser la primera fila en un grupo; el grupo solo comenzará con el color opuesto a la última línea del grupo anterior. Quería que mis grupos siempre comenzaran con el mismo color ... la primera fila de cada grupo siempre debe ser blanca y la siguiente fila coloreada.

El concepto básico era restablecer la palanca cuando se inicia cada grupo, así que agregué un poco 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

Ahora tengo tres tipos diferentes de fondos celulares:

  1. La primera columna de la fila de datos tiene = Code.AlternateColor ("AliceBlue", "White", True) (Esto es lo mismo que la respuesta anterior).
  2. Las columnas restantes de la fila de datos tienen = Code.AlternateColor ("AliceBlue", "White", False) (Esto, también, es lo mismo que la respuesta anterior).
  3. La primera columna de la fila de agrupación tiene = Code.RestartColor ("AliceBlue") (Esto es nuevo).
  4. Las columnas restantes de la fila de agrupación tienen = Code.AlternateColor ("AliceBlue", "White", False) (Esto se utilizó antes, pero no se menciona para agrupar la fila).

Esto funciona para mi. Si desea que la fila de agrupación no tenga color o sea de un color diferente, debería ser bastante obvio a partir de esto cómo cambiarla.

No dude en agregar comentarios sobre lo que podría hacerse para mejorar este código: soy nuevo en SSRS y VB, por lo que sospecho que hay mucho margen de mejora, pero la idea básica parece sólida (y fue útil para mí) así que quería tirarlo aquí.

misha
fuente
1

Probé todas estas soluciones en un Tablix agrupado con espacios de fila y ninguno funcionó en todo el informe. ¡El resultado fue filas de colores duplicados y otras soluciones resultaron en columnas alternas!

Aquí está la función que escribí que funcionó para mí usando un conteo de columnas:

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 un Tablix de 7 columnas, uso esta expresión para el color de fondo de la fila (de celdas):

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

Mis datos de matriz tenían valores faltantes, por lo que no pude lograr que la solución de ahmad funcionara, pero esta solución funcionó para mí

La idea básica es crear un grupo secundario y un campo en su grupo más interno que contenga el color. Luego configure el color para cada celda de la fila en función del valor de ese campo.

Puño de la furia
fuente
Echa un vistazo a @ Aditya y mi respuesta para manejar los valores faltantes en la matriz. Útil si ya tiene (o está dispuesto a crear un grupo de padres falso). No tendrá que crear un campo separado de esa manera.
rpyzh
0

Ligera modificación de otras respuestas desde aquí que funcionó para mí. Mi grupo tiene dos valores para agrupar, así que pude ponerlos a ambos en el primer argumento con un + para que se alternara correctamente

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

Cuando utilicé los grupos de filas y columnas, tuve un problema en el que los colores alternarían entre las columnas a pesar de que era la misma fila. Resolví esto usando una variable global que alterna solo cuando cambia la fila:

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

Ahora, en la primera columna de la fila que desea alternar, establezca la expresión de color en:

= Código.AlternateColor ()

-

En las columnas restantes, configúrelas todas para:

= Código.BGColor

Esto debería alternar los colores solo después de dibujar la primera columna.

Esto también puede mejorar (no verificable), ya que no necesita hacer un cálculo matemático para cada columna.

Eneerge
fuente