如何在Crystal Reports中将固定3行数据合并为列
Crystal Reports 行转组列展示方案
问题背景
我有一个Crystal Reports报表,原始数据集结构如下:
| FieldName | Value | Position |
|---|---|---|
| 'Name' | 'Anton' | 01 |
| 'Age' | 15 | 02 |
| 'Gender' | 'X' | 03 |
| 'Name' | 'Anton' | 04 |
| 'Age' | 15 | 05 |
| 'Gender' | 'M' | 06 |
| 'Name' | 'Anton' | 07 |
| 'Age' | 15 | 08 |
| 'Gender' | 'M' | 09 |
| …… | …… | …… |
当前通过公式将各行数据存入单独变量,示例代码如下:
if record.Position = 1 then stringVar name_1 := record.Value; if record.Position = 2 then StringVar age_1 := record.Value; if record.Position = 3 then StringVar gender_1 := record.Value;
以此类推处理多组数据,再通过页脚公式展示各组信息。现需求是将每3条记录(Position 1-3、4-6…)转为一行,在明细区每行展示一组对应的Name、Age、Gender三列内容。
解决方案
方法1:分组+字段公式(简洁高效)
这是最直接的实现方式,无需数组操作:
创建分组依据公式
新建公式Group_Number,用于计算当前记录所属的组:Ceiling(tonumber(record.Position) / 3)以此公式为依据插入组(右键报表 → 插入组 → 选择该公式)。
创建组内字段提取公式
分别创建三个公式提取对应字段值:Name_Field:If record.FieldName = "Name" Then record.ValueAge_Field:If record.FieldName = "Age" Then record.ValueGender_Field:If record.FieldName = "Gender" Then record.Value
配置展示区域
- 隐藏原始明细区(右键明细节 → 格式化节 → 勾选「抑制显示(无 Drill-Down)」)。
- 将三个字段公式放入组页脚,右键每个公式 → 格式化字段 → 公共 → 求值时间 → 选择「组尾」。
此时每个组页脚会显示该组对应的Name、Age、Gender,实现每行一组的展示效果。
方法2:数组存储+遍历展示(灵活可控)
适合需要对组数据做额外处理的场景:
初始化全局数组
新建公式Init_Group_Array,放在报表头部初始化数组:Global StringVar Array groupData := [];填充组数据到数组
新建公式Populate_Group_Array,放在明细区,将每3条记录合并为一组存入数组:Global StringVar Array groupData; NumberVar groupNum := Ceiling(tonumber(record.Position) / 3); StringVar groupItem := record.FieldName + ":" + record.Value; If tonumber(record.Position) Mod 3 = 1 Then groupData := groupData + [groupItem] Else groupData[groupNum] := groupData[groupNum] + "|" + groupItem;解析数组并展示
新建公式Display_Group_Data,用于解析数组并输出格式化后的行数据:Global StringVar Array groupData; NumberVar i; StringVar result := ""; For i := 1 To UBound(groupData) Do ( StringVar Array items := Split(groupData[i], "|"); StringVar name := "", age := "", gender := ""; For Each item In items Do ( StringVar Array kv := Split(item, ":"); If kv[1] = "Name" Then name := kv[2]; Else If kv[1] = "Age" Then age := kv[2]; Else If kv[1] = "Gender" Then gender := kv[2]; ); result := result + name + " " + age + " " + gender + Chr(13); ); result;将此公式放在报表页脚或子报表明细区,即可展示所有分组后的行数据。
内容的提问来源于stack exchange,提问作者Dreqnoid
相关产品推荐
相关产品推荐

