如何在Crystal Reports中实现按MainRef聚合多任务为单行列布局?
解决Crystal Reports行转列(多任务转单行)的实现方案
嘿,Katy,我刚好有过类似的Crystal Reports行转列需求经验,针对你这个12步骤流程转成单行多列的需求,结合你手头的CR9/2008/2011版本,我给你两种可行的实现方法,你可以根据自己的布局偏好选择:
方法一:交叉表快速实现(推荐,适合固定12个任务)
这个方法最省心,因为Crystal Reports的交叉表天生就是用来做行转列的:
- 先确认数据源里每个
MainRef下的12个任务有明确的顺序标识(如果没有,你可以用RowNumber()函数按MainRef分组生成Task序号,比如创建公式@TaskSeq:RowNumber({MainRef})) - 新建交叉表组件:
- 从字段资源管理器里,把
MainRef拖到交叉表的行区域 - 把刚才的
@TaskSeq(或者如果TaskDescription本身带“Task1”“Task2”这类标识,直接拖TaskDescription)拖到列区域 - 分别把
StartDate、DueDate、CompletedDate拖到汇总区域,汇总函数选「最大值」或「最小值」就行——因为每个任务对应唯一日期,这两个函数结果是一样的
- 从字段资源管理器里,把
- 调整交叉表的显示效果:
- 右键列标题,选择「格式化字段」,把默认的列名改成更清晰的,比如把“1”对应的StartDate列改成「Task1_StartDate」
- 你可以把多个日期字段的交叉表并排,或者在同一个交叉表的汇总区域添加多个字段,调整布局让它们横向排列成你需要的顺序
- KPI与延误判定:直接在交叉表后面加公式字段就行,比如判断
{Task1_CompletedDate} > {Task1_DueDate}来标记延误,或者写公式判断前序任务延误是否影响后续任务(比如If {Task1_CompletedDate} > {Task1_DueDate} And {Task2_StartDate} > {Task1_DueDate} Then "Task2受Task1延误影响")
方法二:手动公式字段转置(适合自定义布局)
如果你需要更灵活的布局控制,比如给不同任务字段加特殊格式,可以用这个方法:
- 先按
MainRef创建分组(你已经在这么做了,保持这个分组不变) - 给每个任务的字段创建单独的公式:
- 比如创建
@Task1_Desc:If RowNumber({MainRef}) = 1 Then {TaskDescription} Else "" - 创建
@Task1_StartDate:If RowNumber({MainRef}) = 1 Then {StartDate} Else Date(0,0,0)(用空日期占位,避免显示乱码) - 以此类推,创建
@Task2_Desc到@Task12_Desc、@Task2_StartDate到@Task12_StartDate,对应RowNumber({MainRef}) = 2到12
- 比如创建
- 隐藏细节行:右键细节区域,选择「格式化节」,勾选「抑制(无 Drill-Down)」,这样就不会显示原来的12行任务了
- 在
MainRef的组脚注区域,把所有创建的公式字段按顺序拖进去,排列成一行:MainRef→@Task1_Desc→@Task1_StartDate→@Task1_DueDate→@Task1_CompletedDate→ ... 直到Task12的所有字段 - KPI计算:在组脚注添加公式字段,比如
@Task1_Delay:If {@Task1_CompletedDate} > {@Task1_DueDate} Then "延误" Else "正常",连锁影响的公式可以这么写:@ChainImpact:If {@Task1_Delay} = "延误" And {@Task2_StartDate} > {@Task1_DueDate} Then "Task2受Task1延误影响" Else ""
版本兼容性提示
- CR9/2008/2011都支持这两种方法,不过CR9的交叉表布局调整需要手动拖拽更多,2008及以后版本的交叉表编辑器更直观
- 如果你的数据源里任务顺序不固定,建议先在数据库层面或者用CR的「运行总计」生成Task序号,确保每个
MainRef下的Task1到Task12对应正确的流程步骤
内容的提问来源于stack exchange,提问作者Katy
相关产品推荐
相关产品推荐

