1

40 列 * 800 行を生成するストアド プロシージャに接続された TADODataSet があります。TADODataSet には、次のようなフィールドである OnGetText を割り当てる AfterOpen イベントがあります。

procedure TForm1.ADODataSet1AfterOpen(DataSet: TDataSet);
begin
  with DataSet do 
  begin
    Fields[4].DisplayLabel:=TR(AS2); //RefId
    Fields[4].DisplayWidth:=8;
    Fields[4].Tag:=1;
    Fields[4].OnGetText:=RefGetText;

    Fields[5].DisplayLabel:=TR(AS3); //ClientId
    Fields[5].DisplayWidth:=8;
    Fields[5].Tag:=1;
    Fields[5].OnGetText:=ClientGetText;
  end;
end;


procedure TForm1.RefGetText(Sender: TField; var Text: String; DisplayText:   Boolean);
begin
  if Sender.DataSet.FieldByName('RelStoreId').AsString='' then
    Text:='NO REF ID'
  else
    KHDM.RefGetText(Sender,Text,DisplayText);
end;

procedure TForm1.ClientGetText(Sender: TField; var Text: String; DisplayText:   Boolean);
begin
  if Sender.DataSet.FieldByName('ClientId').AsString='' then
    Text:='Client ID is not Assigned'
  else
    KHDM.ClientGetText(Sender,Text,DisplayText);
end;

テキストを含む XML にデータをエクスポートしたい 非常に遅いため、フィールドとレコードでループを作成したくない 一括コピーのようなものをストリーミングしたい、またはそのようなものが欲しい

同じ方法を使用する約800のモジュールがあるため、作業方法を変更できません...

助けてください。

4

2 に答える 2

0

私は以前にこの種のテクニックを使用しました-あなたに何か助けはありますか?出力の長さが問題であることがわかりますが、どういうわけかそれを理解できるかもしれません。おそらくClientDataset.SavetoFile()メソッドを見てください

function DataSetToXml(const ADataSet : TOraQuery) : String;
var
  Provider : TDataSetProvider;
  ClientDataSet : TClientDataset;
begin
  Provider := TDataSetProvider.Create(nil);
  try
    Provider.Name := 'tmpProvider';
    Provider.DataSet := ADataSet;
    ClientDataSet := TClientDataSet.Create(nil);
    try
      ClientDataSet.Data := Provider.Data;
      Result := ClientDataSet.XMLData;
    finally
      FreeAndNil(ClientDataSet);
    end;
  finally
    FreeAndNil(Provider);
  end;
end;
于 2012-11-28T14:35:41.523 に答える
0

あまり多くの変更を加えたくないので、これを最適化するためにできることはあまりありません。

これを最適化できることを願っています。データセットに固定フィールド (設計時に追加) がある場合は、通常は DataSetNameFieldName という名前のコンポーネント フィールド (cdsEmployeeEMPNO など) を使用してフィールドを参照できます。

その場合は、参照できますcdsEmployeeEMPNO.AsString(または必要なプロパティ)。これが高速な理由は、この場合に使用するフィールド コンポーネントが、それが参照するフィールドを既に認識しているためです。

あなたの場合、名前でルックアップを使用します: if Sender.DataSet.FieldByName('RelStoreId').AsString=..これは、コードが毎回実行されることを意味しますDataSet.Fields.IndexOf(FieldName)。これらのフィールドはソートされていないため、これは検索に時間がかかります。データセットのサイズを考えると、このようなルックアップは数千回になる可能性がありますが、賢く行えば簡単に 2 倍の速度になります。

何らかの理由でこれらのフィールド コンポーネント ラッパーを使用できない場合は、ルックアップを 1 回実行し、必要なフィールドのインデックスをデータ モジュールの変数に格納して、次のように値を要求することもできますif Sender.DataSet.Fields[RelStoreIdIndex].AsString= 。直接、ルックアップを保存します。これにより、少し速くなります。

ただし、XML 出力も遅いことに注意してください。エクスポートのコードは表示されませんが、最適化の深刻な可能性がいくつかある可能性があります。すべてのリファクタリングを開始する前に、実際のボトルネックを見つけるために、コードのさまざまな部分でプロファイリングを行うことは常に良いことです。

于 2012-11-28T13:51:14.630 に答える