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]--
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
> または、StringListではないけど、こういう手があるよ…
> というものがあれば、どうか教えてください。
>
>
>
MLホームページ: http://www.freeml.com/delphi-users
----------------------------------------------------------------------
おもしろ写真を撮ったらMLにアップしよう!
http://ad.freeml.com/cgi-bin/sa.cgi?id=f3ytr
お返事、ありがとうございます。
参考ページとDelphi6のTStringList.CustomSortのヘルプを印刷し、
何度も何度も読み返しているところですが、
僕の知識では、内容がさっぱり理解できません。
また、ADOはパーソナル版には付いていないようです。
高木さん
ファイルを送ってくださって、ありがとうございます。
僕が思っていた以上に高度な処理で、
これはすぐには実装できそうにありません。
頭がボーーーっとしてきたので、今日はこれで休みます。
あずまさん
はじめまして。
簡単にできると思っていたことが、全然簡単でなく、
かなり難しい処理をするようで、「泣きっ面に蜂」状態です。
途中投げしないよう少しずつ学んでいきたいので、
どうか気長に見守ってやってください。
MLホームページ: http://www.freeml.com/delphi-users
----------------------------------------------------------------------
ちょっとした連絡はメンバー掲示板におまかせ!
http://ad.freeml.com/cgi-bin/sa.cgi?id=f3z68
> カンマで区切られた11個の項目が300行ほどあるデータを、
私なら迷わず ClientDataset を使うと思います。
カンマ区切りの処理は、1行づつ StringList.CommaText に取り込んで、区切ってもらいます。
最初はコツ(クセ)を掴むまでいくつか躓いたような記憶がありますが、並べ替えやフィルタリングなど、あとの処理は楽なのではないでしょうか。
MLホームページ: http://www.freeml.com/delphi-users
----------------------------------------------------------------------
サークルや友達同士の連絡をカンタンに!ML作成はコチラから
http://ad.freeml.com/cgi-bin/sa.cgi?id=f32lg
最近は専ら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
カンマ区切りテキストを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
すぐに具体的なコードをご提示できないのですが、
私はカンマで区切ったものを配列に入れて、
並びかえをしたことがあります。
あまり知識がないので、無理やりといった感じですね。笑
イメージ的には以下のようなものです。
使う配列は以下の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