SQL やその他の接続を DataSource として使用するのではなく、Crystal Reports に DataTable の形式でデータを提供し、レポートを WPF CrystalReportViewer に表示するレポート フレームワークに取り組んでいます。DataRows があればうまく機能します...ただし、提供されるデータがない場合、「フィールドが不明です」という例外に圧倒されます。
以下は、レポートがどのように表示されるかについての簡単な説明です。
- OData DataService を使用してデータを収集し、DataTable に入力します。
- レポートをロードし、既存の DataSources をクリアしてから、提供された DataTable を使用して SetDataSource を実行します。
- レポートを WPF レポート ビューアーに表示する
私が言ったように、レコードがあればすべてが機能しますが、そうでない場合は、「フィールドは既知の例外ではありません」という多くのエラーが発生します。このフレームワークの要件により、拡張性のためにオープンのままにしておく必要があるため、レコードのタイプを定義できません。エンド ユーザーは、OData の結果をカスタマイズして、追加のフィールドを提供できます。
私の最初の質問は次のとおりです。 データが提供されていない場合、Crystal はなぜ「詳細」バンドを解析しようとするのでしょうか?
この問題を回避するために、DataTable にデータがない場合、"IsEmpty" = true というパラメーターを渡しています。次に、数式を使用してデータを表示します。すなわち-
if({?IsEmpty}) then "" else {Command.Item}
これは私の 2 番目の質問につながります: 式が true の場合、false 条件が評価されるのはなぜですか? 「アイテム」フィールドの「フィールドが不明」であることはまだわかります。
データがない場合、「詳細」バンドまたは数式を評価しない方法はありますか?
編集:
これは、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"
このフィールド名は不明です。詳細: errorKind
回避策 (一時的な解決策): データが存在しない場合にレポートに使用する既定の DataTable を作成しています。この 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);
}
}