[delphi-users:1175] カンマ区切りのデータの並べ替え

513 views
Skip to first unread message

Section-X

unread,
Jun 15, 2010, 2:25:13 AM6/15/10
to delphi...@freeml.com
初めまして。Section-Xと申します。
本日より、参加します。
どうぞよろしくお願いいたします。

Windows XP で Delphi 6 Personal(雑誌に付いていた)を使っています。


先日から、頭を抱えてずいぶんと困っているのですが、
-----
カンマで区切られた11個の項目が300行ほどあるデータを、
特定の項目を基準に全体を並べ替え、
第1項目を ComboBox に追加していきたい。
-----

エクセルに「並べ替え」という機能がついています。
ちょうどそれと同じことを Delphi 6 でやりたいです。

試しに、3つの項目で3行のファイルを作って、
TStringListに読み込んでテストしているのですが…

// 名前,身長(cm),体重(kg)
// 東西一郎,183,74
// 北北東二郎,166,58
// 南三郎,170,50

var
SL : TStringList;
begin
SL := TStringList.Create;
SL.LoadFromFile('身体特徴.txt');
SL.Sort;
end;

これで「名前順」に並べ替えることはできました。
が、たとえば「身長」を基準(低い順)に StringList の内容を、

北北東二郎,166,58
南三郎,170,50
東西一郎,183,74

反対に「身長」(高い順)に

東西一郎,183,74
南三郎,170,50
北北東二郎,166,58

と並べ替えることができるのでしょうか?

カンマで区切られているデータだから、
StringList.CommaTextでどうにかなるのでは?と安易に思っていたのですが、
どうにもならないので、みなさんの知恵を貸してもらえませんか?

または、StringListではないけど、こういう手があるよ…
というものがあれば、どうか教えてください。


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
サークルや友達同士の連絡をカンタンに!ML作成はコチラから
http://ad.freeml.com/cgi-bin/sa.cgi?id=f3vnI
-----------------------------------------------------[freeml by GMO]--

moru

unread,
Jun 15, 2010, 2:50:07 AM6/15/10
to delphi...@freeml.com
こんにちは
稲庭と申します。
下記の2点を思いつきます。
 
・TStringList.CustomSortメソッドで、任意の並び順、基準項目で並び替える。
 
// 下記は、Personalだとできなかったかもしれません、、(Personalないので確認できません)
・ADOでCSVをDataSetに読み込み並び替える。
 
参考までですが、よろしくお願いします。
稲庭

高木太郎

unread,
Jun 15, 2010, 3:26:35 AM6/15/10
to delphi...@freeml.com
 こんにちは、イマジオムの高木です。

Section-X さん:


> -----
> カンマで区切られた11個の項目が300行ほどあるデータを、
> 特定の項目を基準に全体を並べ替え、
> 第1項目を ComboBox に追加していきたい。
> -----

 一から作ると結構面倒ですよね。

1.カンマなどの区切り文字で区切られた項目の並びから、n番目の項目を
  取り出す手続き

2.他のリストを連動させてソートすることのできるリスト

……の両方を持っていますので、よろしければさし上げます。 ご連絡
ください。 ご希望の方がおいででしたら、どなたでもご連絡ください。
――――――――――――――――――――――――――――――――――――
株式会社イマジオム 代表取締役 高木太郎
〒316-0024 茨城県 日立市 水木町 1-11-10
電話:0294-28-0147
ファクシミリ:0294-28-0148
電子メール:tarou_...@imageom.co.jp
ホームページ:http://www.imageom.co.jp/


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
練習やMTGの予定は忘れずに共有スケジュールに登録しよう♪
http://ad.freeml.com/cgi-bin/sa.cgi?id=f3wce

きゅうたろう

unread,
Jun 15, 2010, 5:54:21 AM6/15/10
to delphi...@freeml.com
こんにちは、あずま、ともうします。
遠回りかも知れませんが、SQLite3なら、DBとして動かせます。
こちらに、サンプルを作成されている方があります。ご参考になれば幸いです。
> http://netakiri.net/labo/db_sqlite3_sdw_sample.shtml


> または、StringListではないけど、こういう手があるよ…
> というものがあれば、どうか教えてください。
>
>
>


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
おもしろ写真を撮ったらMLにアップしよう!
http://ad.freeml.com/cgi-bin/sa.cgi?id=f3ytr

Section-X

unread,
Jun 15, 2010, 7:21:41 AM6/15/10
to delphi...@freeml.com
稲庭さん

お返事、ありがとうございます。
参考ページとDelphi6のTStringList.CustomSortのヘルプを印刷し、
何度も何度も読み返しているところですが、
僕の知識では、内容がさっぱり理解できません。
また、ADOはパーソナル版には付いていないようです。


高木さん

ファイルを送ってくださって、ありがとうございます。
僕が思っていた以上に高度な処理で、
これはすぐには実装できそうにありません。
頭がボーーーっとしてきたので、今日はこれで休みます。


あずまさん

はじめまして。
簡単にできると思っていたことが、全然簡単でなく、
かなり難しい処理をするようで、「泣きっ面に蜂」状態です。
途中投げしないよう少しずつ学んでいきたいので、
どうか気長に見守ってやってください。

MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
ちょっとした連絡はメンバー掲示板におまかせ!
http://ad.freeml.com/cgi-bin/sa.cgi?id=f3z68

ek

unread,
Jun 15, 2010, 10:04:11 AM6/15/10
to delphi...@freeml.com
ekです。楽しそうなので・・・。

> カンマで区切られた11個の項目が300行ほどあるデータを、

私なら迷わず ClientDataset を使うと思います。
カンマ区切りの処理は、1行づつ StringList.CommaText に取り込んで、区切ってもらいます。
最初はコツ(クセ)を掴むまでいくつか躓いたような記憶がありますが、並べ替えやフィルタリングなど、あとの処理は楽なのではないでしょうか。


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
サークルや友達同士の連絡をカンタンに!ML作成はコチラから
http://ad.freeml.com/cgi-bin/sa.cgi?id=f32lg

ねこ

unread,
Jun 15, 2010, 6:40:52 PM6/15/10
to delphi...@freeml.com
金子です、お早うございます。

最近は専らROMで、プログラムをいじることもほとんどありませんが、面白そ
うなので。

環境:CeleronD 3.06GH + 1GB RAM + XP Home SP2 + DP6 UP2

久しい以前に、TStringGrid から派生する TMyStringGrid を作ったことがあ
ります。これは任意の列をキーに全体のソートができます。TStringGrid への
当該データ読み込みは簡単だと思うので、ソートに関連する部分だけコードを下
記に

procedure TMyStringGrid.SortUpExec;
var
List:TList;
i:integer;
sl:TStrings;
begin
ACol:=fSortKeyCol;//プロパティからソートのキー列を読み込んでいる。ACol
//は下に出てくるカラムNoを覚えている変数
//以下もプロパティから昇順か降順かを指定
if fSortOder=ASC then
Direction:=1
else
Direction:=-1;
List:=TList.Create;
try
for i:=0 to RowCount-2 do
begin
sl:=TStringList.Create;
sl.Assign(Rows[i+1]);
List.Add(sl);
end;
//TListで並べ替え
List.Sort(sortUp); {昇順}
//並べ替えた内容をStringGridへコピーし直す
for i:= 0 to List.Count-1 do
begin
Rows[i+1].Assign(TStrings(List[i]));
TStrings(List[i]).Free;
end;
finally
List.Free;
end;
end;

var
ACol: LongInt; // カラムNoを覚えている変数
Direction:integer;
function sortUp(Item1, Item2: Pointer):integer;
begin
if TStrings(Item1)[ACol]>TStrings(Item2)[ACol] then result:= 1
else
if TStrings(Item1)[ACol]<TStrings(Item2)[ACol] then result:= -1
else result:=0;
result:=result*Direction;
end;

****************************
金子 純一
<kane...@nifty.com
****************************

MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
ちょっとした連絡はメンバー掲示板におまかせ!
http://ad.freeml.com/cgi-bin/sa.cgi?id=f34Ls

tetupei

unread,
Jun 15, 2010, 9:43:37 PM6/15/10
to delphi...@freeml.com
Section-Xさんこんにちは
赤尾です。

カンマ区切りテキストをTStringListで制御する事は少し合理性に外れると思いま
す、
ですがあえて貫くのであればこんな感じでどうでしょう?
※本当はもっと効率的な方法がありますが、難しくなります。

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Memo2: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

type TSStyle = (ssText,ssInteger);
var
//ソート用のプロパティ
fAscending : Boolean; //昇順
fIndex : Integer; //項目番号
fStyle : TSStyle; //テキストか整数かそれとも...

implementation

{$R *.dfm}
function GetCommaText(aStr:String; aIndex:Integer):string;
var
subList:TStringList;
begin
subList := TStringList.Create;
subList.Delimiter := ',';
subList.DelimitedText := aStr;
Result := subList.Strings[aIndex];
subList.Free;
end;

function CustomSort(List: TStringList; Index1, Index2: Integer): Integer;
begin
case fStyle of
ssText :Result :=
CompareText(GetCommaText(List.Strings[Index1],fIndex),

GetCommaText(List.Strings[Index2],fIndex));
ssInteger :Result := StrToInt(GetCommaText(List.Strings[Index1],fIndex))
-

StrToInt(GetCommaText(List.Strings[Index2],fIndex));
end;
if fAscending then
Result := Result * -1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
strList:TStringList;
i: Integer;
begin
strList := TStringList.Create;
strList.Add('東西一郎,183,74');
strList.Add('北北東二郎,166,58');
strList.Add('南三郎,170,50');
fAscending := True; //昇順で
fIndex := 1; //2番目の項目を
fStyle := ssInteger; //整数型でソート
strList.CustomSort(CustomSort); //ソート開始
Memo1.Text := strList.Text;
//データ抽出
Memo2.Clear;
for i := 0 to strList.Count - 1 do
Memo2.Lines.Add(GetCommaText(strList.Strings[i],fIndex));
strList.Free;
end;

end.


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
練習やMTGの予定は忘れずに共有スケジュールに登録しよう♪
http://ad.freeml.com/cgi-bin/sa.cgi?id=f36Gi

じゃぺ

unread,
Jun 15, 2010, 10:35:57 PM6/15/10
to delphi...@freeml.com
川上です。

すぐに具体的なコードをご提示できないのですが、
私はカンマで区切ったものを配列に入れて、
並びかえをしたことがあります。
あまり知識がないので、無理やりといった感じですね。笑

イメージ的には以下のようなものです。
使う配列は以下の3つ。
recA:array of array of string;// 元
recB:array of array of string;// 表示用
recT:array of string;// temp

まず、元の文字列をカンマで区切って recA[i,j] に放り込みます。
(ここら辺のコードがご提示できないです、すみません。
カンマを分割する関数を作れば簡単に取り込めます。
iはレコード、jはカラムです。今回は入れてませんが、
j=0にレコード番号を入れておくと楽です。)

身長でソートするときは
166,北北東二郎,58
170,南三郎,50
183,東西一郎,74
のような文字列にしてやればいいので
for i:=0 to high(recA) do begin
ts.Add(recA[i,1]+','+
recA[i,0]+','+
recA[i,2];
end;
カラムが変わってしまっているので
このあと戻してやる必要があります。
for i:=0 to high(recA) do begin
// ここでts[i]をカンマで分割し、recTに格納
recB[i,0]:=recT[1];
recB[i,1]:=recT[0];
recB[i,2]:=recT[2];
end;
後はrecBから文字列に戻したり、フォームに
表示させたりといった具合です。

体重でソートするときは
58,166,北北東二郎
50,170,南三郎
74,83,東西一郎
でtsに渡します。

スマートではないけど。いかがでしょ


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
おもしろ写真を撮ったらMLにアップしよう!
http://ad.freeml.com/cgi-bin/sa.cgi?id=f37tn

Reply all
Reply to author
Forward
0 new messages