开发者

Delphi Sorting TListView Question

开发者 https://www.devze.com 2022-12-16 20:26 出处:网络
I\'m using the code from: http://www.swissdelphicenter.ch/torry/showcode.php?id=1103 to sort my TListView, which works GREAT on everything but numbers with decimals.

I'm using the code from: http://www.swissdelphicenter.ch/torry/showcode.php?id=1103 to sort my TListView, which works GREAT on everything but numbers with decimals.

So I tried to do this myself, and I created a new Custom Sort called:

cssFloat

Created a new function


function CompareFloat(AInt1, AInt2: extended): Integer;
  begin
    if AInt1 > AInt2 then Result := 1
    else
      if AInt1 = AInt2 then Result := 0
    else
      Result := -1;
  end;
Added of the case statement telling it what type the column is..

             cssFloat  : begin
                  Result := CompareFloat(i2, i1);
              end;

And I changed the Column click event to have the right type selected for the column.


case column.Index of

0: LvSortStyle := cssNumeric;
1: LvSortStyle := cssFloat;
2: LvSortStyle := cssAlphaNum;

else LvSortStyle := cssNumeric;

And The ListView Sort type is currently set to stBoth.

It doesn't 开发者_JAVA技巧sort correctly. And Ideas on how to fix this?

Thank you

-Brad


I fixed it... after 3 hours of struggling with this.. not understanding why.. I finally saw the light.. CompareFloat was asking if two integers were greater or less than each other.


cssFloat  : begin
                    r1 := IsValidFloat(s1, e1);
                    r2 := IsValidFloat(s2, e2);
                    Result := ord(r1 or r2);
                    if Result <> 0 then
                      Result := CompareFloat(e2, e1);
                  end;
(Copied and modified from EFG's Delphi site)

FUNCTION isValidFloat(CONST s:  STRING; var e:extended):  BOOLEAN;
  BEGIN
  RESULT := TRUE;
  TRY
   e:= StrToFloat(s)
  EXCEPT
    ON EConvertError DO begin e:=0; RESULT := FALSE; end;

END END {isValidFloat};


While I don't know what is the problem which you faced perhaps is useful for you...

  function CompareFloat(AStr1, AStr2: string): Integer;
  const
    _MAGIC = -1; //or ANY number IMPOSSIBLE to reach

  var
    nInt1, nInt2: extended;

  begin
    nInt1:=StrToFloatDef(AStr1, _MAGIC);
    nInt2:=StrToFloatDef(AStr2, _MAGIC);
    if nInt1 > nInt2 then Result := 1
    else
      if nInt1 = nInt2 then Result := 0
    else
      Result := -1;
  end;

..and another snippet (perhaps much better):

function CompareFloat(aInt1, aInt2: extended): integer;
begin
  Result:=CompareValue(aInt1, aInt2); // :-) (see the Math unit) - also you can add a tolerance here (see the 'Epsilon' parameter)
end;

Besides the rounding which can cause you problems you can see what the format settings are in conversion between string and numbers (you know, the Decimal Point, Thousands Separator aso.) - see TFormatSettings structure in StringToFloat functions. (There are two - overloaded).

HTH,

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号