DBGridで、任意のレコードを削除するには?

解決


いずみ  2004-01-20 19:39:42  No: 6827

初めて投稿します。皆様、ご指導宜しくお願いします。

DBGridに表示しているデータ内で、該当する任意のデータを
ボタンクリックで非表示設定にすることは可能ですか?
色を変えることは、過去レスを拝見してわかったのですが、
レコードそのものを非表示にしたいです。
宜しくおねがいします。


HOta  2004-01-20 22:15:04  No: 6828

タイトルは削除になっていますが、特定のレコードだけ非表示にするのは、DataSet側の問題になります。DataSetから特定のレコードを除くようにすれば非表示になります。


いずみ  2004-01-21 04:46:53  No: 6829

HOtaさん  返事が遅くなって申し訳ありません。

DataSetから特定のレコードを除くとは、どういうことでしょうか?
再度、必要なレコードのみを抽出するということですか?
なんだか、間違った解釈をしているようで、すみません。


HOta  2004-01-21 06:40:24  No: 6830

元々TDBGridはTDataSetを表示するのが基本ですから、選択したレコードを除くレコードを抽出し直すのが基本でしょう。もし、TDbGrid側で、非表示にするなら、TDbGridに表示しないような手続きを追加しましょう。


Mr.XRAY  URL  2004-01-21 07:07:23  No: 6831

いずみさんへ.

DBGridというのはデータを表示するコントロール(コンポーネント)です.
したがって,レコードを削除するといった場合,

(1)DBGird側からあるレコードを削除する
    当然この場合,元のレコード(データ)も削除されます.

(2)DBGirdからあるレコードを見えなくする.
    元のレコードは削除されずに残っている.

いずみさんの質問ではどちらを意味するのかが判断できない場合が
あります.というのは,非表示のことを削除という用語でいう方も
いるからです(過去にそういうことがありました.そうすると話が
噛み合いません.用語の解釈が違うのですから).


Mr.XRAY  URL  2004-01-21 07:11:53  No: 6832

失礼しました.非表示と書いてありますね.
でしたら,OnDrawDataCell(OnDrawColumnCellじゃないよな)を
使用みて下さい.

確認したいのですが,適切でない発言をしてしまってので
取敢えず...


Mr.XRAY  URL  2004-01-21 07:17:42  No: 6833

たびた


Mr.XRAY  URL  2004-01-21 07:19:37  No: 6834

たびたびすみません.

間違いです.やはり,HOtaさんの言うように,Queryでデータを取り直す
方法がベターですね.

# 今日も調子悪いな.


えび  2004-01-21 08:22:15  No: 6835

「グリッド上で任意の上を選択して非表示」となると
Queryで条件を指定するのは無理だと思います。
このケースだとOnFilterRecordのイベントでレコード毎に条件を見ながら
表示/非表示の指定をするのが良いと思います。


いずみ  2004-01-21 18:44:24  No: 6836

HOtaさん  Mr.XRAYさん  えびさん  おはようございます。
色々なご指導ありがとうございます。

1)データの再抽出の方法は、以前やっていたので出来そうです。
(毎回抽出するパフォーマンスの指摘を受け、今回の改良を考えたのですが…)

2)OnFilterRecordイベントについてのサンプルなどはありませんか?

現在2)の方法を検討中です。
これからもご指導宜しくお願いします。


えび  2004-01-22 00:31:20  No: 6837

例えば、グリッド上でダブルクリックにより選択した行を非表示にするとします
除外する行をテストで確認しながらするとして、フォーム上にリストボックスを
配置してください。
先ず、データセットのFilteredプロパティをTrueにします、
これでOnFilterRecordのイベントが実行されるようになります。

procedure TForm1.DBGrid1DblClick(Sender: TObject);
begin
  //得意先コードをインデックスとし、除外する行を追加
  ListBox1.Items.Add(Query1.FieldByName('得意先コード').AsString);
  //フィルターレコードで検証させる
  Query1.FindNext;
end;

procedure TForm1.Query1FilterRecord(DataSet: TDataSet;
  var Accept: Boolean);
begin
  //該当するレコードの得意先コードが除外リストにあればレコードを表示しない
  Accept
    := ListBox1.Items.IndexOf(DataSet.FieldByName('得意先コード').AsString) = -1;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
{
  この処理は、プログラムの作り方によっては必要ありませんが、
  フォームを閉じる際に、例で試用しているリストボックスがフォーム上から
  消された後に、FilterRecordのイベントが実行される為、フォームを閉じる
  時にはFilterRecordのイベントを実行しないように制御しているだけです
}
  Query1.Filtered := False;
end;


えび  2004-01-22 01:02:48  No: 6838

上記の例だと、グリッドの表示しているカーソル位置によっていは
表示がギクシャクしますね。書き直します。

procedure TForm1.DBGrid1DblClick(Sender: TObject);
begin
  ListBox1.Items.Add(Query1.FieldByName('TOKUISAKI_CODE').AsString);
  Query1.UpdateCursorPos;
  Query1.Resync([]);
end;


HOta  2004-01-22 06:04:39  No: 6839

フィルターはRDBMSではあまり使わない方が良いようです。フィルターはDataSet全体をなめていきます。


えび  2004-01-22 06:27:19  No: 6840

FilterRecordの場合は、結局BDEがデータベースから取得した後の処理なので
さほどパフォーマンスには影響ないのではないでしょうか。
QueryやTableでインデックスを使わずにFilterプロパティのみを使用
するのは問題だと思いますけど。


えび  2004-01-22 06:47:40  No: 6841

補足ですが、たとえばQueryの結果で10000レコード取得したとしても
OnFilterRecordのイベントが実行されるのは殆どの場合グリッドに表示対象の
レコードのみです。無条件に全レコードが処理されるわけでは無いです。

グリッドから特定のレコードを除外する場合に、SQLの条件で指定できると
なるとインデックスの範囲を指定する程度にしないと汎用性が無いと思います。
不特定のレコードを処理するとなるとそのレコード分ORやANDを記述しなければ
ならないのではないでしょうか。


いずみ  2004-01-22 22:40:50  No: 6842

えびさん  HOtaさん  たくさんの親切なご指導ありがとうございます。

現在は、とりあえずデータの再抽出の方法で対処しています。
時間があれば、えびさんのレスを参考に改良することになりそうです。
(じゃあ、初めから言うなって感じです。。)

今回、Filterを初め色々なことを学ぶことができました。
これからもご指導宜しくお願いします。


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

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






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