主从关系表的显示:
主表数据来源是一个有固定列数的查询,
从表数据来源的查询,列数是不固定的(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 的事件中添加这添加这部分创建列代码,也是还有同样的错误。
这个该怎么解决 ?

解决方案 »

  1.   

    查询的SQL执行查询时没有出现错误。执行完查询时,主从表数据显示都正常,
    是当主表换行时,从表的列数发生变化时出现的错误。
      

  2.   

    在从表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;
    还是一样会有错误。应该在什么事件中进行这步操作,试了很多事件都没什么用。
      

  3.   

    while FrmTotal.dxDBGrid3.ColumnCount > 0 do
      FrmTotal.dxDBGrid3.Columns[0].Destroy;改成
    dxDBGrid3.Columns.Clear;
    这样不行吗?既然是主从表,你可以在主表的AfterOpen事件中来实现你的代码,OnDataChange事件是不合适的
      

  4.   

    这样也是不行。
    主表的数据集,也只有点击“查询”的时候Open一次。
    然后在出现的数据中,更换选择主表的不同记录时,就没有重新打开数据集了。
      

  5.   

    你的应用是主表记录滚动一下,从表的数据集就变化,而且从表的列及列数变了,是这样的吗?那假如ADOQUEY1是主,ADOQUERY2是从,只是概念上的,不要去实际设置主从关系什么MasterDataSource之类的,是两个独立的数据集,在ADOQUEY1的AfterScorll事件中来实现关联
    procedure TForm1.ADOQuery1AfterScroll(DataSet: TDataSet);
    begin
     dxDBGrid3.Columns.Clear;
     with doquery2 do
      begin
      。
      end;
     //实现dxDBGrid3列生成,
    end;
      

  6.   

    procedure 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].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;
      end;
    end;在主表的AfterScroll事件中刷新(上面代码),也是和前面同样的错误。
      

  7.   

    删除列 貌似要从后往前删while FrmTotal.dxDBGrid3.ColumnCount > 0 do
      FrmTotal.dxDBGrid3.Columns[FrmTotal.dxDBGrid3.ColumnCount-1].Destroy;
      

  8.   

     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);的代码贴全出来看看,
      

  9.   

    事件的全部代码也是差不多: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;
      

  10.   

    设断点调试时,在触发 ADOQProQry1AfterScroll 事件之前,
    就会先出现:
      在对应所需名称或序数的集合中,未找到项目。
    这个错误了。
      

  11.   

    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;
      

  12.   

    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事件中处理一次就够了,如果是有变化的就得像现在这样处理,
      

  13.   

    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 语句。
      

  14.   

    查询语句是: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,也谢谢各位回帖的关注!