ReportingService 通过RowNumber函数获取行号和生成隔行变色样式
以前一直没有搞明白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函数获取行号和生成隔行变色样式的更多相关文章
- jqGrid根据ID获取行号
根据行号获取ID $('#grid').getCell(rownumber,'id') 根据ID获取行号 $('#' + rowid)[0].rowIndex
- Java基础知识强化之IO流笔记55:IO流练习之 自定义类模拟LineNumberReader的获取行号功能案例
1. 自定义类模拟LineNumberReader的获取行号功能案例 2. 代码实现: (1)MyBufferedReader.java: package cn.itcast_08; import j ...
- Sqlserver获取行号
Sqlserver获取行号 select row_number()over(order by userid )as RowNum,*from OUM_User
- shell脚本,根据字符串获取行号的
awk中不能解析shell变量,建议做法是通过-v传递进去: 1 typeline=`cat $typepath | awk -v str="$typetmp" '/str/{pr ...
- 使用StackTrace堆栈跟踪记录详细日志(可获取行号)
上一篇我们提到使用.NET自带的TraceSource实现简单的日志,具体请看<轻松背后的N+疲惫——系统日志>,这一篇注意想讲的是日志的详细记录,包含请求开始到结束的过程中调用的方法链以 ...
- jquery datatables双击,获取行号。
function dbClickDatatables(rows) { $("#@(Perfix)tbData tbody tr").dblclick(function(e){ de ...
- MySQL查询获取行号rownum
MySQL中可以使用变量产生行号,下面是2个简单例子: 使用工具:MySQL Workbench 说明:表heyf_10中字段,empid(员工工号).deptid(部门编号).salary(薪资): ...
- 有结果集的mysqli函数获取行数和列数
<?php $mysqli=new mysqli("localhost", "root", "123456", "xsphp ...
- asp Gridview绑定形式获取行号
Gridview中使用<%# Container.DataItemIndex %>取得当前行的序号 而在Repeater控件中使用Container.ItemIndex取得当前行的序号 & ...
随机推荐
- hexo 搭建博客
使用hexo搭建网站.记录一下. hexo搭建方法: https://wsgzao.github.io/post/hexo-guide/ http://jacob110.github.io/2015/ ...
- SWD模式连接与注意事项
JTAG模式与SWD模式连接图 SWD 仿真模式概念简述 一.SWD 和传统的调试方式区别 1. SWD 模式比 JTAG 在高速模式下面更加可靠. 在大数据量的情况下面 JTAG 下载程序会失败, ...
- 脚本编程中的test、bash调试、变量计算、参数
脚本编程中的test.bash调试.变量计算.参数 1.文件测试 -e FILE:测试文件是否存在 -f FILE:测试文件是否为普通文件 -d FILE:测试路径是否为目录 -r FILE:测试当前 ...
- 微信支付开发(3) JS API支付
由于微信支付接口更新,本文档已过期,请查看新版微信支付教程.地址 http://www.cnblogs.com/txw1958/category/624506.html 本文介绍如何使用JS API支 ...
- Android ListView自定义Adapter使用误区
参考博客:BaseAdapter中重写getview的心得以及发现convertView回收的机制 使用自定义的BaseAdapter实现LIstView的展示 由于Recycler(反复循环器)的机 ...
- CentOS下netstat + awk 查看tcp的网络连接状态
执行以下命令: #netstat -n | awk ‘/^tcp/ {++state[$NF]} END {for(key in state) print key."\t".sta ...
- box2dweb基础
简介 大名鼎鼎的物理引擎box2d基本上大家都听说过,网上有两个javascript版本的box2d库,一个时box2djs,已经停止维护,一个是box2dweb.下面就来介绍一下box2dweb的基 ...
- Vue.2.0.5-组件
什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能.在 ...
- javascript实例学习之六—自定义日历控件
基于之前上篇博客轻量级jquery,tool.js和base.js.自定义开发的base_datePicker插件,效果类似于jquery_ui的datePicker插件 //基于Base.js以及t ...
- Struts2上传图片时报404错误
可能是struts配置文件中定义的拦截器导致的,后缀拦截导致,将该拦截器去掉,在action类里判断后缀 public String upload()throws Exception{ ActionC ...