SQL Server Report Builder 2.0中使用custom code实现sum distinct

有时在报表中,我们会将在数据库中具主从关系的两个表(head 和 detail)的数据统一放在一行里显示,即既有主表(detail)的数据,又有从表(head)的数据。这个时候,如果我们需要对从表的某一个数值进行求和,则不能简单地使用sum,因为从表数据有可能根据其对应的主表有多行也显示成了多行,这个时候如果简单计和,则很明显有重复的数据。

 

举例说明:

 

主表为学生信息:学生编号、学生姓名、辅导老师编号;

从表为老师信息:老师编号、老师姓名、工资;

 

在一个辅导老师需要辅导多名学生的前提下,假设我们的报表格式为:

辅导老师姓名、工资、学生姓名

 

那么同一个老师的数据将在多行出现,这个时候如果要计算全校老师的工资总和,则需要使用sum( 工资, distinct 老师编号)这种格式。

 

然而,在SQL Server Report Builder 2.0中,本身的系统函数不能对数据根据某一列或多列先进行distinct再求和,我们需要通过custom code来实现。

 

在report的属性对话框中的Code区域,我们写上:

 

   Private _DistinctTotal As System.Collections.Generic.Dictionary(Of String, Decimal)

   Private ReadOnly Property DistinctTotal() As System.Collections.Generic.Dictionary(Of String, Decimal)

       Get

           If (_DistinctTotal Is Nothing) Then

               _DistinctTotal = New System.Collections.Generic.Dictionary(Of String, Decimal)

           End If

           Return _DistinctTotal

       End Get

   End Property

   Public Function GetDistinctTotal(ByVal oid As String, ByVal amount As Decimal) As Decimal

       If (Not Me.DistinctTotal.ContainsKey(oid)) Then

           Me.DistinctTotal.Add(oid, amount)

           Return amount

       Else

           Return 0

       End If

   End Function

 

然后在计总和的字段的值表达式里写上:

=Sum( code.GetDistinctTotal( Fields!老师编号.Value, Fields!工资.Value))

 

这样,结果就符合我们的需求了。

 

如果你的报表分了多个组,比如上述报表按科目来对老师的工资汇总,格式如下:

 

语文、语文辅导老师工资总和

辅导老师姓名、工资、学生姓名

 

数学、数学辅导老师工资总和

辅导老师姓名、工资、学生姓名

 

生物、生物辅导老师工资总和

……

 

然后每一组需要计一次和,如果有的老师既辅导语文也辅导数学,那么仅按老师编号来distinct显然是不对的,因为变量_DistinctTotal As System.Collections.Generic.Dictionary是全局作用域的,如果在语文组中该老师已经计算了工资的话,在数学组中GetDistinctTotal函数将返回0,因此,我们在汇总的时候还应该加上科目组别进行distinct:

 

=Sum( code.GetDistinctTotal( Fields!科目组别.Value & Fields!老师编号.Value, Fields!工资.Value))

//可以不需要另设参数,只需要叠加起来,仍然作为一个参数即可。

 

依此类推,如果有多个分组需要distinct来计和,只需要依次添加分组字段到第一个参数即可(如果存在空值,则需转换成空字符,或者依分组的相应逻辑处理)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值