以前一直没有搞明白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. [LeetCode]题解(python):034-Search for a Range

    题目来源 https://leetcode.com/problems/search-for-a-range/ Given a sorted array of integers, find the st ...

  2. net Datable 基本操作

    net Datable 基本操作 using System; using System.Collections.Generic; using System.Text; using System.Dat ...

  3. 个人常用iOS第三方库以及XCode插件介绍

    第三方库 CocoaPod CocoaPod并不是iOS上的第三方库 而是大名鼎鼎的第三方库的管理工具 在CocoaPod没有出现之前 第三方库的管理是非常痛苦的 尤其是一些大型的库(比如nimbus ...

  4. CFBundleVersion与CFBundleShortVersionString

    CFBundleVersion,标识(发布或未发布)的内部版本号.这是一个单调增加的字符串,包括一个或多个时期分隔的整数. CFBundleShortVersionString  标识应用程序的发布版 ...

  5. 做SSH练习的时候,JUunit运行遇到报错信息

    提示说是applicationcontext文件中的jdbcUrl信息错误,可是xml文件中的url再三确认是没有错的,不知道怎么回事? 最下面贴上applicationContext.xml中的数据 ...

  6. [BS-21] 关于OC中对象与指针的思考

    关于OC中对象与指针的思考 1. 创建对象: OC中可通过代码Person *p = [[Person alloc] init];创建了一个对象p.该过程中内存情况为: 在当前线程的栈(默认1M)中, ...

  7. Trace-导出已有的服务器端跟踪

    跟踪(Trace)常被我们用来检查性能问题.通常我们会有针对CPU.Duration.Reads的创建跟踪定义,这一类的脚本一般不会包含太多的事件和列,筛选条件也相对简单.假如某一天你使用GUI定义了 ...

  8. 错过C++

    曾相识的C++--2008年那是还在学校,接触到了这门语言,可遗憾的是当时,自己没有能静下心好好学习这门语言.所以相识了了半年的c++就这样不见. 如今又相逢,但已经感觉到很陌生,陌生的我们互补相认.

  9. 前端bower使用

    Bower是一个客户端技术的软件包管理器,是由twitter推出的.它可用于搜索.安装和卸载如JavaScript.HTML.CSS之类的网络资源.其他一些建立在Bower基础之上的开发工具,如Yeo ...

  10. Dropbox能火,为何它的中国同行不能火?

    http://tech.163.com/15/0510/11/AP8II63H000915BF.html Dropbox能火,为何它的中国同行不能火? 2015-05-10 11:33:55 来源:  ...