内存表如果没有Provider或者数据库表,不能执行SQL语句。因为是三层结构,客户端不跟数据库交互,所有数据源均由中间层传来的XML流解析得到。故TClientDataSet是完完全全的内存表请问能实现排序吗??

解决方案 »

  1.   

    TClientDataSet当然可以在客户端排序,你可以通过两种方式,一种是设置 ClientDataSet 的 IndexFieldNames,即要进行排序的字段。用分号进行分隔。另一种是设置 IndexName,这种方式更加灵活,但先要在 IndexDefs 中先设定好。这种方法较前一种方法可以倒排数据。具体你可去试试。我只提供个思路给你。
      

  2.   

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ClientDataSet1.Active := false;
      ClientDataSet1.IndexFieldNames := 'Field_Name';
      ClientDataSet1.Active := true;
    end;
      

  3.   

    当然可以,也可以考虑取数据的时候用sql语句直接排序
      

  4.   

    谢谢!那再请问对应的DBGrid有打开行号的功能吗?即无论用户怎么排序,行号都不动不乱
      

  5.   

    procedure TForm1.Button1Click(Sender: TObject);
    var SavePlace: TBook;
    begin
      with ClientDataSet1 do
      begin
        SavePlace := GetBook;
        try
          Active := false;
          IndexFieldNames := 'id';
          Active := true;
          GotoBook(SavePlace);
        finally
          FreeBook(SavePlace);
        end;
      end;
    end;
    {注:用TBook}
      

  6.   

    楼上的BookMark好象只是能找到原先的位置,但不是提供打开行号功能吧?
      

  7.   

    在TClientDataSet中人工加入一个计算字段。然后写事件OnCalcFields的处理过程如下:procedure TForm1.ClientDataSet1CalcFields(DataSet: TDataSet);
    begin
      DataSet.FieldByName(计算字段名字).AsInteger := DataSet.RecNo;
    end;
      

  8.   

    我觉得直接给SQL语句排序就可以了!
      

  9.   

    ”那再请问对应的DBGrid有打开行号的功能吗?即无论用户怎么排序,行号都不动不乱”?hehe,楼主的行号若是通過计算字段(DataSet.RecNo)取得的、 
    重新排序時、行号就会自動重排...
      

  10.   

    TO: lxpbuaa(桂枝香在故国晚秋) 谢谢,我试了下,如下:
    var cds:TClientDataSet;cds:=TClientDataSet.create(nil);
    with cds.FieldDefs.AddFieldDef do begin
             
    Name:='ORDER';
     dataType:=ftInteger;
     end;//创建其他列cds.createDataSet;cds.Fields[0].FieldKind:=fkCalculated;//到这一句出错
    cds.Active := true;
    cds.Fields[0].DisplayLabel:='行号';
    cds.Fields[0].Visible:=True;
    cds.Fields[0].DisplayWidth:=5;
    //...在上面注释出错处提示:Cannot do this operation on an open dataSet.
    于是我在那句之前加上cds.Active:=false;
    可依然出错,提示:Out of bounds(0)请问这是什么原因?谢谢!!
      

  11.   

    var
      cds: TClientDataSet;
      Field: TField;
    begin
      cds := TClientDataSet.create(nil);
      Field := TIntegerField.Create(cds);
      Field.FieldName := 'ORDER';
      Field.DataSet := cds;
      Field.FieldKind := fkCalculated;
      Field.DisplayLabel:='行号';
      Field.DisplayWidth :=5;  with cds.FieldDefs.AddFieldDef do begin
        Name := 'ORDER';
        dataType := ftInteger;
       end;
      cds.createDataSet;
    //……
    end;————————————————————————————————————
    宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
    ————————————————————————————————————
      

  12.   

    TO: lxpbuaa(桂枝香在故国晚秋) 还是不行,结合你的代码如下:var
      cds: TClientDataSet;
      Field: TField;
    begin
      cds := TClientDataSet.create(nil);
      Field := TIntegerField.Create(cds);
      Field.FieldName := 'ORDER';
      Field.DataSet := cds;
      Field.FieldKind := fkCalculated;
      Field.DisplayLabel:='行号';
      Field.DisplayWidth :=5;  with cds.FieldDefs.AddFieldDef do begin
        Name := 'ORDER';
        dataType := ftInteger;
       end;
       
      Filed.destroy;//发现此处若不Destroy掉后面将不能再加入其他列了!  //加入其他列
      cds.createDataSet;  showmessage(BoolToStr(cds.Fields[0].FieldKind=fkCalculated));//结果为0,说明上段代码并未将Field实质性的加入数据集中,并且在DBGrid中也不会显示DisplayLabel而是'ORDER',说明整个定义Field的过程并没有起到作用,也就不能触发OnCalcFields事件。
    //……
    end;希望能继续解答这个问题,谢谢!!
      

  13.   

    写一过程。
    如果用ehlib控件里的DbGridEh(在TitleBtnClick中加入这过程就行).
    procedure dgsort(Column: TColumnEh); //DbGridEh. 如果是DbGrid则是TColumn
    const
     cnUpArrow='↑';
     cnDownArrow='↓';
     procedure ClearArrow(Column: TColumnEh);
     const
       cnArrowLen=2;
     var
       i, iPos : integer;
       sTmp : string;
     begin
       with Column.Grid as TDBGridEh do begin
         for i:=  0 to Columns.Count -1 do begin
           sTmp := Columns.Items[i].Title.Caption;
           if sTmp='' then
             Continue;
           iPos := Pos(cnUpArrow,sTmp);
           if (iPos<>0)and(iPos<=cnArrowLen)  then begin
             sTmp := Copy(sTmp,cnArrowLen+1,High(Integer));
             Columns.Items[i].Title.Caption := sTmp;
           end
           else begin
             iPos := Pos(cnDownArrow,sTmp);
             if (iPos<>0)and(iPos<=cnArrowLen)  then
               sTmp := Copy(sTmp,cnArrowLen+1,High(Integer));
               Columns.Items[i].Title.Caption := sTmp;
           end;
         end;
       end;
     end;
    begin
     if not Assigned(Column.Grid.DataSource) then   Exit;
     if not Assigned(Column.Grid.DataSource.DataSet) then  Exit;
     with (Column.Grid.DataSource.DataSet as TClientDataset) do 
     begin
       ClearArrow(Column);        
       if Pos('IndexDesc',IndexName)<>0 then
       begin
         AddIndex(Column.FieldName + 'Index', Column.FieldName, [],'', '', 0);
         IndexName := Column.FieldName + 'Index';
         Column.Title.Caption :=cnDownArrow+ Column.Title.Caption;
       end 
       else 
       begin
         AddIndex(Column.FieldName + 'IndexDesc', Column.FieldName, [ixDescending],'', '', 0);
         IndexName := Column.FieldName + 'IndexDesc';
         Column.Title.Caption :=cnUpArrow+ Column.Title.Caption;
       end;
     end;end;
      

  14.   

    ClientDataSet1.IndexFieldNames := '...';