主从关系表数据显示问题(从表的列动态创建,列的数量是可变的)

xmwgp 2010-11-26 10:25:55
主从关系表的显示:
主表数据来源是一个有固定列数的查询,
从表数据来源的查询,列数是不固定的(ACCESS,交叉表查询)
通过:
for i := 0 to DM.ADOQProQry2.FieldCount - 1 do
begin
dxDBGrid3.CreateColumn(TdxDBGridColumn);
dxDBGrid3.Columns[i].FieldName := DM.ADOQProQry2.Fields.Fields[i].FieldName;
end;
动态创建的列。
问题:刚刚执行查询,主从表数据都可以正常显示,当主表的选择当前行外的其它记录时,
系统提示错误:
在对应所需名称或序数的集合中,未找到项目。
在主表的 OnDataChange 的事件中添加这添加这部分创建列代码,也是还有同样的错误。
这个该怎么解决 ?
...全文
166 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
goodhj 2010-11-26
  • 打赏
  • 举报
回复
你的应用是主表记录滚动一下,从表的数据集就变化,而且从表的列及列数变了,是这样的吗?

那假如ADOQUEY1是主,ADOQUERY2是从,只是概念上的,不要去实际设置主从关系什么MasterDataSource之类的,是两个独立的数据集,在ADOQUEY1的AfterScorll事件中来实现关联
procedure TForm1.ADOQuery1AfterScroll(DataSet: TDataSet);
begin
dxDBGrid3.Columns.Clear;
with doquery2 do
begin
。。。。
end;
//实现dxDBGrid3列生成,
end;
xmwgp 2010-11-26
  • 打赏
  • 举报
回复
这样也是不行。
主表的数据集,也只有点击“查询”的时候Open一次。
然后在出现的数据中,更换选择主表的不同记录时,就没有重新打开数据集了。
goodhj 2010-11-26
  • 打赏
  • 举报
回复
while FrmTotal.dxDBGrid3.ColumnCount > 0 do
FrmTotal.dxDBGrid3.Columns[0].Destroy;

改成
dxDBGrid3.Columns.Clear;
这样不行吗?

既然是主从表,你可以在主表的AfterOpen事件中来实现你的代码,OnDataChange事件是不合适的
Believe 2010-11-26
  • 打赏
  • 举报
回复
学习,UP
xmwgp 2010-11-26
  • 打赏
  • 举报
回复
在从表DATASOURCE的 OnDataChange 事件中,有先删除原先的列:

while FrmTotal.dxDBGrid3.ColumnCount > 0 do
FrmTotal.dxDBGrid3.Columns[0].Destroy;

然后再根据从表的数据源重新创建列:

for i := 0 to DM.ADOQProQry2.FieldCount - 1 do
begin
dxDBGrid3.CreateColumn(TdxDBGridColumn);
dxDBGrid3.Columns[i].FieldName := DM.ADOQProQry2.Fields.Fields[i].FieldName;
end;


还是一样会有错误。

应该在什么事件中进行这步操作,试了很多事件都没什么用。
goodhj 2010-11-26
  • 打赏
  • 举报
回复
是不是应该把原先的列先全部清除掉然后在动态创建呢?
goodhj 2010-11-26
  • 打赏
  • 举报
回复
是不是应该把原先的列先全部掉然后在动态创建呢?
xmwgp 2010-11-26
  • 打赏
  • 举报
回复
查询的SQL执行查询时没有出现错误。

执行完查询时,主从表数据显示都正常,
是当主表换行时,从表的列数发生变化时出现的错误。
hongqi162 2010-11-26
  • 打赏
  • 举报
回复
检查一下你的查询过程,可能是哪里查询出现了问题
xmwgp 2010-11-26
  • 打赏
  • 举报
回复
查询语句是:

TRANSFORM First(PRODUCTRecord.[REALWEIGHT]) AS REALWEIGHT之First
SELECT Left(RQ0000,8)&PLANID&PFID00&BANCI AS ID00,
PRODUCTRecord.[PCNUM] AS 批次号, PRODUCTRecord.[BEGINT] as 时间, PRODUCTRecord.[TOTWEIGHT]
FROM PRODUCTRecord
WHERE Left(RQ0000,8)&PLANID&PFID00&BANCI = :ID00
GROUP BY PRODUCTRecord.[PCNUM], PRODUCTRecord.[BEGINT], PRODUCTRecord.[TOTWEIGHT],
Left(RQ0000,8)&PLANID&PFID00&BANCI
PIVOT PRODUCTRecord.[YPCODE]

把主从表单独,不设置关联,在查询的时候再给从表参数赋值,
这样真的是可以了。
谢谢 goodhj,也谢谢各位回帖的关注!
xmwgp 2010-11-26
  • 打赏
  • 举报
回复
操作:
有一个查询按钮,单击“查询”的时候,主从表数据都可以正常的显示出来,
然后移动主表的记录到不同的记录时,就出现那个错误。
goodhj 2010-11-26
  • 打赏
  • 举报
回复
。。。。
就是不知道那个错误是什么时候触发的。

那你就说是主从数据显示的问题。。。。

只能你自己看看在执行什么操作的时候会报那错误,然后自己从执行那操作一开始的地方下断点,一句句的跟踪,我们帮不上了
xmwgp 2010-11-26
  • 打赏
  • 举报
回复
ADOQProQry2 的 sql 语句是写在 query 的sql 属性中,固定,没有在程序中改变的。

sql 语句是 ACCESS 数据库的交叉表查询,所以列的数量是变化的。

现在又出现,要打开ADOQProQry2的SQL 时:RichEdit Line Insertion error。还可以 Active。

读不到sql语句了,刚刚还是好好可以的。一会还读不到,我重新创建个 ADOQProQry2。然后再把sql贴上来。

就是不知道那个错误是什么时候触发的。

出错时,程序跳转到控件的:

procedure TCustomdxDBTreeListControl.AssignNodeValues(ANode: TdxDBTreeListControlNode; AColumn: TdxDBTreeListColumn);
begin
AColumn.AssignNodeValues(ANode);
end;

这个的 end 语句。
goodhj 2010-11-26
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 xmwgp 的回复:]
设断点调试时,在触发 ADOQProQry1AfterScroll 事件之前,
就会先出现:
在对应所需名称或序数的集合中,未找到项目。
这个错误了。
[/Quote]
那就是你其他地方出错了,跟主从数据没有关系
goodhj 2010-11-26
  • 打赏
  • 举报
回复
DM.ADOQProQry2的SQL文怎么写的?叫你贴全就是想看你SQL文那段怎么写的,怀疑你SQL没CLEAR,要类似这样
DM.ADOQProQry2.close;
DM.ADOQProQry2.sql.clear;
DM.ADOQProQry2.sql.add('');
DM.ADOQProQry2.open;
在procedure TDM.ADOQProQry1AfterScroll(DataSet: TDataSet);中下断点跟踪到哪一句出的错?

如果你DM.ADOQProQry2结果集的字段是不变的话就没必要在TDM.ADOQProQry1AfterScroll事件中做字段显示处理,在AfterOpen事件中处理一次就够了,如果是有变化的就得像现在这样处理,
kye_jufei 2010-11-26
  • 打赏
  • 举报
回复
i:=qry_kyesb.Fields.Count;
cxGrid1.BeginUpdate;
cxGrid1DBTableView1.BeginUpdate;
cxGrid1DBTableView1.ClearItems;
for iLoop:=0 to i-1 do
begin
FColumn:=cxGrid1DBTableView1.CreateColumn;
FColumn.DataBinding.FieldName:=qry_kyesb.Fields[iLoop].FieldName;
FColumn.HeaderAlignmentHorz:=taCenter;
FColumn.Name:='cxGrid1DBTableView1Column'+ IntToStr(iLoop+1);
FColumn.Width:=95;
FColumn.OnGetDisplayText:=nil;
end;
cxGrid1DBTableView1.DataController.Refresh;
cxGrid1DBTableView1.EndUpdate;
cxGrid1.EndUpdate;
finally
Screen.Cursor:=crDefault;
FreeAndNil(RES_LOADING_F);
end;
xmwgp 2010-11-26
  • 打赏
  • 举报
回复
设断点调试时,在触发 ADOQProQry1AfterScroll 事件之前,
就会先出现:
在对应所需名称或序数的集合中,未找到项目。
这个错误了。
xmwgp 2010-11-26
  • 打赏
  • 举报
回复
事件的全部代码也是差不多:

procedure TDM.ADOQProQry1AfterScroll(DataSet: TDataSet);
var
i: Integer;
begin
DM.ADOQProQry2.Parameters.ParamByName('ID00').Value := DM.ADOQProQry1.FieldByName('ID00').AsString;
if DM.ADOQProQry2.Active = True then DM.ADOQProQry2.Close;
DM.ADOQProQry2.Active := True;
if FindComponent('FrmTotal.dxDBGrid3') <> nil then
begin
while FrmTotal.dxDBGrid3.ColumnCount > 0 do
FrmTotal.dxDBGrid3.Columns[0].Destroy;

for i := 0 to DM.ADOQProQry2.FieldCount - 1 do
begin
FrmTotal.dxDBGrid3.CreateColumn(TdxDBGridColumn);
FrmTotal.dxDBGrid3.Columns[i].FieldName := DM.ADOQProQry2.Fields.Fields[i].FieldName;

if DM.ADOQProQry2.Fields.Fields[i].FieldName = 'ID00' then
begin
FrmTotal.dxDBGrid3.Columns[i].Visible := False;
end;

if DM.ADOQProQry2.Fields.Fields[i].FieldName = '时间' then
begin
FrmTotal.dxDBGrid3.Columns[i].Width := 70;
FrmTotal.dxDBGrid3.Columns[i].Alignment := taCenter;
FrmTotal.dxDBGrid3.KeyField := DM.ADOQProQry2.Fields.Fields[i].FieldName;
end;
end;
end;
end;
goodhj 2010-11-26
  • 打赏
  • 举报
回复
while FrmTotal.dxDBGrid3.ColumnCount > 0 do
FrmTotal.dxDBGrid3.Columns[0].Free; // 没有 clear,用 Free 和 Destory一样。
for i := 0 to DM.ADOQProQry2.FieldCount - 1 do
begin
FrmTotal.dxDBGrid3.CreateColumn(TdxDBGridColumn);
FrmTotal.dxDBGrid3.Columns[i].FieldName := DM.ADOQProQry2.Fields.Fields [i].FieldName;
end;
处理显示这段代码我测试过,应该是没问题的
下断点自己跟踪下,
把procedure ADOQProQry1AfterScroll(DataSet: TDataSet);的代码贴全出来看看,

Versus1008 2010-11-26
  • 打赏
  • 举报
回复
删除列 貌似要从后往前删

while FrmTotal.dxDBGrid3.ColumnCount > 0 do
FrmTotal.dxDBGrid3.Columns[FrmTotal.dxDBGrid3.ColumnCount-1].Destroy;
加载更多回复(1)

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧