提到SSRS 那么就不得不提一下自定义代码的功能,通过自定义代码,有时候可以解决一些比较复杂的问题,比如将让指定的数据行应用指定的属性值。此篇将演示如何通过简单结构的自定义代码进行报表样式的基本设计。

注:此篇虽然演示的是RDLC报表,但是在RDL报表中自定义代码这部分是通用的,没有任何区别。(不得不说我更愿意用RDLC报表这种通过代码提供数据源的方式,虽然有些麻烦但在数据的组织上要更灵活一些。)

首先新建一个ASP.NET WebForm项目,建立一个类文件,里面包含一个DateItem类作为数据容器,此外增加一个DataProvider类提供RDLC报表数据源。

然后创建一个测试asp.net页面承载Report Viewer控件,最后创建一个rdlc报表页面。

最终解决方案目录如下所示:

在asp.net页面中依次放入scriptmanager控件以及ReportViewer控件。

打开rdlc文件,添加数据源,然后按如下设计报表:

在数据源提供者的方法中,加入一些测试数据。

关于创建RDLC报表以及通过代码为报表提供数据源的详细方式,可以参考我的这篇随笔

浏览项目,可以看到报表最初默认的效果。

接下来为报表添加自定义代码丰富这张报表,方法是右键点击报表空白区域,然后点击Report Properties…

在Report Properties界面中,点击Code,在右边的Customer Code输入自定义代码。

添加如下代码:

Public Function ROWDESC(ROWHEADER AS String) AS String

SELECT CASE ROWHEADER

CASE "M": Return "餐费"

CASE "M1": Return "早餐"

CASE "M2": Return "午餐"

CASE "M3": Return "晚餐"

CASE "L": Return "市场"

CASE "L1": Return "蔬菜"

CASE "L2": Return "肉类"

CASE "L3": Return "水果"

CASE "T": Return "交通"

CASE "T1": Return "地铁"

CASE "T2": Return "公交"

CASE "T3": Return "火车"

CASE "T4": Return "飞机"

END SELECT

END Function

这段代码的结构不是很复杂,相信有编程基础的朋友看过一遍就知道是什么意思了。代码主要是SWITCH CASE结构,根据传递进来的Title不同而显示不同的行头。

然后右键点击报表内容的行头,点击菜单中的Expression…

在表达式界面中输入如下代码:

在属性中应用代码的方式就是=Code.方法名。

浏览报表,可以看到报表内容的行头已经根据代码发生了变化。

接下来对报表的边框进行一下特殊的边框设置,比如下面的效果,行头是带有上下边框的,以及汇总行也是带有上下边框的。

这个效果常规方法很难设计出来,但是通过自定义代码就可以轻松搞定。

再为报表添加如下代码:

Public Function UPBORDER(ROWHEADER AS String) AS String

SELECT CASE ROWHEADER

CASE "M": Return "Solid"

CASE "L": Return "Solid"

CASE "T": Return "Solid"

END SELECT

END Function

Public Function DOWNBORDER(ROWHEADER AS String) AS String

SELECT CASE ROWHEADER

CASE "M": Return "Solid"

CASE "L": Return "Solid"

CASE "T": Return "Solid"

CASE "T4": Return "Solid"

END SELECT

END Function

同样也是简单的SWITCH CASE结构,这些代码一个是设置行顶边框的,一个是设置行底边框的,通过判断其Title的属性来决定是否有上边框和下边框。

选中报表内容行,在属性中找到BorderStyle属性集,依次找到Top和 Bottom进行如下设置:

这样就实现了特殊边框的效果。

有时候我们希望汇总行的字体是加粗的,这个也很容易。首先添加下面的代码。

Public Function ISBOLD(ROWHEADER AS String) AS String

SELECT CASE ROWHEADER

CASE "M": Return "Bold"

CASE "L": Return "Bold"

CASE "T": Return "Bold"

END SELECT

END Function

然后将这个代码应用到FontStyle属性中。

浏览报表,可以看到如下效果:

至此,你可以看到通过自定义代码,一些复杂样式的实现就相对容易一些,灵活运用自定义代码,将起到事半功倍的效果,尤其是根据不同的数据行套用不同的样式。

不得不所报表的自定义代码编写起来比编写Javascript还要痛苦,因为它基本上就是一个文本编辑器,没有任何智能感知等辅助代码的功能,所以在编写的时候需要不断去尝试和测试。但总体来说通过自定义代码实现复杂的功能确实要清晰和容易很多。希望RS的下一个版本可以对此功能进行改进。

示例代码下载

玩转SSRS第十篇---自定义代码的更多相关文章

  1. 15天玩转redis —— 第十篇 对快照模式的深入分析

    我们知道redis是带有持久化这个能力了,那到底持久化成到哪里,持久化成啥样呢???这篇我们一起来寻求答案. 一:快照模式 或许在用Redis之初的时候,就听说过redis有两种持久化模式,第一种是S ...

  2. SQL Server Reporting Service(SSRS) 第五篇 自定义数据处理扩展DPE(Data Processing Extension)

    最近在做SSRS项目时,遇到这么一个情形:该项目有多个数据库,每个数据库都在不同的服务器,但每个数据库所拥有的数据库对象(table/view/SPs/functions)都是一模一样的,后来结合网络 ...

  3. 我的MYSQL学习心得(十) 自定义存储过程和函数

    我的MYSQL学习心得(十) 自定义存储过程和函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心 ...

  4. 第十篇 Integration Services:高级事件行为

    本篇文章是Integration Services系列的第十篇,详细内容请参考原文. 简介在前一篇, we introduced fault tolerance by examining method ...

  5. 第十篇 SQL Server安全行级安全

    本篇文章是SQL Server安全系列的第十篇,详细内容请参考原文. 不像一些其他industrial-strength数据库服务,SQL Server缺乏一个内置保护个别数据记录的机制,称为行级安全 ...

  6. Python开发【第二十篇】:缓存

    Python开发[第二十篇]:缓存redis&Memcache   点击这里 Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy ...

  7. 【译】第十篇 SQL Server安全行级安全

    本篇文章是SQL Server安全系列的第十篇,详细内容请参考原文. 不像一些其他industrial-strength数据库服务,SQL Server缺乏一个内置保护个别数据记录的机制,称为行级安全 ...

  8. 【译】第十篇 Integration Services:高级事件行为

    本篇文章是Integration Services系列的第十篇,详细内容请参考原文. 简介在前一篇, we introduced fault tolerance by examining method ...

  9. 跟我学SpringCloud | 第十篇:服务网关Zuul高级篇

    SpringCloud系列教程 | 第十篇:服务网关Zuul高级篇 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特殊说明,本系列教程全 ...

随机推荐

  1. NSOperation

    自定义operation 相比GCD,可以中断任务,也可使用 addDependency,对要执行的任务进行排序.. // // CustomOperation.h // Test // // Cre ...

  2. ndk学习20: jni之OnLoad动态注册函数

    一.原理 当在系统中调用System.loadLibrary函数时,该函数会找到对应的动态库, 然后首先试图找到"JNI_OnLoad"函数,如果该函数存在,则调用它 JNI_On ...

  3. Python统计百分比及排序

    source.txt: 60行 89 91 93 90 92 92 94 92 89 95 93 92 90 92 93 94 94 92 90 92 92 92 ... 统计各个值的百分比,并排序 ...

  4. UIView的一些基本方法 init、loadView、viewDidLoad、viewDidUnload、dealloc

    init方法 在init方法中实例化必要的对象(遵从LazyLoad思想) ‍init方法中初始化ViewController本身 loadView方法 当view需要被展示而它却是nil时,view ...

  5. 【Storage】Ubuntu LVM 安装配置

    参考资料: https://www.centos.bz/2012/02/installation-and-usage-of-lvm/ http://blog.chinaunix.net/uid-206 ...

  6. Python之socket简介

    http://goodcandle.cnblogs.com/archive/2005/12/10/294652.aspx http://yangrong.blog.51cto.com/6945369/ ...

  7. 指针 与 数组 以及 a 与 &a的区别

      指针 与数组 并没有什么关系,   指针就是指针,指针变量在32位系统下,永远占4个byte,其值为某一个内存的地址,指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到;   数组 ...

  8. ffmpeg-20160508-git-bin

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...

  9. CString之GetBuffer与ReleaseBuffer

    我们知道,CString是MFC中提供的方便字符串操作的一个类,非常好使,具有自动动态内存管理功能. GetBuffer()主要作用是将字符串的缓冲区长度锁定: ReleaseBuffer()则是解除 ...

  10. 数据结构-链表逆置(c++模板类实现)

    链表结点类模板定义: template <class T> class SingleList; template <class T> class Node { private: ...