我给dbGrid的TitleClick事件中加入了排序的功能,就是ADOQuery.Sort:='...',
但是问题出现了,随意选择某列进行排序后,我再移动主表纪录(上一条,下一条),发现从表纪录过滤不出来了或者报计数错误,跟踪vcl的代码,结果发现他是根据IndexFields进行SetDetailFilter的,而不是MasterField,最终,LinkField变成了刚才排序的字段,倘若这个字段不是建立主从关系的字段的话,就造成过滤不到从表纪录了。他的排序改变了IndexField,但是SetDetailFilter的时候又把LinkField设置为IndexField,delphi为何这么做?到底是我的问题还是delphi的问题呢?
后来我在主表BeforeScroll中把IndexField变为MasterField就结果正常了,哎,我不知道该怎么表达我的心情了!
(delphi6+ADO+oracle8i,c/s,两层结构)
大家说说吧!也祝大家新年快乐!
但是问题出现了,随意选择某列进行排序后,我再移动主表纪录(上一条,下一条),发现从表纪录过滤不出来了或者报计数错误,跟踪vcl的代码,结果发现他是根据IndexFields进行SetDetailFilter的,而不是MasterField,最终,LinkField变成了刚才排序的字段,倘若这个字段不是建立主从关系的字段的话,就造成过滤不到从表纪录了。他的排序改变了IndexField,但是SetDetailFilter的时候又把LinkField设置为IndexField,delphi为何这么做?到底是我的问题还是delphi的问题呢?
后来我在主表BeforeScroll中把IndexField变为MasterField就结果正常了,哎,我不知道该怎么表达我的心情了!
(delphi6+ADO+oracle8i,c/s,两层结构)
大家说说吧!也祝大家新年快乐!
不过我的排序不是用你所说的方法(因为我不会 : ) ),而是用了我自己的方法。
http://expert.csdn.net/Expert/topic/2518/2518696.xml?temp=.3603174
全部源码如下: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.
按照非主从表关联字段排序从表后,你移动主表纪录位置,或者新增从表纪录都会出错的。我跟踪vcl代码发现排序后IndexFieldName就变化了,但是delphi还是把LinkField设置为了IndexField,能不出错么?如果刚才排序的从表字段的类型和关联字段的类型不兼容,还会引发变体类型转换错误。
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
----------------
我没试过添加新数据,但浏览时,不论按任何字段排序,肯定没问题
然後在從表的BeforeInsert中也做同樣的操作,然後就正常了。哎
不知道我表达清楚没有,赫赫。通常在这种情况下,我从表的数据都是自己使用sql语句重新提取(数据集不设置主从表关系),因为对于Delphi数据绑定控件,我总觉得还是有不少用起来很不爽的地方。 最高兴的还是看到你的这句话“此貼當散分貼吧”:D