如何从带行组列组的SSRS报表中获取列值并传入VB.NET DLL做CPK计算
解决方案
步骤1:编译符合SSRS要求的VB.NET DLL
- 你的VB.NET类库需要设置强名称签名,SSRS要求自定义程序集必须有强名称才能被信任加载,操作路径是项目属性→签名→勾选「为程序集签名」,选择或新建强名称密钥文件
- 公开的CPK计算方法需要声明为
Shared静态方法,入参设置为Double()或者Object()类型的数组用来接收单组列的所有数值,返回值设置为Double类型输出CPK计算结果,示例代码框架如下:
Public Class CPKCalculator Public Shared Function CalculateCPK(data As Double(), USL As Double, LSL As Double) As Double ' 此处写入你已实现的CPK计算逻辑 Dim avg As Double = data.Average() Dim std As Double = data.AsEnumerable().StdDev() Dim cpu As Double = (USL - avg) / (3 * std) Dim cpl As Double = (avg - LSL) / (3 * std) Return Math.Min(cpu, cpl) End Function End Class
步骤2:SSRS报表配置自定义程序集引用
- 打开SSRS报表的「报表属性」窗口,切换到「引用」选项卡
- 在「添加程序集」区域选择你编译好的DLL文件,填入程序集的强名称信息(包括版本、公钥令牌)
- 若调用时出现权限报错,可在「报表属性」的「代码」选项卡或者SSRS服务器的策略配置文件中,给该DLL授予
FullTrust权限。
步骤3:收集列组对应的数据数组并调用计算
针对行组+列组的透视表结构,你可以直接在列汇总区域调用方法计算单列CPK:
- 用SSRS内置的
LookupSet函数收集当前列对应的所有原始数据,转换成数组后传入DLL方法即可 - 表达式示例如下,假设你的数据集名称为
ProductionData,列组的分组字段是SpecName,数值字段是MeasureValue,上下限分别为参数@USL和@LSL:=YourNamespace.CPKCalculator.CalculateCPK(LookupSet(Fields!SpecName.Value, Fields!SpecName.Value, Fields!MeasureValue.Value, "ProductionData"), Parameters!USL.Value, Parameters!LSL.Value) - 若需要全局多列的CPK汇总计算,你可以在报表的自定义代码块中先遍历所有行数据,按列组字段分类存储到不同数组变量中,需要调用时直接传入对应数组即可。
注意事项
- 传入数组前需要先过滤空值、异常值,避免DLL计算时报错,你可以在SSRS表达式中先对
LookupSet返回的结果做过滤,也可以在VB.NET的计算方法中加入入参校验逻辑 - 如果DLL入参要求为Double类型数组,你可以在自定义代码块中写个转换函数,把LookupSet返回的Object数组转成Double数组后再传入计算方法
- 部署到SSRS服务器时,需要把DLL放到服务器的
SSRS安装目录\ReportServer\bin路径下,同时修改rssrvpolicy.config配置文件添加对应程序集的信任配置。
内容的提问来源于stack exchange,提问作者Tomer B
相关产品推荐
相关产品推荐

