我正在开发一个报告框架,它将以 DataTable 的形式向 Crystal Reports 提供数据,而不是使用 SQL 或任何其他连接作为数据源,并将在 WPF CrystalReportViewer 中显示报告。如果我有 DataRows,它会很好用......但是,如果没有提供数据,我会被“字段未知”异常所淹没。
以下是有关如何显示报告的快速说明:
- 使用 OData DataService 收集数据并填充 DataTable。
- 加载报表,清除现有数据源,然后使用提供的数据表设置数据源。
- 在 WPF 报表查看器中显示报表
就像我说的,如果有记录,一切正常,但如果没有,我会得到很多“字段未知异常”。由于该框架的要求,我无法定义记录的类型,因为它需要保持开放以实现可扩展性。最终用户可以自定义 OData 结果以提供附加字段。
我的第一个问题是: 如果没有提供数据,Crystal 为什么还要尝试解析“细节”波段?
为了解决这个问题,如果 DataTable 中没有数据,我将传入一个名为“IsEmpty”= true 的参数。然后,我使用公式来显示我的数据。IE-
if({?IsEmpty}) then "" else {Command.Item}
这引出了我的第二个问题: 如果表达式为真,为什么要评估假条件?我仍然知道“项目”字段的“字段未知”。
如果没有数据,有没有办法不评估“详细信息”带或公式?
编辑:
只有当 CR 评估公式时,我才会得到这个异常。有没有办法检查是否提供了该字段?
例外:
此字段名称未知。详细信息:文件 QCItemHistoryReportReduced {36B056B1-E4C1-4C1E-A19C-79ACBEE3E3D7}.rpt 中的 errorKind 错误:
公式格式错误:
if(isNull({Command.TestType})) then "Null" else if({Command.TestType}="C") Then "Character" else "Not Character"
此字段名称未知。详细信息:错误种类
解决方法(临时解决方案): 如果不存在数据,我正在构建一个用于报告的默认数据表。此 DataTable 将包含报告所需的所有列。不存在行数据,但只要指定列标题,它就可以工作
protected virtual void InitializeDefaultTable()
{
DefaultDataTable = new DataTable();
foreach (Table table in Database.Tables)
{
foreach (DatabaseFieldDefinition field in table.Fields)
{
if (!DefaultDataTable.Columns.Contains(field.Name))
{
DefaultDataTable.Columns.Add(field.Name, GetType(field.ValueType));
}
}
}
}
protected virtual Type GetType(FieldValueType fieldType)
{
switch (fieldType)
{
case FieldValueType.DateField:
return typeof(DateTime);
case FieldValueType.StringField:
return typeof(string);
case FieldValueType.Int16sField:
return typeof(Int16);
case FieldValueType.Int32sField:
return typeof(Int32);
case FieldValueType.BooleanField:
return typeof(bool);
case FieldValueType.NumberField:
return typeof(decimal);
default:
return typeof(string);
}
}