反转ClientDataSet索引的顺序

6

我想要在TClientDataSet中反转索引的顺序,下面的代码看起来应该能实现,但实际上却无法实现。有没有一种简单的方法来反转索引的顺序?

procedure TForm8.Button1Click(Sender: TObject);
var
  index: TIndexDef;
begin
  index := ClientDataSet1.IndexDefs.Find('LengthIndex');
  if ixDescending in index.Options then
    index.Options := index.Options - [ixDescending]
  else
    index.Options := index.Options + [ixDescending];
end;

2
为什么不删除索引并重新创建它?应该没有比这更快的方法了,因为(如有错误请指出),如果有一种非常快速地反转索引的方法,就没有必要区分升序和降序索引 - 数据库引擎可以根据查询即时排序。 - Thijs van Dien
也许你会看一下这个网址:http://edn.embarcadero.com/article/29056 里面不仅有关于CDS指数的详细解释,还有适合你需求的代码 - 我想是这样的 :o) - Sir Rufo
2个回答

9
TIndexDef.Options用于创建索引,不能用于尝试影响现有的索引。请参阅文档我强调的):

创建新索引时,使用Options指定索引的属性。Options可以包含零个或多个TIndexOption常量ixPrimary、ixUnique、ixDescending、ixCaseInsensitive和ixExpression。

检查现有索引的定义时,请读取Options以确定用于创建索引的选项。

您需要创建一个单独的索引,并将ixDescending值设置为该索引。然后,您可以通过仅更改IndexName属性来来回切换。

2
+1,正确的方法是创建两个索引,并使用IndexName属性在它们之间进行切换。 - RRUZ
什么是(重点在我这里)的意思? - Michael Riley - AKA Gunny
@CapeCodGunny:这意味着我是那个添加了粗体以强调这些要点的人。 - Ken White
好的,明白了。所以你摘取了文档的部分内容,并加粗了那些能够突出概念的要点。这很不错。谢谢。 - Michael Riley - AKA Gunny
很棒的算法建议:“您需要创建一个单独的索引,并将ixDescending值设置为。然后,您只需通过更改IndexName属性来切换即可。” 简单、优雅,对我非常有用! - RickyBelmont

1
这是我最终采用的双向排序方法。基本上它只是创建和释放索引,不太美观但有效。如果您可以访问FireDAC,则使用TFDMemTable更容易实现。
type
  TSortByFieldOption = (ForceAscending, ForceDescending);
  TSortByFieldOptions = set of TSortByFieldOption;

procedure SortClientDataSetByField(cds : TClientDataSet; FieldName : String; Options : TSortByFieldOptions = []);
const
  IndexName = 'GridSort';
var
  i: integer;
  index: TIndexDef;
  OldOrder: string;
  IndexOptions : TIndexOptions;
begin
  cds.DisableControls;
  try
    i := cds.IndexDefs.IndexOf(IndexName);
    if i <> - 1  then
    begin
      index := cds.IndexDefs.Find(IndexName);
      OldOrder := index.Fields;
      try
        cds.DeleteIndex(IndexName);
      except;
        OutputDebugString('no index?');
        //there seem to be conditions where the index does not exist but
      end;
      index.Free; //delete index for some reason does not free the index
      indexOptions := index.Options;
    end else
      IndexOptions := [ixDescending];

    index := cds.IndexDefs.AddIndexDef;
    index.Name := IndexName;
    index.Fields := FieldName;
    if ForceAscending in Options then
      index.Options := []
    else if ForceDescending in Options then
      index.Options := [ixDescending]
    else if OldOrder = FieldName  then
    begin
      if (IndexOptions = [ixDescending]) then
        index.Options := []
      else
        index.Options := [ixDescending];
    end;
    cds.IndexName := IndexName;
  finally
    cds.EnableControls;
  end;
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接