我的情况是这样的:用ADOquery+DBGrid作为输入界面,DBGrid中只有ADOQuery的部分的栏位,包括'单价,数量',希望增加一个新栏位'金额',它和值应该为'单价*数量',用以显示用户的输入结果,最终并不会把'金额'存放到远程表上去。但是,这里有一些特殊情况不好办:
    ADOquer是动态的,包括它的连接字串,SQL.text等都是动态生成的,一次一次的可能都不一样,在设计时期是不激活的(但远程表的结构总是相同的),也就是说在设计时期不大好操作dataset;
    在论坛中找到一些添加计算栏位的代码,都是要在dataset关闭的前提下才能加进去,那么我原来的栏位就不见了。我想,我目前的问题是个典型的基础问题,应该有正确的做法,只是我还不会。请教各位高人给予指点。多谢多谢!

解决方案 »

  1.   

    modify your sql to have a tryselect 单价,数量,单价*数量 as 金额
      from your_table
      

  2.   

    谢谢二位回答!TO qybao(阿宝) : 这个办法并不可行,我要求能即时地对用户输入做出反应,而不仅仅是对早先存贮在表中的 '单价,数量'做出反应。TO pinyu(品雨) :您可否再说清楚一些呢?比如在运行时期指定哪些属性。
      

  3.   

    在afteropen后加上添加计算字段不行吗?
      

  4.   

    to  Tensionli() :我做如下尝试,但代码在ADOQuery1.open之后,一直没有执行:procedure TForm1.ADOQuery1AfterOpen(DataSet: TDataSet);
    var Fld:Tfield;
    begin
      inherited;
      if (Fld<>nil) then exit;  if dataset.FindField('AMOUNT')<>nil then
        showmessage('已经存在了')
      else showmessage('还没有');  fld := TIntegerField.Create(nil);
      fld.DataSet   := ADOQuery1;
      fld.FieldName := 'AMOUNT';
      fld.FieldKind := fkCalculated;
      fld.Name:='NEWFLD';
    end;
      

  5.   

    //if (Fld<>nil) then exit;
    后可以执行了,但仍报错,说 "Can not perform this operation for open dataset",还是核心的问题,只能在关闭后才能添加。
    但是,在设计时期,即使dataset为激活状态,也可以添加新的Field,delphi自己就有办法这样做。如果能把这时delphi做的事情用代码表述出来就好了。真的纳闷啊~
      

  6.   

    用两个ADOQuery:ADOQuery1,ADOQuery2,将其SQL.Text设置成相同
    procedure TForm1.BitBtn1Click(Sender: TObject);
    var
      i: integer;
      T: tstringfield;
      T1: tstringfield;
    begin
      ADOquery2.open;
      ADOQuery1.Close;
      ADOquery1.fielddefs.clear;
      for i := 0 to ADOquery2.FieldDefs.Count - 1 do
        with ADOquery2.FieldDefs.Items[i].FieldClass.Create(self) do
        begin
          FieldName := ADOquery2.FieldDefs.Items[i].name;
          Name := ADOQuery1.Name + FieldName;
          size := ADOquery2.FieldDefs.Items[i].size;
          Index := i;
          DataSet := ADOQuery1;
        end;
      ADOQuery1.FieldDefs.UpDate;
      T := TStringField.Create(Self);
      T.FieldName := 'myfield';
      t.FieldKind := fkcalculated;
      T.Name := ADOQuery1.Name + T.FieldName;
      T.Index := ADOquery2.FieldDefs.Count;
      T.DataSet := ADOQuery1;
      ADOQuery1.FieldDefs.UpDate;
      ADOQuery1.Open;
    end;procedure TForm1.ADOQuery1CalcFields(DataSet: TDataSet);
    begin
      DataSet.FieldByName('myfield').Value:=DataSet.FieldByName('sum1').Value-DataSet.FieldByName('sum2').Value
    end;  
      

  7.   

    To LWH008 (LWH006的新帐号):
        不知道你是怎么操作的,首先用字段编辑器增加一个计算类型的字段;
        然后在计算字段的触发事件中写好计算字段的算法;
        最后每当程序触发计算字段事件时,计算字段的值将自动生成(激发条件一般是价格字段或数量字段被修改等等时候)。
      

  8.   

    I have no delphi and sql server in company
    or I can help you to test it
      

  9.   

    哈哈,终于搞定了! 就一个字:"骗"!
    (1)先给ADOquery补齐那些为了能激活它所缺少的部件,比如connection,sql.text等(本来是在运行时期才赋值的那些);
    (2)然后激活它,进入栏位编辑器,添加所有fields,再添一个计算栏位AMOUNT;
    (3)再到CalcFields中去写上公式。
    试运行,ok! 
    (4)拿掉第(1)步中补入的那些东西,再试运行,还是ok! 简直不敢相信啊!
    偷看了一下它的DFM文件,不过是在对ADOQuery1的定义中,嵌入了许多Field的定义,包括那个新增的计算栏位AMOUNT。感谢上面各位朋友的真情协助! 暂不结帖,看大伙还有没有更好的办法。