Stringgridで実数型を文字型に変換してGridsortでsortしてみたのですが、うまくいきません。
stringgridには、実数型をformatで文字型に変換しています。
striggird1.cells[0,i+1]:=format('%.0f',[a/b]);
これをGridsortでsortしています。
1
2
3
10
とデータがあれば、gridsortすると
10
1
2
3
となってしまいます。
*******************************
procedure GridSort(SGrid:TStringGrid; ACol:Integer; KeyIsNum:Boolean=False);
procedure MergeSort(Buffer: TStringList; ARow, Count: Integer);
var I, J, Center : Integer;
Temp: TStringList;
Hikaku: Boolean;
begin
if Count = 1 then Exit;
Center := Count div 2;
MergeSort(Buffer, ARow, Center);
MergeSort(Buffer, ARow + Center, Count - Center);
I:=0; J:=0;
Temp := TStringList.Create;
try
while (I < Center) and (J < Count - Center) do begin
if KeyIsNum then
Hikaku:=( StrToFloatDef(Buffer[ARow+I],0) > StrToFloatDef(Buffer[ARow+Center+J],0) )
else
Hikaku:=( CompareStr(Buffer[ARow+I],Buffer[ARow+Center+J]) >0 );
if Hikaku then begin
Temp.AddObject(Buffer[ARow + Center + J], Buffer.Objects[ARow + Center + J]);
Inc(J);
end else begin
Temp.AddObject(Buffer[ARow + I], Buffer.Objects[ARow + I]);
Inc(I);
end;
end;
if I = Center then
while J < Count - Center do begin
Temp.AddObject(Buffer[ARow + Center + J], Buffer.Objects[ARow + Center + J]);
Inc(J);
end
else
while I < Center do begin
Temp.AddObject(Buffer[ARow + I], Buffer.Objects[ARow + I]);
Inc(I);
end;
for I:=0 to Count-1 do begin
Buffer[ARow + I] := Temp[I];
Buffer.Objects[ARow + I] := Temp.Objects[I];
end;
finally
Temp.Free;
end;
end;
var
ARow: Integer;
Buffer: TStringList;
begin
with SGrid do begin
Buffer := TStringList.Create;
try //Buffer に key とそれに対応する Rows を格納する
for ARow:=FixedRows to RowCount-1 do begin
Buffer.AddObject(Cells[ACol, ARow], TStringList.Create);
TStringList(Buffer.Objects[ARow - FixedRows]).Assign(Rows[ARow]);
end;
//Buffer を実際にソートする
MergeSort(Buffer, 0, RowCount - FixedRows); //Buffer.Sort; と置き換え
//ソートしたデータを Grid に書き戻す
for ARow := FixedRows to RowCount - 1 do begin
Rows[ARow].Assign(TStringList(Buffer.Objects[ARow - FixedRows]));
TStringList(Buffer.Objects[ARow - FixedRows]).Free;
end;
finally
Buffer.Free;
end;
end;
end;
CompareStrではなく数値のままで比較したらよいのでは?
例えば実数200.45をstringgridで表示するとき小数点以下を削って表示したいので、format使ったのですが、他に方法ありますか?
探したらあった。
http://www.kisoh-pile.jp/Delphi/TStringGrid.html#StringGridSort
GridSort(対象StringGrid, キー列, [true=数値 False=文字列]);
複数キーで、ソートする場合は、下位キーから順番に実行して下さい。
例: GridSort(StringGrid1, 2); 3列目文字キー
GridSort(StringGrid1, 0, True); 1列目数値キー
数値を文字列キーにする場合は、桁あわせ(0で埋める)が必要ですが、
StringGrid1.Cells[1,1]:=IntToStr(数値) X
StringGrid1.Cells[1,1]:= FormatFloat('000',数値) O
第3引数をTrueにすれば実数でソートします
ソート結果で10が前にくるのは、つまりこういうことでは?
StringGrid1.Cells[1,1]:= FormatFloat('000',数値)にしたら出来ました。ありがとうございます。
StringGrid1.Cells[1,1]:= FormatFloat('###,数値)でGridsortは違うんですね。
数値の桁数が4桁以上になると'000'ではまた問題が出そうなので
GridSortの3つ目の引数KeyIsNumをTrueで呼ぶことも検討してはいかがでしょうか?
procedure GridSort(SGrid:TStringGrid; ACol:Integer; KeyIsNum:Boolean=False);
********
KeyIsNumをtrueで呼び出す??
Gridsort(stringgrid1,1,true);にすると
実パラメータが多すぎるとエラーなります。
trueの呼び出し方ってどうするんでしょう。
試してみましたが実パラメータが多すぎるとのエラーはでませんでした。警告もなし。
逆に
procedure GridSort(SGrid:TStringGrid; ACol:Integer; KeyIsNum:Boolean=False);
この宣言でKeyIsNumが指定されることを弾くにはどうすればいいのかがわかりません。
パラメータの存在全否定ですね。
こちらの環境は Windows10 Pro 64bit 20H2 + Delphi 10.4 Community です。
ありがとうございます。
Gridsort(stringgrid1,1,true);
このコードで実行できるのですね。実行できないのは何かが間違ってるのでしょう。
コンパイルエラーになる行と、コンパイルエラーのメッセージをコピーアンドペーストでそのままここに書いてみては?
解決しました。
unit1,unit2にそれぞれgridsortを記述していたのが問題でした。ありがとうございました。
Unit1とUnit2にパラメータの違うGridSortの記述があり、パラメータの少ない方を呼んでいたとかでしょうか?
両ユニットで同じ宣言をしていてパラメータが通ったり弾かれたりするならば不安になる内容なのですが...
ツイート | ![]() |