将交替的行颜色添加到SQL Server报表服务报表中

将交替的行颜色添加到SQL Server报表服务报表中

Add alternating row color to SQL Server Reporting services report

如何在SQL Server Reporting Services报表中为交替的行加阴影?

编辑:下面列出了许多很好的答案-从快速,简单到复杂而全面。 las,我只能选择一个...


转到表行的BackgroundColor属性,然后选择"表达式..."

使用以下表达式:

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

此技巧可以应用于报告的许多区域。

在.NET 3.5+中,您可以使用:

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

不寻找代表-我只是自己研究了这个问题,并认为我会分享。


当对行进行分组时,使用IIF(RowNumber ...)可能会导致一些问题,另一种选择是使用简单的VBScript函数确定颜色。

这需要付出更多的努力,但是当基本解决方案不够用时,这是一个不错的选择。

基本上,您将代码添加到报表中,如下所示...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

然后在每个单元格上,如下设置BackgroundColor:

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

有关此Wrox文章的完整详细信息


当我使用Catch22的解决方案时,我得到了象棋效果,我想是因为我的矩阵在设计上有多个列。
这种表达对我来说很好:

1
=iif(RunningValue(Fields![rowgroupfield].Value.ToString,CountDistinct,Nothing) Mod 2,"Gainsboro","White")

我已经更改了@ Catch22的解决方案,因为我不喜欢必须更改每个颜色的想法,因此我不喜欢进入每个字段的想法。这在需要更改颜色变量的字段众多的报表中尤其重要。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'*************************************************************************
' -- 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

注意,我已经将功能从接受颜色的功能更改为包含要使用的颜色的功能。

然后在每个字段中添加:

1
=Code.AlternateColor(rownumber(nothing))

这比手动更改每个字段的背景色的颜色要强得多。


我注意到的一件事是,前两种方法都不了解第一行应在组中是什么颜色。该组将从与上一组的最后一行相反的颜色开始。我希望我的组始终以相同的颜色开始...每个组的第一行应始终为白色,而下一行应为彩色。

基本概念是在每个组开始时重置切换,因此我添加了一些代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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

所以我现在有三种不同的细胞背景:

  • 数据行的第一列具有= Code.AlternateColor(" AliceBlue"," White",True)(与上一个答案相同。)
  • 数据行的其余列具有= Code.AlternateColor(" AliceBlue"," White",False)(这也与先前的答案相同。)
  • 分组行的第一列具有= Code.RestartColor(" AliceBlue")(这是新的。)
  • 分组行的其余列具有= Code.AlternateColor(" AliceBlue"," White",False)(以前使用过,但未在分组行中提及。)
  • 这对我有用。如果您希望分组行是无色或不同的颜色,则如何更改它应该很明显。

    请随时添加有关如何改进此代码的注释:我对SSRS和VB都是陌生的,因此我强烈怀疑还有很多改进的余地,但是基本思想似乎是正确的(而且很有用)对我来说),所以我想把它扔在这里。


    对于组页眉/页脚:

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

    您还可以使用它来"重置"每个组中的行颜色计数。我希望每个子组中的第一条详细信息行都以怀特开头,并且此解决方案(当用于详细信息行时)允许发生这种情况:

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

    请参阅:http://msdn.microsoft.com/zh-cn/library/ms159136(v=sql.100).aspx


    Michael Haren的解决方案对我来说很好。但是我收到警告说预览时"透明"不是有效的BackgroundColor。找到了一个快速修复
    在SSRS中设置Report元素的BackgroundColor。不使用任何内容代替"透明"

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

    不使用VB来解决此问题的唯一有效方法是将行分组模值"存储"在行分组内(以及列分组外),并在列分组内显式引用它。我在找到这个解决方案

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

    但是Ankeet并不是最好的解释发生的事情,他的解决方案推荐了不必要的步骤,即在恒定值上创建分组,因此,这是我针对具有单个行组RowGroup1的矩阵的分步过程:

  • 在RowGroup1中创建一个新列。为此,将文本框重命名为RowGroupColor。
  • 将RowGroupColor的文本框的值设置为

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

  • 将所有行单元格的BackgroundColor属性设置为

    "=ReportItems!RowGroupColor.Value"

  • 将RowGroupColor列的宽度设置为0pt并设置CanGrow
    假以将其对客户隐藏。
  • 瞧!这也解决了该线程中提到的许多问题:

    • 自动重置子组:只需为此添加一个新列
      行组,对其组值执行RunningValue。
    • 无需担心True / False切换。
    • 颜色仅保留在一个位置,以方便修改。
    • 可以在行或列组上互换使用(仅将高度设置为0而不是宽度)

    如果SSRS可以公开"文本框上的值"之外的属性,那就太好了。您可以将这种计算填入行组文本框的BackgroundColor属性中,然后在所有其他单元格中将其引用为ReportItems!RowGroup.BackgroundColor。

    嗯,我们可以做梦...


    我的问题是我希望连续的所有列都具有相同的背景。我按行和按列进行分组,并在此处使用前两个解决方案,使第1列中的所有行都带有彩色背景,第2列中的所有行都带有白色背景,第3列中的所有行都带有彩色背景, 等等。好像(Catch22解决方案的)RowNumberbOddRow注意我的列组,而不是忽略它并仅与新行交替。

    我想要的是使第1行中的所有列具有白色背景,然后使第2行中的所有列具有彩色背景,然后使第3行中的所有列具有白色背景,依此类推。我通过使用选定的答案获得了这种效果,但没有传递NothingRowNumber,而是传递了列组的名称,例如

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

    认为这对其他人可能有用。


    我认为这里不讨论此技巧。就是这样

    在任何类型的复杂矩阵中,当您想要交替使用单元格颜色(逐行或逐列)时,
    可行的解决方案是

    如果您想明智地选择其他颜色的细胞,

  • 在报表设计视图的右下角,在"列
    组",在1(使用表达式)上创建一个假的父组,名为
    " FakeParentGroup"。
  • 然后,在报表设计中,为要着色的单元格
    或者,使用以下背景颜色表示
  • =IIF(RunningValue( Fields![ColumnGroupField].Value, countDistinct,"FakeParentGroup" ) MOD 2,"White","LightGrey")

    就这样。

    明智的做法是交替使用颜色行,只是您必须相应地编辑解决方案。

    注意:在这里,有时您需要相应地设置单元格的边框,通常它会消失。

    另外,当您创建假父组时,请不要忘记删除报告中出现的报告中的值1。


    @Aditya的答案很好,但在某些情况下,如果行的第一单元格(用于行背景格式)缺少值(在具有列/行组和值的复杂表格中),则格式设置将被取消。

    @Aditya的解决方案巧妙地利用了runningValue函数的countDistinct结果来识别tablix(行)组中的行号。如果第一个单元格中的Tablix行的值缺失,则runningValue不会增加countDistinct结果,它会返回前一行的编号(因此,将影响该单元格的格式)。为了解决这个问题,您将不得不添加一个附加项来抵消countDistinct值。我的目的是检查行组本身中的第一个运行值(请参见下面的代码片段的第3行):

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

    希望这可以帮助。


    如果整个报表需要交替显示颜色,则可以使用Tablix绑定的数据集作为报表上整个报表范围的标识行号,并在RowNumber函数中使用它。

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

    我在带有行空格的分组Tablix上尝试了所有这些解决方案,但没有一个解决方案适用于整个报表。结果是重复的彩色行,其他解决方案导致交替的列!

    这是我使用列数为我编写的功能:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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

    对于7列Tablix,我将此表达式用于行(单元格)的背景色:

    1
    =Code.AlternateColorByColumnCount("LightGrey","White", 7)

    有人可以在下面的代码中解释从其余字段变为false背后的逻辑(从上面的帖子)

    我注意到的一件事是,前两种方法都不了解第一行应在组中是什么颜色。该组将从与上一组的最后一行相反的颜色开始。我希望我的组始终以相同的颜色开始...每个组的第一行应始终为白色,而下一行应为彩色。

    基本概念是在每个组开始时重置切换,因此我添加了一些代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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

    所以我现在有三种不同的细胞背景:

  • 数据行的第一列具有= Code.AlternateColor(" AliceBlue"," White",True)(与上一个答案相同。)
  • 数据行的其余列具有= Code.AlternateColor(" AliceBlue"," White",False)(这也与先前的答案相同。)
  • 分组行的第一列具有= Code.RestartColor(" AliceBlue")(这是新的。)
  • 分组行的其余列具有= Code.AlternateColor(" AliceBlue"," White",False)(以前使用过,但未在分组行中提及。)
  • 这对我有用。如果您希望分组行是无色或不同的颜色,则如何更改它应该很明显。

    请随时添加有关如何改进此代码的注释:我对SSRS和VB都是陌生的,因此我强烈怀疑仍有很大的改进空间,但是基本思路似乎是合理的(而且很有用)对我来说),所以我想把它扔在这里。


    我的矩阵数据中缺少值,因此无法获得ahmad的解决方案,但该解决方案对我有用

    基本思想是在包含颜色的最里面的组上创建一个子组和字段。然后根据该字段的值为行中的每个单元格设置颜色。


    仅仅因为以上答案似乎都不适合我的矩阵,所以我在这里发布了此内容:

    http://reportingservicestnt.blogspot.com/2011/09/alternate-colors-in-matrixpivot-table.html


    当同时使用行和列组时,我遇到一个问题,即即使是同一行,颜色也会在列之间交替。我通过使用仅在行更改时才更改的全局变量解决了此问题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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

    现在,在要替换的行的第一列中,将颜色表达式设置为:

    =Code.AlternateColor()

    --

    在其余的列中,将它们全部设置为:

    =Code.BGColor

    这应该仅在绘制第一列之后才使颜色交替。

    这也可以(不可验证地)提高性能,因为它不需要为每一列进行数学计算。


    从这里对我有用的其他答案的略微修改。我的小组有两个要分组的值,因此我可以将它们都放在第一个参数中,并带有+号以使其正确交替

    1
    = Iif ( RunningValue (Fields!description.Value + Fields!name.Value, CountDistinct, Nothing) Mod 2 = 0,"#e6eed5","Transparent")

    推荐阅读