1

德尔福使用: 2007

你好,

我有一个包含几列的 Listview。我想对一个特定的列进行排序。项目可以是数字或字母。

例子

基本上,顺序应该是:1->99,A->Z,AA->ZZ,AAA->ZZZ。我在网上找到了一些CustomSort的代码,我修改了一下。这是结果(好吧,代码更大,但我只放重要的东西):

function CustomSortProc(Item1, Item2: TListItem; SortColumn: Integer): Integer; stdcall;
var
 s1, s2: string;
 i1, i2: Integer;
 r1, r2: Boolean;

 function IsValidNumber(AString : string; var AInteger : Integer): Boolean;
 var
  Code: Integer;
 begin
  Val(AString, AInteger, Code);
  Result := (Code = 0);
 end;

 function CompareNumeric(AInt1, AInt2: Integer): Integer;
 begin
  if AInt1 > AInt2 then Result := 1 else
  if AInt1 = AInt2 then Result := 0 else Result := -1;
 end;

begin
 Result := 0;

 if (Item1 = nil) or (Item2 = nil) then Exit;

 r1 := IsValidNumber(s1, i1);
 r2 := IsValidNumber(s2, i2);
 Result := ord(r1 or r2);
 if Result <> 0 then Result := CompareNumeric(i1, i2) else
 begin
  Result := Length(s1) - Length(s2);
  if Result = 0 then Result := lstrcmp(PChar(s1), PChar(s2));
 end;
end;

以下是该列的排序方式:

例子

换句话说,字母和数字是正确排序的。但是,我无法将所有数字都放在字母之前。我敢肯定这很简单,但我一生都无法弄清楚。

非常感谢你。

4

1 回答 1

1

如果一个是字符串,一个是 int,则来自 val 的字符串的值为 0,所以它会在之前。

if (Item1 = nil) or (Item2 = nil) then Exit;

 r1 := IsValidNumber(s1, i1);
 r2 := IsValidNumber(s2, i2);
 if (r1 and r2) then
   Result := CompareNumeric(i1, i2)
 else
   if r1 then 
     result := -1
   else
    if r2 then
      result := 1
    else
    begin
     Result := Length(s1) - Length(s2);
     if Result = 0 then 
       Result := lstrcmp(PChar(s1), PChar(s2));
    end;
end;

我想,机器上没有Dephi来检查。

于 2013-03-10T03:02:27.440 回答