ClientDataSet上のGroup By化

解決


庄司  2007-11-14 22:26:13  No: 28413

お世話になります。

開発環境
OS  XP Pro SP2
Delphi7.0
oracle

現在
「TSQLConnection」、「TSQLQuery」でDBへ接続し、SQL文でSelectしています。
取得したレコードを
「TDataSetProvider」、「TClientDataSet」、「TDataSource」→「TDBGrid_1」で表示しています。

次に2つ目を以下のように作成し設定しています。
「TDataSetProvider2」、「TClientDataSet2」、「TDataSource2」→「TDBGrid_2」
プロバイダのデータセットを「TClientDataSet」にしています。

1つ目ではフィールド数10列
2つ目では「1つ目のフィールド(10列の中)から3列」に項目エディタで設定して表示しています。

表示列数が3列の時、重複したレコードが発生するため、SQLのGroup By句のようなことをして重複レコードを非表示にしたいのですが、
ヘルプの集合体などを読んで試行錯誤しましたが、イメージした結果が表示されませんでした。

目的としては
重複レコードの非表示です。

質問したい内容は
1.重複レコードの非表示をTrueにするプロパティなどが存在するのか?
2.存在しない時、グループ化する手順。
  (Aggregates プロパティやインデックスなどの設定方法など。)
3.または、「TClientDataSet」で保持しているローカルのDB?にSQLの構文で問い合わせを行い、2つ目の「TClientDataSet2」に表示を行う方法。
(CommandTextプロパティについて色々試したのですが、イメージ通りに行きませんでした。イメージした動作をしているのかもわかりません。)

上記内容について知恵を貸してください。
説明不備などもございましたらご指摘ください。

よろしくお願いします。


Ru  2007-11-15 01:06:37  No: 28414

同じ内容で悩んだことがありました。
結局良い解決策が見つからなかったので強引に処理はしましたが・・・

===============================================
案1

・計算項目フィールドを一つ作成しておく(例:TmpAAA)
・インデックスを使用してグループ化したいキーで並び替えの設定をしておく。
・OnCalcFieldsイベントを使用して重複項目にフラグを立てる(例:TmpAAA= '1')
・FilteredプロパティをTrue。Filterプロパティに TmpAAA = '' としておく。

OnCalcFieldsイベントの大まかな説明
1.レコードを読み込んだ際に,グローバル変数などにグループ化したいキーの値を保持
2.次のレコードを読み込んだ際にキーの比較を行い,同じキーならばフラグを立てる(例:TmpAAA= '1')
3.キーが違った場合は再度グローバル変数などにグループ化したいキーの値を保持する。

-----------------------------------------------

===============================================
案2

・パラドックステーブルを作成一度データを書き出す
・書き出したデータテーブルに対してSQLを発行する。

-----------------------------------------------

ClientDataSetが保持しているデータに対してSQL発行できれば良いんですがねぇ。
手法ご存じの方いればおなじく教えて貰いたいです。


庄司  2007-11-15 02:25:22  No: 28415

Ruさんありがとうございます。

案1について
参考になりました。
(強引な方法考えていると現実逃避した妄想に逃げていくため助かります)
もう少し自分なりに調査してみて理想の製造がダメそうなら採用させていただきます。

案2について
DB関連もまだまだ未熟なため「パラドックステーブル」についても調査してみます。

>ClientDataSetが保持しているデータに対してSQL発行できれば良いんですがねぇ。
>手法ご存じの方いればおなじく教えて貰いたいです。
強引に処理すれば解決出来ますがあと1日ほど手法ご存知の方がいないか待ってみようかなと思います。
もし、こういう行為がルール違反などでしたらご指摘ください。気づき次第解決にします。

よろしくお願いします。


むく  2007-11-15 20:53:31  No: 28416

DISTINCTではダメですか?


庄司  2007-11-15 23:05:42  No: 28417

むくさん返信ありがとうございます。

>DISTINCTではダメですか?
今回のケースでは「TClientDataSet1」のデータから「TClientDataSet2」に
絞り込んで表示するため、「TClientDataSet1」の時点で重複レコードを
削除しないのです。
(Delphi上に「DISTINCT」が存在するか調べてみたのですが、見つから
  なかったのででSQLの「DISTINCT」としてです。)

Ruさんの案1の方法より簡単に目的の動作をすることが出来たのでコードを
載せておきます。
(載せたコードは実行して試してみてはないので予想していないエラーが
  発生してしまう可能性ありですが。)

--------------------------------------------------------------------
(Field1 : String;)

with ClientDataSet1 do begin
  Open;

  First;
  Field1 := FieldByName('Field1').AsString;
  Next;   //2行目からループスタート
  while not Eof do begin
    //同じ工程の時
    if Field1 = FieldByName('Field1').AsString then begin
      Prior;    //Deleteで最後のレコードになった時、Eofプロパティが
                //Trueにならないため
      Delete;
      end
    else
      Field1 := FieldByName('Field1').AsString;

    Next;
  end;
  //先頭行を選択しておく
  First;
end;
--------------------------------------------------------------------

貴重な時間を割いて考えてくださったRuさん、むくさんありがとうございました


庄司  2007-11-16 18:10:26  No: 28418

解決チェック


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加