複数のTStringListを、そのうち一つのStringListのソートの結果と同じ並び順でソートするには


mk  2024-08-11 09:58:44  No: 151541

いつもお世話になります。
現在、1つのTStringListにソートのキーとなる情報を入れ、他の3つのTStringGlidに
キーに付属する情報を入れています。(ソート前はすべてのTStringGridで、キーの
並び順と同じ順序でならんでいます。)
1つ目のキーをソートした後、他の3つのキーも同じ順序でソートしたいのですが、
どのような形で行えばよいか、アイデアについてご助言をお願いできますでしょうか。
なにとぞよろしくお願いいたします。

※最初、キーとなるTStringListに、「AddObject(キー文字列、StringList.Create)」などとして、
 キーに付属する情報をTStringListにぶら下げてソートさせていましたが、データ数が20万件
 以上に増え、TStringListを大量に作るのは処理速度やメモリにも優しくないと考え、より
 高速、効率的なやり方を探しております。

※環境は2種類です。
Delphi6 Personal+ Windows10、Delphi11 Community + Windows10


igy  2024-08-11 11:03:24  No: 151542

> 他の3つのキーも同じ順序でソートしたいのですが、
> どのような形で行えばよいか、アイデアについてご助言をお願いできますでしょうか。

外しているかもしれませんが・・
TStringList の CustomSort メソッド を使うのでは、ダメですか?


mk  2024-08-11 11:42:58  No: 151543

ご助言ありがとうございます。
カスタムソートは、ソートする際、その順番を入れ替える条件を具体的に指定するものだと認識しておりましたが、他の配列のソートも同時にできる機能があるのでしょうか。
大変申し訳ありませんが、もし可能でしたら、もう少しだけ具体的にお教えくださいますでしょうか。
お手間をおかけし、申し訳ありません。


igy  2024-08-11 12:03:47  No: 151544

タイトルには、
> 複数のTStringListを、そのうち一つのStringListのソートの結果と同じ並び順でソートするには
と書いてあり、
最初の投稿の本文をよくみたら、
> 現在、1つのTStringListにソートのキーとなる情報を入れ、他の3つのTStringGlidに
と、“TStringList”ではなく、TStringGlid”と書いてあったり、
で、次の投稿では
> 他の配列のソートも
と、今度は“配列”も出てきたりして、イマイチよくわからないので、
mk さんがやりたいことを、もう少し詳細に書いていただいたら、
回答しやすいかもしれません。


AAAAA  2024-08-11 12:30:38  No: 151545

StringGrid にデータは入れない

var
  StringList: TStringList;

uses
    StrUtils;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Memo1.Lines.Add('A');
   StringList.Sort;
   Memo1.Lines.Add('B');
   StringGrid1.Invalidate;
   StringGrid2.Invalidate;
   StringGrid3.Invalidate;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
    I,J: Integer;
    ITEM: TDATA_ITEM;

begin
     StringGrid1.OnDrawCell    := StringGrid1DrawCell;
     StringGrid2.OnDrawCell    := StringGrid1DrawCell;
     StringGrid3.OnDrawCell    := StringGrid1DrawCell;

   //---------------------------
   // 仮データ
   //---------------------------

     StringList := TStringList.Create;
     J := 200000;
     for I:=0 to (J-1) do
     begin
       ITEM := TDATA_ITEM.Create;
       ITEM.TEXT1 := 'A' + IntToStr(I);   //StringGrid1 用
       ITEM.TEXT2 := 'B' + IntToStr(I);   //StringGrid2 用
       ITEM.TEXT3 := 'C' + IntToStr(I);   //StringGrid3 用
       StringList.AddObject(RightStr('000000' + IntToStr(J-I),6) , ITEM);
     end;
     StringGrid1.RowCount := J;
     StringGrid2.RowCount := J;
     StringGrid3.RowCount := J;

   //---------------------------
   // 編集しないのなら不要
   //---------------------------

     StringGrid1.Options := StringGrid1.Options + [goEditing];
     StringGrid2.Options := StringGrid1.Options + [goEditing];
     StringGrid3.Options := StringGrid1.Options + [goEditing];

     StringGrid1.OnSetEditText := StringGrid1SetEditText;
     StringGrid2.OnSetEditText := StringGrid1SetEditText;
     StringGrid3.OnSetEditText := StringGrid1SetEditText;

     StringGrid1.OnGetEditText := StringGrid1GetEditText;
     StringGrid2.OnGetEditText := StringGrid1GetEditText;
     StringGrid3.OnGetEditText := StringGrid1GetEditText;

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
    I: Integer;
    ITEM: TDATA_ITEM;
begin
    for I:=0 to StringList.Count - 1 do
    begin
      ITEM := TDATA_ITEM(StringList.Objects[I]);
      ITEM.Free;
    end;
    StringList.Free;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: LongInt;
  Rect: TRect; State: TGridDrawState);
var
    ITEM: TDATA_ITEM;
    TEXT: String;
    StringGrid: TStringGrid;
begin
    ITEM := TDATA_ITEM(StringList.Objects[AROW]);
    if (ACOL = 1) and (AROW <> 0) then
    begin
      if Sender = StringGrid1 then TEXT := ITEM.TEXT1;
      if Sender = StringGrid2 then TEXT := ITEM.TEXT2;
      if Sender = StringGrid3 then TEXT := ITEM.TEXT3;

      TStringGrid(Sender).Canvas.FillRect(Rect);
      TStringGrid(Sender).Canvas.TextRect(Rect,Rect.Left,Rect.Top,TEXT);
    end;
end;

procedure TForm1.StringGrid1GetEditText(Sender: TObject; ACol, ARow: LongInt;
  var Value: string);
var
    ITEM: TDATA_ITEM;
begin
    ITEM := TDATA_ITEM(StringList.Objects[AROW]);

    if Sender = StringGrid1 then Value := ITEM.TEXT1;
    if Sender = StringGrid2 then Value := ITEM.TEXT2;
    if Sender = StringGrid3 then Value := ITEM.TEXT3;
end;

procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol, ARow: LongInt;
  const Value: string);
var
    ITEM: TDATA_ITEM;
begin
    ITEM := TDATA_ITEM(StringList.Objects[AROW]);
    if Sender = StringGrid1 then ITEM.TEXT1 := Value;
    if Sender = StringGrid2 then ITEM.TEXT2 := Value;
    if Sender = StringGrid3 then ITEM.TEXT3 := Value;
end;


AAAAA  2024-08-11 12:31:32  No: 151546

  TDATA_ITEM = class(TPersistent)
  public
    TEXT1: String;
    TEXT2: String;
    TEXT3: String;
  end;

わすれもの


mam  URL  2024-08-13 14:50:26  No: 151575

「JCL(JEDI Component Library)」と「JVCL(JEDI Visual Component Library)」をインストールして「TJvStringGrid」を使うと、とても簡単ですよ。
https://mam-mam.net/delphi/vcl_tjvstringgrid.html

//並び変える
  JvStringGrid1.SortGrid(
    ACol,       //並び替え基準列番号指定
    order,       //True:昇順 false:降順
    True,       //固定行は並び替えしない
    stAutomatic,//並び替えタイプ
    true        //True:空のセルを上に移動させる
  );


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

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






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