プログラミング勉強中です。
ListViewで、ファイルサイズのカラムをクリックしたとき、
サイズの大小でソートせず、文字列の順番としてソートされてしまいます。
具体的には次のとおり。
(ソート前)
カラム1 サイズ
aaaaaa 1234 KB
bbbbbb 555 KB
cccccc 1280 KB
(昇順ソート後)
カラム1 サイズ
aaaaaa 1234 KB
cccccc 1280 KB
bbbbbb 555 KB
(こうなってほしい)
カラム1 サイズ
bbbbbb 555 KB
aaaaaa 1234 KB
cccccc 1280 KB
どのようにしたら、よろしいでしょうか。
よろしくお願いいたします。
環境
Delphi 6 personal + Windows2000
TListViewって、カラムを押すと自動でソートしましたっけ?
SortTypeを設定して試してみましたがソートされませんでした
# D7Pro
自動でできるかどうかはさておき。
ソートする場合、AlphaSortかCustomSortを使用するかと思いますが、AlphaSortであれば、SortTypeをstNone以外にしておき、OnCompareイベントで比較してやればよいかと思います。
CustomSortであれば、比較用プロシージャを用意する必要があるので、各カラムごとにプロシージャを用意するなり、プロシージャ内で切り分けるなりすればできます。
Format使って桁指定して数字出力すればいいんじゃないでしょうか?
Poさんへ。
数値をB, KB, MBにするのは、Formatでは無理では?Ifで、どの単位にするか切り分ける必要がありそうです。
APIを使えば1発変換ですね。
定義で、
{$EXTERNALSYM StrFormatByteSize64}
function StrFormatByteSize64(
qdw: int64;
pszBuf: PCHAR;
uiBufSize: UINT
):PCHAR; stdcall;export;
{$EXTERNALSYM StrFormatByteSize64A}
function StrFormatByteSize64A(
qdw: int64;
pszBuf: PAnsiChar;
uiBufSize: UINT
):PAnsiChar; stdcall;export;
{$EXTERNALSYM StrFormatByteSize64W}
function StrFormatByteSize64W(
qdw: int64;
pszBuf: PWideChar;
uiBufSize: UINT
):PWideChar; stdcall;export;
として、実体を
function StrFormatByteSize64; external 'shlwapi.dll' name 'StrFormatByteSize64A';
function StrFormatByteSize64A; external 'shlwapi.dll' name 'StrFormatByteSize64A';
function StrFormatByteSize64W; external 'shlwapi.dll' name 'StrFormatByteSize64W';
としておき、
var
buf: array[0..512] of char;
begin
Memo1.Lines.Add(StrFormatByteSize64(532, @buf[0], 511));
Memo1.Lines.Add(StrFormatByteSize64(1340, @buf[0], 511));
Memo1.Lines.Add(StrFormatByteSize64(23506, @buf[0], 511));
Memo1.Lines.Add(StrFormatByteSize64(2400016, @buf[0], 511));
Memo1.Lines.Add(StrFormatByteSize64(2400000000, @buf[0], 511));
end;
とすれば、
532 バイト
1.30 KB
22.9 KB
2.28 MB
2.23 GB
と出来ます。
IE5.0以降で使用できるAPIですので、使えないときもあります。
書き忘れました。
StrFormatByteSize64に関する情報
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/shlwapi/string/strformatbytesize64.asp
すみません。単位変換のほうの説明は省略してました。
この辺りは自分でなんとかやってくれるだろうと思ってましたので(^^;
私が答えたのは
>サイズの大小でソートせず、文字列の順番としてソートされてしまいます。
の部分です。
このことから、たまさんは既に文字列のソートはできるのだと解釈します。Formatを使ってListViewに出力すれば、文字列の順番としてソートしていただければ
たまさんのご希望通りの動作になってくれると思います。
ヘルプより
>d 10進数。指定された桁数より少ないときは,結果の文字列の左側にゼロが埋め込まれる
実際にはゼロは表示には現れませんがソートには働いてくれますんで。
うろ覚えですが
var Size: Integer;
SubItems.Add(Format('%5d, [Size]));
こんな感じに出力すれば[00120]のようになると思います。
#実際には左側のゼロは見えません。
便利そうなAPIですねぇ
ソートもちゃんとなってくれそうですね(?
ところで、単位違ってもソートできるんでしょうかね
またまたすみません。
Size: Integer;
ではおそらくダメです。
Size: Extended;
とでもしておいてください。
なるほど、例えば、20, 1000という数値を、
' 20'
' 1000'
とすると言うことでしょうか。
そうすると、ListViewのカラム幅を小さくしたとき、
20
1..
となってほしいのに、
..
1..
となってしまいますよ。
# ..は省略された部分
OnCompareで、直接数値を比較してやった方がスマートだと思いますが、どうでしょう。
ツイート | ![]() |