我给dbGrid的TitleClick事件中加入了排序的功能,就是ADOQuery.Sort:='...',
但是问题出现了,随意选择某列进行排序后,我再移动主表纪录(上一条,下一条),发现从表纪录过滤不出来了或者报计数错误,跟踪vcl的代码,结果发现他是根据IndexFields进行SetDetailFilter的,而不是MasterField,最终,LinkField变成了刚才排序的字段,倘若这个字段不是建立主从关系的字段的话,就造成过滤不到从表纪录了。他的排序改变了IndexField,但是SetDetailFilter的时候又把LinkField设置为IndexField,delphi为何这么做?到底是我的问题还是delphi的问题呢?
后来我在主表BeforeScroll中把IndexField变为MasterField就结果正常了,哎,我不知道该怎么表达我的心情了!
(delphi6+ADO+oracle8i,c/s,两层结构)
大家说说吧!也祝大家新年快乐!

解决方案 »

  1.   

    没人捧场?太过份了!borland让我又爱又恨,  :)
      

  2.   

    帮你UP从表自己用Query取,不用本身的属性。
      

  3.   

    我刚才试了一下,没你所说的问题。
    不过我的排序不是用你所说的方法(因为我不会 : ) ),而是用了我自己的方法。
    http://expert.csdn.net/Expert/topic/2518/2518696.xml?temp=.3603174
      

  4.   

    VeryOldMan(老者) :我用的排序方法和你几乎一样
      

  5.   

    最好升级Delphi.因为我在D7没有发觉有你这样的问题.
      

  6.   

    是这样的,如果你用ClientDataSet应该就没有这样的问题了。
      

  7.   

    确实是delphi的bug,在使用ehlib控件中也有类似错误,只能对主表排序。
      

  8.   

    我就是在D7下使用的,确实没问题。
    全部源码如下:object Form1: TForm1
      Left = 192
      Top = 107
      Width = 696
      Height = 480
      Caption = 'Form1'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object Splitter1: TSplitter
        Left = 0
        Top = 201
        Width = 688
        Height = 3
        Cursor = crVSplit
        Align = alTop
      end
      object Panel1: TPanel
        Left = 0
        Top = 0
        Width = 688
        Height = 57
        Align = alTop
        TabOrder = 0
        object DBNavigator1: TDBNavigator
          Left = 8
          Top = 8
          Width = 240
          Height = 25
          DataSource = DataSource1
          TabOrder = 0
        end
      end
      object DBGrid1: TDBGrid
        Left = 0
        Top = 57
        Width = 688
        Height = 144
        Align = alTop
        DataSource = DataSource1
        TabOrder = 1
        TitleFont.Charset = DEFAULT_CHARSET
        TitleFont.Color = clWindowText
        TitleFont.Height = -11
        TitleFont.Name = 'MS Sans Serif'
        TitleFont.Style = []
        OnTitleClick = DBGrid1TitleClick
      end
      object DBGrid2: TDBGrid
        Left = 0
        Top = 204
        Width = 688
        Height = 249
        Align = alClient
        DataSource = DataSource2
        TabOrder = 2
        TitleFont.Charset = DEFAULT_CHARSET
        TitleFont.Color = clWindowText
        TitleFont.Height = -11
        TitleFont.Name = 'MS Sans Serif'
        TitleFont.Style = []
      end
      object ADOQuery1: TADOQuery
        Active = True
        Connection = ADOConnection1
        CursorType = ctStatic
        Parameters = <>
        SQL.Strings = (
          'Select * From sfjl')
        Left = 136
        Top = 168
      end
      object ADOConnection1: TADOConnection
        Connected = True
        ConnectionString = 
          'Provider=Microsoft.Jet.OLEDB.4.0;Password="";Data Source=E:\wygl' +
          '_BAK.mdb;Persist Security Info=True'
        LoginPrompt = False
        Mode = cmShareDenyNone
        Provider = 'Microsoft.Jet.OLEDB.4.0'
        Left = 56
        Top = 168
      end
      object DataSource1: TDataSource
        DataSet = ADOQuery1
        Left = 168
        Top = 168
      end
      object DataSource2: TDataSource
        DataSet = ADOTable1
        Left = 184
        Top = 296
      end
      object ADOTable1: TADOTable
        Active = True
        Connection = ADOConnection1
        CursorType = ctStatic
        IndexFieldNames = 'XQBH;HZBH'
        MasterFields = 'XQBH;HZBH'
        MasterSource = DataSource1
        TableName = 'SFMX'
        Left = 152
        Top = 296
      end
    end---------------------------------------
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ADODB, DB, ExtCtrls, Grids, DBGrids, DBCtrls;type
      TForm1 = class(TForm)
        Panel1: TPanel;
        DBGrid1: TDBGrid;
        DBGrid2: TDBGrid;
        Splitter1: TSplitter;
        ADOQuery1: TADOQuery;
        ADOConnection1: TADOConnection;
        DataSource1: TDataSource;
        DataSource2: TDataSource;
        ADOTable1: TADOTable;
        DBNavigator1: TDBNavigator;
        procedure DBGrid1TitleClick(Column: TColumn);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.DBGrid1TitleClick(Column: TColumn);
    {$J+}
     const PreviousColumnIndex : integer = 0;
    {$J-}
    begin
      if DBGrid1.FieldCount = 0 then
         Exit;
      if DBGrid1.DataSource.DataSet is TCustomADODataSet then
         with TCustomADODataSet(DBGrid1.DataSource.DataSet) do
         begin
           try
             DBGrid1.Columns[PreviousColumnIndex].title.Font.Style :=
             DBGrid1.Columns[PreviousColumnIndex].title.Font.Style - [fsBold];
           except
           end;
           Column.title.Font.Style := Column.title.Font.Style + [fsBold];
           PreviousColumnIndex := Column.Index;
           if (Pos(Column.Field.FieldName, Sort) = 1)
                and (Pos(' DESC', Sort)= 0) then
              Sort := Column.Field.FieldName + ' DESC'
           else
              Sort := Column.Field.FieldName + ' ASC';
         end;
    end;end.
      

  9.   

    这个不一定叫做BUG,可能是VCL的局限性,我现在好多需要排序的从表的SQL,都是自己写,因为VCL提供的的确不爽。
      

  10.   

    VeryOldMan(老者):你的排序方法和我的一样,你是使用在主从表当中么?如果是单表当然没有任何问题。但是如果为主从表结构的,则肯定出错。
    按照非主从表关联字段排序从表后,你移动主表纪录位置,或者新增从表纪录都会出错的。我跟踪vcl代码发现排序后IndexFieldName就变化了,但是delphi还是把LinkField设置为了IndexField,能不出错么?如果刚才排序的从表字段的类型和关联字段的类型不兼容,还会引发变体类型转换错误。
      

  11.   

    这个不一定叫做BUG,可能是VCL的局限性,我现在好多需要排序的从表的SQL,都是自己写,因为VCL提供的的确不爽。
      

  12.   

    你看下面一段:
      object ADOTable1: TADOTable
        Active = True
        Connection = ADOConnection1
        CursorType = ctStatic
        IndexFieldNames = 'XQBH;HZBH'
        MasterFields = 'XQBH;HZBH' //<font color="red">说明存在主从关系</font>
        MasterSource = DataSource1 //<font color="red">说明存在主从关系</font>
        TableName = 'SFMX'
        Left = 152
        Top = 296
      end
    ----------------
    我没试过添加新数据,但浏览时,不论按任何字段排序,肯定没问题
      

  13.   

    我不得不在主表的BeforeScroll中把從表的IndexFieldNames改為MasterFields,
    然後在從表的BeforeInsert中也做同樣的操作,然後就正常了。哎
      

  14.   

    其实取从表数据是否应该也应该用查询方式呢?对于设置了主从表关系的数据集,我没有跟踪过相应的代码,不知道在主表Scroll时,从表的数据是在从表数据集中过滤还是根据主表的masterField的值重新从数据库提取数据。
        不知道我表达清楚没有,赫赫。通常在这种情况下,我从表的数据都是自己使用sql语句重新提取(数据集不设置主从表关系),因为对于Delphi数据绑定控件,我总觉得还是有不少用起来很不爽的地方。    最高兴的还是看到你的这句话“此貼當散分貼吧”:D
      

  15.   

    补充一下我的意思,如果主表scroll时从表数据的提取是过滤方式的话,那对于数据量比较大的情况就不适合使用主从表的关系数据集的方式了
      

  16.   

    不知道楼主改用BDE试试会不会有这个问题
      

  17.   

    當主表scroll的時候,從表數據是靠過濾來和主表對應的。adoTable是一下子打開,獲取全部數據的。如果從表數據量很大,這樣是不大好。但是本地數據集合的操作比sql語句通過網絡取數據應該是要快的。我覺得使用感知控件可以省略很多代碼,我不相信自己能比borland的人厲害,既然他提供了,就使用。