以前一直没有搞明白SSRS里面的RowNumber函数到底该怎么用,所以一直没有很好的办法在SSRS中的表格上实现隔行变色的样式,实现隔行变色的关键就是获取表格中每一行的行号。在最近了解了下这个函数,发现RowNumber函数“在某些时候”获取行号还是非常有用的,之所以说“某些时候”是因为RowNumber函数获取的行号实际上是数据集中最小粒度行的行号,这是什么意思呢?意思就是RowNumber函数只能用来计算数据集的行号,如果报表上Tablix(Matrix,Table等控件都是基于Tablix)中分组的粒度比数据集行要大那么RowNumber函数就无能为力了,因为RowNumber永远都是基于数据集中的行来计算行号的,所以其计算出来行号的粒度永远都是和数据集的粒度保持一致。

那么我们现在来看看RowNumber函数的概念,RowNumber函数使用的时候要传一个参数,参数就是数据范围(Scope)的名称,SSRS中数据范围(Scope)一般指的就是行组、列组、数据集等可以划分数据范围的数据结构,RowNumber函数在运行的时候会根据当前所在的数据范围迭代过的记录来计算数据集中的行计数,从而生成行号,而RowNumber函数参数是用来指定重置行计数的数据范围的。前面这句话说的很抽象不好理解,下面我们通过图文结合方式来详细介绍下RowNumber函数的使用以方便理解。

假设我们现在的报表上有一个数据集叫DBSet用来获取数据库中的数据

然后我们在报表上定义了一个Matrix用来展示数据集DBSet中的数据,我们只用到了Matrix的一个行组(行组名DateID),该行组通过数据集DBSet字段DateID来分组,而字段DateID的粒度也是数据集DBSet的最小粒度,也就是说在数据集DBSet中字段DateID每一行的值都是不同的。

然后我们在Matrix上定义了一列Row Number用于显示当前行的行号,行号通过我们本文中所述的RowNumber函数来生成,RowNumber函数的参数是设置的数据集DBSet的名称,所以RowNumber函数的行计数范围是整个数据集,行计数在Matrix上永远都不会被重置。

而上图中RowNumber函数是位于行组DateID中的单元格内的,所以RowNumber函数当前所在的数据范围就是行组DateID,所以RowNumber函数会根据行组DateID的迭代范围来做数据集的行计数,我们来看看运行报表的结果:

在上图中我们看到,当列Date为20100101时,Matrix中行组DateID只迭代过数据集中一行数据,所以这时RowNumber函数返回的结果是1。当Date为20100102时,Matrix中行组DateID迭代过的DateID值为20100101、20100102,所以行组DateID的当前迭代包含数据集中的两行数据,所以RowNumber函数返回的结果是2。而当Date为20100103时,Matrix中行组DateID迭代过的DateID值为20100101、20100102、20100103,所以行组DateID的当前迭代包含数据集中的三行数据,所以RowNumber函数返回的结果是3。以此类推所以RowNumber函数在行组DateID上每一行的迭代就生成了整个Matrix的行号。

在上面这个例子中我们了解到了RowNumber函数可以用来生成行号,但是RowNumber函数的参数可以用来做什么并没有很好地被体现出来。我们将上面的例子稍作修改如下,我们在行组DateID上添加了一个父组叫YearMonth,根据数据集中的字段YearMonth来进行分组,字段YearMonth的粒度要比DateID大,所以在数据集DBSet中字段YearMonth和字段DateID是一对多关系,也就是说一个YearMonth值包含多行DateID记录。

紧接着我们将列Row Number的表达式改为了RowNumber("YearMonth"),我们将RowNumber函数的参数指定为了Matrix的行组YearMonth,那么根据我们上面所述,现在RowNumber函数会根据行组YearMonth的迭代值来进行行计数重置,当行组YearMonth的迭代值发生变化的时候RowNumber函数的行计数会清0。

根据上图的修改,我们再次运行报表结果如下,我们可以看到RowNumber函数返回的行计数在行组YearMonth的值变化后又从1开始了,印证了我们上面所说的当RowNumber函数参数指定的数据范围的迭代值发生变化后RowNumber函数的行统计被清0了。

在本文开始的时候我们说了RowNumber函数是在“在某些时候”可以用来获取行号,上面的例子中Matrix的最小粒度也就是行组DateID的粒度,而DateID的粒度和数据集DBSet的粒度刚好一致,所以用RowNumber函数来返回行号是没有问题的,也就是我们本文中提到的“在某些时候”。但是如果Matrix的最小粒度要比数据集DBSet的粒度要大,那么用RowNumber函数来返回行号就是不行的了,现在我们将上面的例子再稍作修改如下:

我们删除了行组DateID只留下了行组YearMonth,那么现在Matrix的最小粒度就是行组YearMonth了,然后我们将列Row Number的表达式改回RowNumber("DBSet"),那么RowNumber函数的行计数重置范围又变回整个数据集了,行计数在整个Matrix上不会被清0。运行报表我们查看到结果如下:

可以看到每一行的行计数都不正确了,为什么会出现这样的结果呢?我们来分析下,RowNumber函数当前所在的数据范围就是行组YearMonth,所以RowNumber函数会根据行组YearMonth的迭代范围来做数据集的行计数。当行组YearMonth等于201001的时候,行组YearMonth迭代了数据集中31行数据,所以RowNumber函数返回值31。当行组YearMonth等于201002的时候,行组YearMonth迭代了数据集中YearMonth为201001、201002的数据集行总共59行数据,所以RowNumber函数返回值59。当行组YearMonth等于201003的时候,行组YearMonth迭代了数据集中YearMonth为201001、201002、201003的数据集行总共90行数据,所以RowNumber函数返回值90。以此类推行组YearMonth的每一次迭代都会把从201001到当前行包含的数据集行数作为RowNumber函数的返回值,所以就有了上图中报表运行的结果。所以我们在使用RowNumber函数的时候一定要确保Tablix中的最小粒度要和数据集的粒度保持一致,否则统计出来的行号就会像上图一样是完全错误的。

正确使用RowNumber函数生成行号就可以设置报表为隔行变色的效果:

ReportingService 通过RowNumber函数获取行号和生成隔行变色样式的更多相关文章

  1. jqGrid根据ID获取行号

    根据行号获取ID $('#grid').getCell(rownumber,'id') 根据ID获取行号 $('#' + rowid)[0].rowIndex

  2. Java基础知识强化之IO流笔记55:IO流练习之 自定义类模拟LineNumberReader的获取行号功能案例

    1. 自定义类模拟LineNumberReader的获取行号功能案例 2. 代码实现: (1)MyBufferedReader.java: package cn.itcast_08; import j ...

  3. Sqlserver获取行号

    Sqlserver获取行号   select row_number()over(order by userid )as RowNum,*from OUM_User

  4. shell脚本,根据字符串获取行号的

    awk中不能解析shell变量,建议做法是通过-v传递进去: 1 typeline=`cat $typepath | awk -v str="$typetmp" '/str/{pr ...

  5. 使用StackTrace堆栈跟踪记录详细日志(可获取行号)

    上一篇我们提到使用.NET自带的TraceSource实现简单的日志,具体请看<轻松背后的N+疲惫——系统日志>,这一篇注意想讲的是日志的详细记录,包含请求开始到结束的过程中调用的方法链以 ...

  6. jquery datatables双击,获取行号。

    function dbClickDatatables(rows) { $("#@(Perfix)tbData tbody tr").dblclick(function(e){ de ...

  7. MySQL查询获取行号rownum

    MySQL中可以使用变量产生行号,下面是2个简单例子: 使用工具:MySQL Workbench 说明:表heyf_10中字段,empid(员工工号).deptid(部门编号).salary(薪资): ...

  8. 有结果集的mysqli函数获取行数和列数

    <?php $mysqli=new mysqli("localhost", "root", "123456", "xsphp ...

  9. asp Gridview绑定形式获取行号

    Gridview中使用<%# Container.DataItemIndex %>取得当前行的序号 而在Repeater控件中使用Container.ItemIndex取得当前行的序号 & ...

随机推荐

  1. 玩转HTML5移动页面

    (1) 动画雪碧图涉及的动画十分多,用的元素也十分多,请务必使用雪碧图(Sprite)!网上的工具有一些可以帮助你生成雪碧图的工具,例如CssGaga,GoPng等等,自动化构建工具Grunt和Gul ...

  2. ios runtime swizzle

    ios runtime swizzle @implementation NSObject(Extension) + (void)swizzleClassMethod:(Class)class orig ...

  3. C语言的内存管理

    C语言的内存管理 转载:http://blog.csdn.net/wind19/article/details/5964090   对于一个C语言程序而言,内存空间主要由五个部分组成代码段(.text ...

  4. Web开发学习

    这几天天天学习网络开发的一些东西,接触了好些概念.原本打算自己弄个个人博客,BlogEngine.net已经做的很好了,可以直接拿来用而且源码开放.做的很不错,是WebForm的.本来打算好好学习一下 ...

  5. 用仿ActionScript的语法来编写html5——第七篇,自定义按钮

    第七篇,自定义按钮这次弄个简单点的,自定义按钮.其实,有了前面所定义的LSprite,LBitmap等类,定义按钮就很方便了.下面是添加按钮的代码, function gameInit(event){ ...

  6. linux gitlab nginx 安装 配置

    更新:bitnami-gitlab 7.8版本后界面发生变化 邮件问题: cd /data/server/gitlab/apps/gitlab/htdocs/config vim environmen ...

  7. C#资源文件和C#枚举如何结合使用?

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来.我们都知道计算机技术发展日新月异,速度惊人的快,你我稍不留神,就会被慢慢淘汰!因此:每日不间断的学习是避免被 ...

  8. JQuery-UI Dialog下使用服务器端按钮失效

    目标:点按钮弹出div层,选择数据后自动隐藏div,将所选数据赋值到窗体. <div id="divWinPop"> //里面是要实现弹出框的代码,包括翻页.查找等. ...

  9. mysql导sql脚本

    在navicat或sql yog ,或dos窗口中,如下 命令 ->mysql source d:\test.sql;

  10. TIJ——Chapter One:Introduction to Objects

    ///:~容我对这个系列美其名曰"读书笔记",其实shi在练习英文哈:-) Introduction to Objects Object-oriented programming( ...