[delphi-users:1130] ListBoxの日本語ソート、ASCIIソート

451 views
Skip to first unread message

しばじゅんた

unread,
May 17, 2010, 9:06:37 PM5/17/10
to delphi...@freeml.com
お世話様です。

TStringGrid の列ソートで、列をListBoxにいれて、Sortし、元に戻す
ということをしています。(Cellをいちいち文字比較していては遅いので)
TStringGrid の話はおいといて。
ListBoxのソートで、カナ濁点・漢字濁点はMicrosoftの仕様で同一文字とみなされるようです。
Oracleを使用していて、この列順に印刷物を印刷するのですが、印刷アプリは別のものなので、この列情報をワークDBに入れ、OracleのOrderByで順番を指定して印刷します。
OracleのOrderByでは文字コード順になるのですかね、こちらのソートの方が
私らにしてみれば普通です。Microsoftの濁点無視Sortがおかしい。

ListBoxではこうなります(エクセルとかもこうなるようですね)
しばだ あきこ
しばた たみこ
しばだ ようこ
Oracle Ordrer By ではこうなります
しばた たみこ
しばだ あきこ
しばだ ようこ (たとだが逆かも知れませんが、たとだで纏まります)

うるさいお客が「これでは困る、どの順でも良いから同じにしてくれ」と言って来ています。
こんなのどうでもいいじゃん、と思っているのですが。
Oracleは変えようがないし、Microsoftが無茶なのですから、「出来ません」と
答えていいですかね?
ListBoxが完全ASCIIソート出来れば済みそうなのですが(英語圏モードにするのwww)・・・
C Builder6で申し訳ありませんが。


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

----------------------------------------------------------------------
【無料】freemlのiPhoneアプリができました♪今すぐダウンロード!
http://ad.freeml.com/cgi-bin/sa.cgi?id=fww8R
-----------------------------------------------------[freeml by GMO]--

ポン太

unread,
May 17, 2010, 9:56:21 PM5/17/10
to delphi...@freeml.com
しばじゅんた さん、こんにちは。ポン太 です。


>Oracleは変えようがないし、Microsoftが無茶なのですから、「出来ません」と
>答えていいですかね?

それで商売が成り立つのならそう答えるのも一つの方法でしょうが。
私は通常発注する立場なのですが、この程度のことでできませんと言われるよう
なら、その業者は使わないです。
Oracleでもソート順は変えようがあるし、またソートにListboxを使うという手
は、アマチュアならともかくプロとしてはどうなの?という気がします。

私としてのお薦めはソートをTStringListのSortに変更することです。これなら
たいした変更なしにコード順のソートになると思います。

それから
>うるさいお客が「これでは困る、どの順でも良いから同じにしてくれ」と言って来て
>います。
この程度の要求で「うるさいお客」扱いなら、うるさくないお客というのはいな
いと思いますよ。


2010/05/18(火) 10:46 ポン太


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

----------------------------------------------------------------------
PCにもメンバー掲示板ができました!
http://ad.freeml.com/cgi-bin/sa.cgi?id=fwxkI

中村@ブレーン

unread,
May 17, 2010, 10:11:14 PM5/17/10
to delphi...@freeml.com
中村です。

しばじゅんた さんは書きました:
>TStringGrid の列ソートで、列をListBoxにいれて、Sortし、元に戻す
>ということをしています。

ListBoxを使うと、ListBox固有のソート順になってしまうので、
TList.SortList などで適当なソート順にソートしたらいかがでしょう?

Oracle は既定では単純なコード順だと記憶しているので、実装は簡単だと思います。

# 蛇足: TListBox で TStringGrid の列ソートって結構めんどくさい気がしますが...

----------
東京都 日野市 中村拓男


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

----------------------------------------------------------------------
共有スケジュールに予定を登録してメンバーに共有しよう♪
http://ad.freeml.com/cgi-bin/sa.cgi?id=fwxxC

DEKO

unread,
May 17, 2010, 11:25:37 PM5/17/10
to delphi...@freeml.com
こんにちは。

> TStringGrid の列ソートで、列をListBoxにいれて、
> Sortし、元に戻すということをしています。
ListBox ではなく、StringList を使うといいですよ。

function CustomSortASC(List: TStringList; Index1, Index2: Integer): Integer;
// 昇順ソート
begin
//result := AnsiCompareStr(List[Index1], List[Index2]); // ロケール考慮/大文字小文字区別
result := CompareStr(List[Index1], List[Index2]);   // ロケール無視/大文字小文字区別
//result := AnsiCompareText(List[Index1], List[Index2]); // ロケール考慮/大文字小文字無視
//result := CompareText(List[Index1], List[Index2]); // ロケール無視/大文字小文字無視
end;

function CustomSortDESC(List: TStringList; Index1, Index2: Integer): Integer;
// 降順ソート
begin
//result := -AnsiCompareStr(List[Index1], List[Index2]); // ロケール考慮/大文字小文字区別
result := -CompareStr(List[Index1], List[Index2]);   // ロケール無視/大文字小文字区別
//result := -AnsiCompareText(List[Index1], List[Index2]); // ロケール考慮/大文字小文字無視
//result := -CompareText(List[Index1], List[Index2]); // ロケール無視/大文字小文字無視
end;

procedure TForm1.Button1Click(Sender: TObject);
var
SL: TStringList;
begin
SL := TStringList.Create;
try
SL.Add('しばだ あきこ');
SL.Add('しばた たみこ');
SL.Add('しばだ ようこ');
SL.CustomSort(CustomSortASC ); // 昇順ソート
// SL.CustomSort(CustomSortDESC); // 降順ソート
Memo1.Lines.Text := SL.Text;
finally
SL.Free;
end;
end;

Delphi のコードで申し訳ありませんが (w

--
by DEKO
-------------------------------------
http://homepage1.nifty.com/ht_deko/
ht_...@nifty.com
-------------------------------------


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

----------------------------------------------------------------------
写メはMLにアップしてみんなと楽しもう!
http://ad.freeml.com/cgi-bin/sa.cgi?id=fwyxQ

しばじゅんた

unread,
May 18, 2010, 12:08:20 AM5/18/10
to delphi...@freeml.com

DEKOさん、中村さん、ポン太ありがとうございます。

CustomSortは見た事ありますが、全然使ってませんでした。
うちの問題のこの部分だけこのようにしてみようかと思います。

Microsoftがこのようなソート順にしたのはそんなに昔ではないはずですよね。
当方は全編でTListBoxでTStringGrid のソートを肩代わりさせていますが、
使用上、速度とも全然問題はありませんでした。パターン化しているので簡単にやってます。
TListBox使って何か問題でも?と思います、こんなことで資質を問われても困りますがwww(答えていただいて済みませんが)コードを書きたくない派なので。
MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
【無料】freemlのiPhoneアプリができました♪今すぐダウンロード!
http://ad.freeml.com/cgi-bin/sa.cgi?id=fwzda

DEKO

unread,
May 18, 2010, 1:46:15 AM5/18/10
to delphi...@freeml.com
こんにちは。

> Microsoftがこのようなソート順にしたのはそんなに昔ではないはずですよね。
いえ、Windows 95 の時点で既にこの仕様です。

照合順序を細かく制御したい場合には、
CompareStr() / CompareText() ではなく、CompareString() API を使います。
http://msdn.microsoft.com/ja-jp/library/cc410673.aspx
先程のコード例を CompareString() で書き換えてみてください。

# TStringList.Sort はロケールの影響を受けますので、
# 今回のような件には使えません。

何故ロケール依存の照合順序になっているのかといいますと、
例えばスペイン語はアルファベットが 27 文字ありまして、
http://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%9A%E3%82%A4%E3%83%B3%E8%AA%9E#.E3.82.A2.E3.83.AB.E3.83.95.E3.82.A1.E3.83.99.E3.83.83.E3.83.88
ロケールを考慮しない ASCII 順だとアルファベット順にならないのです。

また、照合順序はベンダ依存であり、環境依存です。
お使いの OS (Mac とか Linux とか) や DB によって照合順序が一致しない事があります。

加えて言えば、ANSI と Unicode の照合順序も違います。

さらに言えば、Vista 以降の Windows では、地域と言語のオプションにて、
照合順序を "XJIS" / "部首/画数" で切り替える事ができるようになっています。

> TListBox使って何か問題でも?と思います、こんなことで資質を問われても困り
> ますがwww(答えていただいて済みませんが)コードを書きたくない派なので。
まあまあ、落ち着いて。

TListBox や TMemo を使ってソートを行う事は別に構わないと思います。
ただ、今回の件はコードを書くしか解決方法がない訳ですからね。
そこの所だけはご理解頂ければと思います。

--
by DEKO
-------------------------------------
http://homepage1.nifty.com/ht_deko/
ht_...@nifty.com
-------------------------------------


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

----------------------------------------------------------------------
共有スケジュールに予定を登録してメンバーに共有しよう♪
http://ad.freeml.com/cgi-bin/sa.cgi?id=fw0qG

KHE00221

unread,
May 18, 2010, 4:30:57 PM5/18/10
to delphi...@freeml.com
ほぼ StringList からのパクリなんだけど


TStringGrid = class(Grids.TStringGrid)
public
procedure QuickSort(ACol, L, R: Integer);
end;

procedure TStringGrid.QuickSort(ACol, L, R: Integer);
var
C,I,J,P: Integer;
Item1,Item2: String;
begin
repeat
I := L;
J := R;
P := (L + R) shr 1;
repeat
while AnsiCompareStr(Cells[ACol,I],Cells[ACol,P]) < 0 do Inc(I);
while AnsiCompareStr(Cells[ACol,J],Cells[ACol,P]) > 0 do Dec(J);
if I <= J then
begin
for C:=0 to ColCount-1 do
begin
Item1 := Cells[C,I];
Item2 := Cells[C,J];
Cells[C,I] := Item2;
Cells[C,J] := Item1;
end;
if P = I then
P := J
else if P = J then
P := I;
Inc(I);
Dec(J);
end;
until I > J;
if L < J then QuickSort(ACol, L, J);
L := I;
until I >= R;
end;

procedure TForm5.Button1Click(Sender: TObject);
begin
StringGrid1.QuickSort(0,0,StringGrid1.RowCount-1);
end;

procedure TForm5.Button2Click(Sender: TObject);
var
I,J: Integer;
begin
StringGrid1.RowCount := 10000;

for I:=1 to 10000 do
begin
StringGrid1.Cells[1,I] := Char(65+Random(26));
StringGrid1.Cells[2,I] := IntToStr(Random(10000));
end;

end;

ホンとは Cells 経由じゃなくて 直接いじりたいんだけど
MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
PCにもメンバー掲示板ができました!
http://ad.freeml.com/cgi-bin/sa.cgi?id=fw99S

KHE00221

unread,
May 18, 2010, 4:31:53 PM5/18/10
to delphi...@freeml.com
StringGrid1.QuickSort(0,0,StringGrid1.RowCount-1);

最初の値 1 or 2
MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
共有スケジュールに予定を登録してメンバーに共有しよう♪
http://ad.freeml.com/cgi-bin/sa.cgi?id=fw99X

DEKO

unread,
May 19, 2010, 1:28:44 AM5/19/10
to delphi...@freeml.com
こんにちは。

AnsiCompareStr() ではロケールの影響を受けるので、
CompareStr() にした方がいいですね。

--
by DEKO
-------------------------------------
http://homepage1.nifty.com/ht_deko/
ht_...@nifty.com
-------------------------------------


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

----------------------------------------------------------------------
【無料】freemlのiPhoneアプリができました♪今すぐダウンロード!
http://ad.freeml.com/cgi-bin/sa.cgi?id=fwFnU
Reply all
Reply to author
Forward
0 new messages