如何在 SQL Server Reporting Services 报表中对交替行进行着色?
18 回答
转到表格行的 BackgroundColor 属性并选择“Expression...”
使用这个表达式:
= IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", "Transparent")
这个技巧可以应用于报告的许多领域。
在 .NET 3.5+ 中,您可以使用:
= If(RowNumber(Nothing) Mod 2 = 0, "Silver", "Transparent")
不寻找代表——我只是自己研究了这个问题,并认为我会分享。
在对行进行分组时,使用 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 文章中
当我使用 Catch22 的解决方案时,我得到了象棋效果,我认为是因为我的矩阵在设计中不止一列。这个表达对我来说很好:
=iif(RunningValue(Fields![rowgroupfield].Value.ToString,CountDistinct,Nothing) Mod 2,"Gainsboro", "White")
我已经更改了@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))
这比手动更改每个字段的背景颜色的颜色要强大得多。
我注意到的一件事是,前两种方法都没有任何关于组中第一行应该是什么颜色的概念。该组将以与前一组的最后一行相反的颜色开始。我希望我的组总是以相同的颜色开始......每组的第一行应该始终是白色的,下一行应该是彩色的。
基本概念是在每个组开始时重置切换,所以我添加了一些代码:
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 都是全新的,所以我强烈怀疑还有很大的改进空间,但基本想法似乎是合理的(而且很有用对我来说)所以我想把它扔在这里。
对于组页眉/页脚:
=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
Michael Haren 的解决方案对我来说很好。但是我收到警告说“透明”在预览时不是有效的背景颜色。从Setting BackgroundColor of Report elements in SSRS 中找到快速修复 。不使用任何东西而不是“透明”
= 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 设置为 false 以对客户端隐藏它。
瞧!这也解决了这个线程中提到的很多问题:
- 子组的自动重置:只需为该行组添加一个新列,对其组值执行 RunningValue 。
- 无需担心真/假切换。
- 颜色只保留在一个地方,以便于修改。
- 可以在行组或列组上互换使用(只需将高度设置为 0 而不是宽度)
如果 SSRS 能够在 Textboxes 上公开除 Value 之外的属性,那就太棒了。您可以将这种计算填充到行组文本框的 BackgroundColor 属性中,然后在所有其他单元格中将其作为 ReportItems!RowGroup.BackgroundColor 引用。
啊,好吧,我们可以做梦……
我的问题是我希望一行中的所有列都具有相同的背景。我按行和按列分组,在这里使用前两个解决方案,我得到第 1 列中的所有行都有彩色背景,第 2 列中的所有行都有白色背景,第 3 列中的所有行都有彩色背景, 等等。就好像RowNumber
和bOddRow
(Catch22 的解决方案)注意我的列组,而不是忽略它,只与新行交替。
我想要的是第 1 行中的所有列都具有白色背景,然后第 2 行中的所有列具有彩色背景,然后第 3 行中的所有列具有白色背景,依此类推。我通过使用选定的答案获得了这种效果,但我没有传递Nothing
给RowNumber
,而是传递了我的列组的名称,例如
=IIf(RowNumber("MyColumnGroupName") Mod 2 = 0, "AliceBlue", "Transparent")
认为这可能对其他人有用。
我认为这里不讨论这个技巧。所以这里,
在任何类型的复杂矩阵中,当您想要交替的单元格颜色时,无论是逐行还是逐列,工作解决方案是,
如果你想要一种不同颜色的单元格,那么,
- 在报表设计视图的右下角,在“Column Groups”中,在 1(使用表达式)上创建一个假父组,命名为“FakeParentGroup”。
- 然后,在报表设计中,对于要交替着色的单元格,使用以下背景颜色表达式
=IIF(RunningValue(字段![ColumnGroupField].Value,countDistinct,“FakeParentGroup”)MOD 2,“白色”,“浅灰色”)
就这样。
对于备用颜色行也是如此,只是您必须相应地编辑解决方案。
注意:在这里,有时您需要相应地设置单元格的边框,通常它会消失。
当您创建假父组时,不要忘记删除进入图片的报告中的值 1。
如果对于整个报告,您需要交替颜色,则可以使用 Tablix 绑定到的 DataSet 作为报告上的报告范围标识行号,并在 RowNumber 函数中使用它...
=IIf(RowNumber("DataSet1") Mod 2 = 1, "White","Blue")
@Aditya 的答案很好,但在某些情况下,如果行的第一个单元格(用于行背景格式)有缺失值(在具有列/行组和缺失值的复杂 tablixes 中),格式将被丢弃。
@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")
希望这可以帮助。
有人可以在下面的代码中解释将其余字段变为假的逻辑(来自上面的帖子)
我注意到的一件事是,前两种方法都没有任何关于组中第一行应该是什么颜色的概念。该组将以与前一组的最后一行相反的颜色开始。我希望我的组总是以相同的颜色开始......每组的第一行应该始终是白色的,下一行应该是彩色的。
基本概念是在每个组开始时重置切换,所以我添加了一些代码:
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 都是全新的,所以我强烈怀疑还有很大的改进空间,但基本想法似乎是合理的(而且很有用对我来说)所以我想把它扔在这里。
我在带有行空间的 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,我将此表达式用于行(单元格)背景色:
=Code.AlternateColorByColumnCount("LightGrey","White", 7)
只是因为上面的答案似乎都不适用于我的矩阵,所以我在这里发布:
http://reportingservicestnt.blogspot.com/2011/09/alternate-colors-in-matrixpivot-table.html
我的矩阵数据中有缺失值,所以我无法让 ahmad 的解决方案起作用,但这个解决方案对我有用
基本思想是在包含颜色的最里面的组上创建一个子组和字段。然后根据该字段的值设置行中每个单元格的颜色。
从这里对我有用的其他答案稍作修改。我的组有两个要分组的值,因此我可以将它们都放在第一个 arg 中,并带有 + 以使其正确交替
= Iif ( RunningValue (Fields!description.Value + Fields!name.Value, CountDistinct, Nothing) Mod 2 = 0,"#e6eed5", "Transparent")
当同时使用行组和列组时,我遇到了一个问题,即颜色会在列之间交替,即使它是同一行。我通过使用仅在行更改时交替的全局变量来解决此问题:
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()
-
在其余列中,将它们全部设置为:
=代码.BGColor
这应该使颜色仅在绘制第一列后才交替。
这也可能(无法验证)提高性能,因为它不需要对每一列进行数学计算。