0

私はこれまで数日を費やして、アプリケーションでFastReportを使用するための基礎を築きました。アプリケーションは、デバイスのテスト結果データを、いくつかの固定フィールド(DeviceID、Passedなど)と可変数の結果フィールドで構成されるDBFファイルの形式で保存します。各フィールドは、使用可能な測定データのタイプに対応します。これらのフィールドは1つから100まであります。各フィールドには、OVやRVなどの文字コード名があります。合計レコード数は、ゼロから最大で数万になります。

特定のレポートテンプレートには、表示されるフィールド名がすでにデザインに含まれています。レポートで欠落しているフィールドは空になります。

私の質問は、レポートの作成が可能な限り単純になるように、レポートとレポートに提供されるデータを設計する最良の方法に関するものです。ユーザーが独自のレポートを生成できるようにします。2種類のレポート出力が必要です。 -結果と集計のリスト。私に頭痛の種を与えているのは骨材です。MIN、MAX、COUNTなど(FastReportで内部的に提供されている)だけでなく、標準偏差も必要です。さらに、グループヘッダーをクリックすると、データテーブルが表示または非表示になるFastReportの「ドリルダウン」機能を使用したいと思います。常に表示されるように、アグリゲートはフッターではなくヘッダーに配置するのが理想的です。

TQueryのSQLは、「StDev」集計を提供するため(FastREportは提供しません)、柔軟性が高いことがわかりましたが、私が見る限り、各フィールドに固定のTQueryが必要です。これまでのところ、私が思いつくことができる最も良い解決策は、メインテーブルで「合格」のフィルターを使用して(ユーザーが合格、不合格、またはすべてを表示できるようにするため)、同じもので別の「統計」テーブルを作成することです。フィールド名の列。ただし、個々のレコードとしてMIN、MAX、COUNT、MEAN、STDEVを使用します。次に、TfrxDBDataSetを使用して、このテーブルをFastReportに公開します。FastReport独自のADODatabaseとADOQueryを使用して、DBFファイルに直接アクセスすることもできます。これはうまく機能しますが、可能であれば、レポートでこのアクセスレイヤーをユーザーに公開したくありませんでした。

集計関数が基本的なデータベース要件でなければならない場合、これは非常に厄介に思えます。私はこれを行うためのはるかに簡単な方法を逃していますか?FastReport(professional)で提供される(優れた)デモを実行し、XE2を使用しています。StDevを自分で計算する必要がある場合は、MATHユニットの便利な機能も知っています。

何かご指導をいただければ幸いです。

4

2 に答える 2

2

コードで計算できるもの、配列値のリスト、集計または関数計算結果については、を使用してイベントTfrxUserDataSetを実装することをお勧めします。TfrxReport.OnGetvalue

最初は混乱するかもしれませんが、ユーザーデータセットは単にデータセット名とそのデータセット名を介して利用可能なフィールドのリストを宣言し、起動するイベントを使用して「ナビゲート」(最初、次のレコード)し、いつ宣言するかを宣言します。計算されたデータの終わりに達しました。これにより、「ジェネレーター」など、計算用の通常の仮想データプロバイダーのロジックセットを構築できます。

OnGetValueイベントは次のようになります。

procedure TfrmReport.frxReportGetValue(const VarName: string; var Value: Variant);
begin
   Value := GetReportValue(VarName);
end;

// INPUT:  VarName = '(<GlobalArea."hdReportTitle">)'
// OUTPUT: tableName = 'GlobalArea', fieldName = 'hdReportTitle'
function ParseVar(const VarName:String; var tableName,fieldName:String; var ParenFlag:Boolean):Boolean;
var
 paVarName:String;
 angleBracketFlag:Boolean;
 dotPos:Integer;
 fieldQuoteFlag:Boolean;
 procedure RemoveOuter(var str:String; initialChar,finalChar:Char; var flag);
 var
  n:Integer;
 begin
    n := Length(str);
   if n>2 then begin
      ParenFlag := (str[1]=initialChar) and (str[n]=finalChar);
      if ParenFlag then begin
         str := Copy(str,2,n-2);

      end;
   end;
 end;
begin
   result := false;
   fieldQuoteFlag := false;
   paVarName := SysUtils.Trim(VarName);
   ParenFlag := false;
   tableName := '';
   fieldName := '';
   RemoveOuter(paVarName, '(',')',parenFlag);
   RemoveOuter(paVarName,'<','>',angleBracketFlag);
   dotPos := Pos('.',paVarName);
   if dotPos >0 then begin
    tableName := Copy(paVarName,1,dotPos-1);
    fieldName := Copy(paVarName,dotPos+1,Length(paVarName));
    RemoveOuter(fieldName, '"','"',fieldQuoteFlag);
    result := true;
   end else begin
      tableName := '';
      fieldName := paVarName;
   end;
end;

function TfrmProfitAnalysisReport.GetReportValue(const VarName:String):Variant;
var
 tableName:String;
 fieldName:String;
 parenFlag:Boolean;
begin
 ParseVar(VarName,tableName,fieldName,parenFlag);
 result := NULL;
   { Global Area - Header Values }
 if sameText(tableName,'GlobalArea') then begin
   if fieldName='hdReportTitle' then
      result := GetTitle; { A function that calculates a title for the report }
   else if fieldName='hdReportSubtitle' then
      result := 'Report for Customer XYZ'
   else if fieldName='....' then begin
      ...
   end;

   if Variants.VarIsNull( result) then
      result :=  '?'+fieldName+'?';

end;
于 2012-06-01T19:47:04.077 に答える
1

さて、多くの可能な答えを伴う多くの質問:

1)データセットについては、レポート内で使用するのではなく、アプリケーション(DataModuleまたはForm)に配置することを強くお勧めします。それはあなたにもっと柔軟性を与えるでしょう。

2)集計ごとに1つのクエリを設定できますが、データテーブルが大量のレコードで大きくなると、パフォーマンスに影響します。いくつかの選択肢:

  • 2.1)FastReportスクリプトで値を計算しますが、これによりロジックもレポートに公開されます。
  • 2.2)Delphiコードのレコードを反復処理し、結果を変数としてレポートに渡します。例:

    frxReport.Variables['MIN'] := YourMinVariableOrMethod;
    frxReport.Variables['MAX'] := YourMaxVariableOrMethod;
    
  • 2.3)クエリに関連付けられたClientDataSetを使用し、ClientDataSetにTAggregateFieldsを実装します。

私は個人的に、シンプルで強力なDelphiコードのすべてのロジックを備えた2.2アプローチを好みます。

于 2012-06-01T16:25:03.743 に答える