将交替行颜色添加到SQL Server Reporting服务报告

时间:2008-09-04 18:18:33

标签: sql-server reporting-services formatting

如何在SQL Server Reporting Services报告中对交替的行进行着色?


修改:下面列出了一系列优秀答案 - 从quicksimplecomplex and comprehensive。唉,我只能选一个......

18 个答案:

答案 0 :(得分:212)

转到表格行的BackgroundColor属性并选择“Expression ...”

使用此表达式:

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

这个技巧可以应用于报告的许多方面。

在.NET 3.5+中你可以使用:

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

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

答案 1 :(得分:87)

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

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

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

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:

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

详细信息请参见Wrox article

答案 2 :(得分:64)

当我使用Catch22的解决方案时,我得到了国际象棋效果,我认为因为我的矩阵在设计中有不止一列。 那个表达对我很好:

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

答案 3 :(得分:20)

我已经改变了@ Catch22的解决方案有点因为如果我决定改变其中一种颜色,我不喜欢进入每个领域的想法。这在需要更改颜色变量的众多字段的报告中尤为重要。

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

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

然后在每个字段中添加:

=Code.AlternateColor(rownumber(nothing))

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

答案 4 :(得分:16)

我注意到的一件事是,前两种方法都没有任何关于组中第一行应该是什么颜色的概念;该组将以与前一组的最后一行相反的颜色开始。我希望我的小组始终以相同的颜色开始......每组的第一行应始终为白色,下一行应为彩色。

基本概念是在每个组启动时重置切换,所以我添加了一些代码:

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

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

  1. 数据行的第一列= Code.AlternateColor(“AliceBlue”,“White”,True)(这与上一个答案相同。)
  2. 剩余的数据行列= Code.AlternateColor(“AliceBlue”,“White”,False)(这也与上一个答案相同。)
  3. 分组行的第一列= Code.RestartColor(“AliceBlue”)(这是新的。)
  4. 分组行的剩余列= = Code.AlternateColor(“AliceBlue”,“White”,False)(之前使用过,但没有提及它用于分组行。)
  5. 这对我有用。如果您希望分组行是非彩色的,或者是不同的颜色,那么从中可以很明显地改变它。

    请随意添加关于可以采取哪些措施来改进此代码的评论:我对SSRS和VB都是全新的,所以我强烈怀疑还有很大的改进空间,但基本的想法似乎是合理的(和它对我很有用)所以我想把它扔出去。

答案 5 :(得分:10)

用于组页眉/页脚:

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

您还可以使用它来“重置”每个组中的行颜色计数。我希望每个子组中的第一个细节行以White开头,这个解决方案(在详细行上使用时)允许这样做:

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

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

答案 6 :(得分:7)

迈克尔哈伦的解决方案对我来说很好。但是我收到一条警告说“透明”在预览时不是有效的BackgroundColor。找到了快速解决方案 Setting BackgroundColor of Report elements in SSRS。使用Nothing而不是“Transparent”

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

答案 7 :(得分:6)

在不使用VB的情况下解决此问题的唯一有效方法是在行分组(以及列分组外)中“存储”行分组模数值,并在列分组中明确引用它。我在

找到了这个解决方案

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

但Ankeet并不是解释正在发生的事情的最佳工作,他的解决方案建议在常量值上创建分组的不必要步骤,所以这是我对具有单个行组RowGroup1的矩阵的逐步过程:

  1. 在RowGroup1中创建一个新列。将文本框重命名为RowGroupColor。
  2. 将RowGroupColor的文本框的值设置为

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

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

    "=ReportItems!RowGroupColor.Value"

  4. 将RowGroupColor列的宽度设置为0pt并设置CanGrow 为了将其隐藏起来,将其隐藏起来。
  5. 瞧!这也解决了这个帖子中提到的很多问题:

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

    如果SSRS会暴露除Textboxes上的Value之外的属性,那将是非常棒的。您可以在行组文本框的BackgroundColor属性中填充此类计算,然后在所有其他单元格中将其作为ReportItems!RowGroup.BackgroundColor引用。

    啊,好吧,我们可以做梦......

答案 8 :(得分:5)

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

我想要的是第1行中的所有都有白色背景,然后第2行中的所有列都有彩色背景,然后第3行中的所有列都有白色背景,等等。我通过使用所选答案获得了此效果,但我没有将Nothing传递给RowNumber,而是传递了我的列组名称,例如

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

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

答案 9 :(得分:4)

我认为这里不讨论这个技巧。所以在这里,

在任何类型的复杂矩阵中,当您想要交替的单元格颜色时,无论是行式还是列式, 工作解决方案是,

如果你想要另一种颜色的单元格,那么,

  1. 在报表设计视图的右下角,在“列”中 组“,在1上创建一个假父组(使用表达式),命名为 “FakeParentGroup”。
  2. 然后,在报告设计中,对于要着色的细胞 或者,使用以下背景颜色表达
  3.   

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

    多数人。

    相同的替代颜色行,只需要相应地编辑解决方案。

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

    同样不要忘记在创建虚假父组时在图片中删除值1。

答案 10 :(得分:2)

如果整个报表需要交替颜色,则可以使用Tablix绑定的DataSet作为报表的报表范围标识rownumber,并在RowNumber函数中使用...

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

答案 11 :(得分:2)

@Aditya的答案很棒,但是如果行的第一个单元格(用于行背景格式化)具有缺失值(在具有列/行组和缺失值的复杂Tablix中),则存在格式化将被抛弃的情况

@ Aditya的解决方案巧妙地利用countDistinct函数的runningValue结果来识别Tablix(行)组中的行号。如果第一个单元格中的Tablix行缺少值,runningValue将不会增加countDistinct结果,并且它将返回上一行的数字(因此,将影响该单元格的格式)。要考虑到这一点,您必须添加一个额外的术语来抵消countDistinct值。我的看法是检查行组本身的第一个运行值(参见下面代码段的第3行):

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

希望这有帮助。

答案 12 :(得分:1)

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

我注意到的一件事是,前两种方法都没有任何关于组中第一行应该是什么颜色的概念;该组将以与前一组的最后一行相反的颜色开始。我希望我的小组始终以相同的颜色开始......每组的第一行应始终为白色,下一行应为彩色。

基本概念是在每个组启动时重置切换,所以我添加了一些代码:

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

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

  1. 数据行的第一列= Code.AlternateColor(“AliceBlue”,“White”,True)(这与上一个答案相同。)
  2. 剩余的数据行列= Code.AlternateColor(“AliceBlue”,“White”,False)(这也与上一个答案相同。)
  3. 分组行的第一列= Code.RestartColor(“AliceBlue”)(这是新的。)
  4. 分组行的剩余列= = Code.AlternateColor(“AliceBlue”,“White”,False)(之前使用过,但没有提及它用于分组行。)
  5. 这对我有用。如果您希望分组行是非彩色的,或者是不同的颜色,那么从中可以很明显地改变它。

    请随意添加关于可以采取哪些措施来改进此代码的评论:我对SSRS和VB都是全新的,所以我强烈怀疑还有很大的改进空间,但基本的想法似乎是合理的(和它对我很有用)所以我想把它扔出去。

答案 13 :(得分:1)

我在带有行空格的Grouped Tablix上尝试了所有这些解决方案,并且没有一个在整个报表中都有效。结果是重复的彩色行和其他解决方案导致交替列!

这是我编写的函数,它使用了一个列数:

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,我将此表达式用于Row(of Cells)Backcolour:

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

答案 14 :(得分:0)

我的矩阵数据中缺少值,因此我无法获得ahmad的解决方案,但是this solution worked for me

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

答案 15 :(得分:0)

因为上面的答案似乎都没有在我的矩阵中起作用,我在这里发布:

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

答案 16 :(得分:0)

Slight modification of other answers from here that worked for me. My group has two values to group on, so I was able to just put them both in the first arg with a + to get it to alternate correctly

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

答案 17 :(得分:0)

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

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

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

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