向SQL Server Reporting Services报告中添加交替的行颜色


141

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


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


2
= IIf(RowNumber(Nothing)Mod 2 = 0,“无颜色”,“#DDEBF7”)
Stefan Steiger

如果选择多个单元格,则无法编辑文本框属性,但是可以在属性面板中访问填充颜色并在其中设置表达式!
kitsu.eb

Answers:


213

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

使用以下表达式:

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

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

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

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

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


10
这在某些情况下会失败,尤其是在具有大量小计的表和矩阵对象中。Catch22的响应没有相同的限制。同样,Catch22的方法可用于强制矩阵中的列具有交替的列颜色,这在蓝月亮中很有用。
注册用户

16
我总是确保支持回答自己问题的人。提问者经常会自己找到答案,然后再也没有回过头来发布它,而我们其余的人可能在黑暗中有同样的问题。先生,这对你来说是个麻烦。
Matt DiTrolio 2011年

4
当我使用上面的代码时,我收到一条警告消息[rsInvalidColor] The value of the BackgroundColor property for the textbox ‘active’ is “Transparent”, which is not a valid BackgroundColor. ,就像正确的表达式一样=IIf(RowNumber(Nothing) Mod 2 = 0, "Silver", Nothing)。不过,感谢您的提示。
罗素B

2
这使问题在分组的情况和细节视图

3
有些浏览器无法处理“透明”或“无”。最好的选择是使用“白色”
Nate S.

89

当对行进行分组时,使用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文章的完整详细信息


上面的代码可以添加到报表的“代码”部分,也可以添加到VB.NET项目中的代码隐藏页中,然后进行编译和部署为作为程序集引用的DLL。我建议您花更多的精力将其部署为dll,因为您通常会在许多报告中引用它。
注册用户

在尝试了一些其他技巧之后,这是我处理分组问题的首选方式。将交互式排序应用于列时,它不会崩溃。+1,非常感谢。
雷克斯·米勒

当行数奇数时,颜色会偏移。
K理查德2010年

20
不要忘记在第一行之后将行中的所有列的“ True”更改为“ False”,否则您将看到棋盘效果!感谢您的解决方案-效果很好!
Peter Mularien 2011年

彼得·穆拉利安(Peter Mularien):我遇到了这个问题,您能解释一下如何解决吗?
Bill软件工程师

64

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

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

13
这个答案值得更多关注-这是一个干净的解决方案,可以完美地在具有行组和列组的矩阵中工作,并且不需要自定义代码即可工作。美丽!
Stefan Mohr'3

9
实际上,即使对于多列,这也可以正常工作-但如果分组中的数据“丢失”,则不能。因此,如果您的数据在2007年有12个月的数据,而在2006年没有1月份的数据,并且按行和按年分组,那么2006年的颜色将减少一种,因为RunningValue变得不同步,因为即使有仍然在矩阵“2006年1月”一箱有没有数据的数据集和RunningValue保持不变,没有颜色变化等
凯尔·黑尔

2
@ahmad,这是如此接近。我遇到的问题是空盒子使用相反的颜色。我如何确保空盒子上色正确?
FistOfFury

@KyleHale您是否已解决缺少的框颜色问题?
FistOfFury

2
@FistOfFury我知道的唯一解决方案是确保为丢失的数据设置一个值(通常为0)。
凯尔·黑尔

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))

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


1
不错,除了这个线程!我喜欢不必在每一列中设置“ True”或“ False”。我也喜欢“ mod 3”的选项,因此我只能在每第3行加阴影。
Baodad

我也喜欢这种解决方案。但是,当我使用行分组时,它对我不起作用。@ahmad 上面的解决方案虽然对我有用。
Baodad

如果您不希望向数据集添加其他字段,那么这对于tablix是一个很好的解决方案!
clamchoda

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)(以前使用过,但未在分组行中提及。)

这对我有用。如果您希望分组行是无色或不同的颜色,那么如何更改它应该是很明显的。

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


您还可以按照此答案中的说明重置每个组的行编号。
StackOverthrow

10

对于组页眉/页脚:

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

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

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

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


7

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

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

白色总比没有好。
Nate S.

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设置为false,以将其对客户端隐藏。

瞧!这也解决了该线程中提到的许多问题:

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

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

嗯,我们可以做梦...


5

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

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

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

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


4

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

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

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

  1. 在报表设计视图的右下角的“列组”中,在1(使用表达式)上创建一个假父组,名为“ FakeParentGroup”。
  2. 然后,在报表设计中,对于要替换颜色的单元格,请使用以下背景颜色表示

= IIF(RunningValue(Fields![ColumnGroupField] .Value,countDistinct,“ FakeParentGroup”)MOD 2,“白色”,“浅灰色”)

就这样。

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

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

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


1
对于必须在复杂的表格中创建行带的人来说,这个答案绝对是个不错的选择!如果存在现有的父组,请使用它。否则,创建FakeParentGroup。具有列和行组的Tablix中的缺失值通常会导致格式不正确。请参阅基于@Aditya的答案,以解决第一个单元格中的缺失值。
rpyzh 2014年

2

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

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

2

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

@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")

希望这可以帮助。


感谢@rpyzh,这是适用于具有公共父行组Report的多行组的解决方案!
Niallty

1

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

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

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

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)(以前使用过,但未在分组行中提及。)

这对我有用。如果您希望分组行是无色或不同的颜色,那么如何更改它应该是很明显的。

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


1

我在带有行空格的分组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)


0

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

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


查看@Aditya和我的答案来处理矩阵中的缺失值。如果您已经有(或愿意创建一个假的)父组,则很有用。您无需那样创建单独的字段。
rpyzh 2014年

0

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

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

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.