You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SSRS Report Builder中汇总相同测试状态的连续序列号

需求背景
  • 现有一批带唯一序列号的送测部件,所有序列号均归属于和车间订单号(shop order number)绑定的容器(container)
  • 此前相关数据全部采用纸质手动记录追踪,现在计划通过SSRS Report Builder按车间订单生成报表,展示每个容器及其关联的所有序列号信息
  • 当前已实现按容器编号分组,展示单条序列号、测试通过/失败状态、序列号计数的功能,但生成的报表长达数十页,可读性差
优化需求
  • 相同测试状态的连续序列号合并展示在同一行,仅标注该区间的首个和最后一个序列号
  • 不同状态的连续序列号区间单独分行展示
  • 保留展示对应容器内的序列号总数量
实现方案

推荐优先在SQL查询层完成数据聚合,性能更好也更稳定;如果没有权限修改查询逻辑,也可以在SSRS报表层面通过自定义代码实现。

方案1:SQL层处理(经典「间隙与孤岛」问题解法)

你遇到的是典型的连续序列分组问题,业内也称孤岛问题。假设你的原始数据表包含容器ID、序列号、测试状态、车间订单号字段,且序列号为可排序的数值/可提取数值的字符串,参考查询逻辑如下:

WITH 排序预处理 AS (
    SELECT 
        容器ID,
        序列号,
        测试状态,
        -- 按容器、测试状态分组后,对序列号升序排序
        ROW_NUMBER() OVER (PARTITION BY 容器ID, 测试状态 ORDER BY 序列号) AS 排序序号
    FROM 你的原始业务表
    WHERE 车间订单号 = @ShopOrderNum -- 直接使用SSRS的车间订单参数即可
),
连续区间分组 AS (
    SELECT 
        容器ID,
        序列号,
        测试状态,
        -- 连续的序列号减去排序序号的差值是固定值,用这个值作为连续区间的分组标识
        CAST(序列号 AS INT) - 排序序号 AS 区间分组ID
        -- 如果序列号带前缀,比如是SN00012格式,就先提取数值部分:CAST(RIGHT(序列号, 5) AS INT) - 排序序号 AS 区间分组ID
    FROM 排序预处理
)
SELECT 
    容器ID,
    MIN(序列号) AS 区间起始序列号,
    MAX(序列号) AS 区间结束序列号,
    测试状态,
    COUNT(序列号) AS 本区间序列号数量,
    -- 窗口函数统计同一容器的总序列号数
    SUM(COUNT(序列号)) OVER (PARTITION BY 容器ID) AS 容器内总序列号数
FROM 连续区间分组
GROUP BY 容器ID, 测试状态, 区间分组ID
ORDER BY 容器ID, MIN(序列号)

查询返回的结果就是你需要的预期结构,直接绑定到SSRS的表格控件即可,不需要额外做复杂分组配置。

方案2:SSRS报表层处理

如果无法修改查询SQL,可以通过SSRS自定义代码实现分组:

  1. 右键报表空白处打开【报表属性】,切换到【代码】标签,粘贴如下VB自定义代码:
    Dim 上一个序列号 As Integer = 0
    Dim 上一个状态 As String = ""
    Dim 分组ID As Integer = 0
    ' 获取连续区间分组标识
    Function 获取分组ID(当前序列号 As Integer, 当前状态 As String) As Integer
        If 当前序列号 = 上一个序列号 + 1 And 当前状态 = 上一个状态 Then
            Return 分组ID
        Else
            分组ID +=1
            上一个序列号 = 当前序列号
            上一个状态 = 当前状态
            Return 分组ID
        End If
    End Function
    
  2. 给表格设置两级分组:
    • 父分组按容器ID分组,用于区分不同容器
    • 子分组的分组表达式写:=Code.获取分组ID(CInt(Fields!序列号.Value), Fields!测试状态.Value)
  3. 在子分组的行单元格中配置展示值:
    • 区间首尾序列号分别写=Min(Fields!序列号.Value)和=Max(Fields!序列号.Value)
    • 本区间数量:=Count(Fields!序列号.Value, "你的子分组名称")
    • 容器总数量:=Count(Fields!序列号.Value, "你的父分组名称")

内容的提问来源于stack exchange,提问作者David Lopez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 05:30:04