逛遍了好多地方,找不到解决方法
    我在form里面分别放了cx_query1,ylcx_database1,datasource1,dbgrid1,在进入窗体的时候,
    dbgrid1列出了数据库中某个表的信息,我现在想用按钮来控制对dbgrid的增加,删除,修改,
    首先,我设置了一个按钮,这个按钮是用来查询的,然后查询的信息显示在dbgrid中,我现在要实现的功能是:
    再在窗体上增加两个按钮,一个叫修改,一个叫确定。当dbgrid显示出之前查询的记录时候,该dbgrid是只供浏览的,
    如果要对dbgrid中的某行记录进行修改,请问需要怎么做呢?而且修改的同时,只有对选中的该行进行修改,其他记录
    不能被编辑(显示灰色不可编辑),当对被选中的这条记录编辑完后,按另一个按钮确定,才对刚才的修改进行提交数据库操作
   哪位大虾能给个详细的代码吗,我试过好多方法,都不行    我之前试过的方法:
   1.比如将dbgrid中的options属性下的dbediting设成true 和将cx_query1的属性requeslive设成true,
     那么这样的结果则对于dbgrid每条记录都是可以修改,这并不是我要的;
   2.在设置datasource1下的dataset下的cachedupdates为true的时候,然后在按钮写ylcx_database1.commit则出现
     can not modiy a read-only dataset的错误,在之前其他的操作中也有类似的错误出现过   看了很多帖子,很多人都提到,用query作查询的时候,dbgrid返回的是一个read-only的数据子集,不能对其修改,如果要对
   其修改,需将requstlive设成true,其实还应该将dbgrid下的options下的dgediting设成true,这样才可以对其编辑,好郁 闷,研究了很久不知道怎样才能实现我要的功能,所以请个位路过的大哥大姐们给好好看一下,在线等,马上给分,谢谢了

解决方案 »

  1.   

    1、如果只改某一条数据可以将DBGrid设置为只读的,然后通过一个窗体用输入框的形式录入
    或者:
    初始默认为只读的,
    点修改按钮的时候变为可写记录上数据的记录号,如i:=Query1.RecNo;
    在Grid的OnKeyPress事件,
    if Query1.RecNo<>i then Key:=#0;
    提交后变为只读的。
    2、你数据集是只读的
      

  2.   

    你不如这样,将Dbgrid只作显示浏览用,设置为readonly;
    增加或者修改时,把这笔信息显示另外一个窗体的各个edit中,再进行操作!!Dbgrid不能只允许一行可以修改,其它行不可以修改的;
    要么全部可以修改,要么全部不可以修改!!!
      

  3.   

    用dbedit关联一下,在dbedit框中进行修改不就成了。
      

  4.   

    若只操作DBGrid其中一条记录,其它不允许操作
    可以控制数据集,用两个全局变量(I,J)把记录号保存下来
    初始化
    I:=-1; 
    J:=-1;
    DBGrid.Readonly:=True;procedure TForm1.Button1Click(Sender: TObject); //Button1修改按扭,保存记录号
    begin 
     DBGrid.Readonly:=false; 
     I:=ADOQuery1.RecNo;
      ....
    end;procedure TForm1.DBGridCellClick(Column: TColumnEh); //点击dbgrid某行,保存记录号
    begin
      J:=ADOQuery1.RecNo;
      If I<>J then //表示已经滚动了记录
         DBGrid.Readonly:=True; 
    end;在BeforeEdit中写代码:procedure TForm1.ADOQuery1BeforeEdit(DataSet: TDataSet);
    begin
       if I<>J then  //编辑前再控制一下,若当前记录号不是按修改键时的记录,将无法修改!
         abort;
    end;
      

  5.   

     to :KAIKAI  dunzimu
       我用其他的方法,用了一些dbedit控件来间接控制(多设置了这些控件不会和你的方法冲突吧),但是情况也不好,新的问题来了,你的方法我已经试过了,运行的时候和之前的情况一样会出错,错误是can not modify a read-only dataset,就是说之前查询返回的数据子集为只读状态,但是奇怪的事,我在程序中将其dbgrid.readonly设置为false时,也是同样报错,也不知道是什么原因。我自己尝试了在设计阶段将cx_query.requestlive设置成true的时候,就可以对之前设置的与之关联的dbedit进行修改来改变dbgrid中对应的字段的值,但是问题又来了,这样我就根本用不上query.edit了,从而不能对其修改功能控制;奇怪的事,我只能在在设计控件属性直接将cx_query1.requestlive设置成true,如果你在程序中写cx_query1.requestlive :=true;时,运行时也会出现can not modify a read-only dataset,感觉好变态啊,而且在写这句之前,我还特意加了dbgrid.readonly :=false防止其出现象不能编辑只读类似的错误,好郁闷啊,情况试了满多种的    不过还是感谢大家关注,希望大虾们能研究下我的情况,真的是很压抑我都开始在怀疑我装的delphi是不是有问题了呵呵
      

  6.   

    别人给了只是思路,不可能是100%的答案!!!TQuery的requestlive属性默认是false 表示sql执行后返回的结果集是只读的,即是不可修改的;
    像你的做法,要频繁的修改他的状态,这控制不好就是很严重的问题了!不过这样种要求,最好还是单独建一个窗口做修改,新增,保存等动作,Dbgrid仅作显示用.
      

  7.   

    谢谢,我后来也是用你说的方法去做了,
    现在有个问题,就是要怎样知道所点击DBGrid中的记录是第几条记录呢?我用的SQL SERVER,QERUY组件,
    对于小型的数据库用dbgrid.reco就可以得到正确答案,可是对于MSSQL数据库我也测试过好几次,
    也用过dataset.selectedindex,都没用,对于大型的数据库,这种办法行不通,测试的时候得到的值得都是-1,
    请问还有什么其他办法解决吗?最好是能给个详细的代码,本人比较菜,其中的20分准备给kaikai_kk的,其他的20分就给解决这个问题的人了,呵呵 再次谢谢各位,感觉从这里确实学到了好多东西...
      

  8.   


    dbgrid.reco 谁教你这样写的? dataset.selectedindex 又是干什么?
    操作的不是dbgrid的记录号,而数据集中的记录号这样,I:=(DBGrid1.DataSource.DataSet as TQuery).RecNo; 
    你不用管他返回的值是多少,你只要懂得,只要有数据,这个I就有值就行了!!!
      

  9.   

    首先非常感谢KAIKAI,那么晚了还来帮我解决问题,非常感谢!
    不好意思的是,可能是昨晚程序看花了眼了,我也是到处找答案,看多了,写错了,是query.reno,
    我才接触编程一个多月,非常抱歉,属于非常菜的那种,很多东西确实都是用蒙的(因为不知道其具体功能,只看那个函数或过程的英文字面的意思和我所想要的答案匹配,呵呵,但是还是有意识地去了解啦),所有大家不要被我误导,呵呵对于kaikai_kk大哥,叫大哥应该ok吧,真希望能拜你为师,有机会的话...I:=(DBGrid1.DataSource.DataSet as TQuery).RecNo;这个我也去试了,我在这个事件里面这样写:
    procedure Tylcx_form.DBGrid1CellClick(Column: TColumn);
    begin
      i :=(dbgrid1.DataSource.DataSet as Tquery).RecNo;
      edit4.Text :=inttostr(i);//用来做测试的,就是当我在dbgrid1里,点哪一行的时候,编辑框就显示相应纪录号
    end;当然,i是全局变量,在前面声明我在这边定义应该没错吧
    var
      ylcx_form: Tylcx_form;
      i :integer=1;
    implementation{$R *.dfm}做了这些之后,我获得的数据还是-1,即编译通过,运行程序,当我在dbgrid里点任意一个地方的时候,edit.texe的值总是等于-1;我错在哪里呢?这到底是什么原因呢?不好意思,我就是这么难缠给再给个详细的说明,不胜感激了!
      

  10.   


    var
      ylcx_form: Tylcx_form;
      i:integer;
    implementation{$R *.dfm}procedure Tylcx_form.DBGrid1CellClick(Column: TColumn);
    begin
      i:=DBGrid1.DataSource.DataSet.RecNo;
      edit4.Text:=inttostr(i);
    end;
      

  11.   

    你这个应该没有经过测试吧
    上面的我的全局变量的赋值方式是没错的,
    i:=DBGrid1.DataSource.DataSet.RecNo;这句我也已经试过了,
    我用的MSSQL的数据库,麻烦好像就是在这里。
      

  12.   

    谢谢,我现在也按照你说的做了一遍了,重新建了一个工程,然后简单的重新测试了一下,可结果还是-1啊...
    请问你用的数据库是MSSQL吗?
    怎么那么奇怪啊,SOS。
      

  13.   

    你一开始试点,第三或第四条记录,试试var
      ylcx_form: Tylcx_form;
      i:integer;{-----------------------留意这里}
    implementation{$R *.dfm}procedure Tylcx_form.DBGrid1CellClick(Column: TColumn);
    begin
      i:=DBGrid1.DataSource.DataSet.RecNo;
      edit4.Text:=inttostr(i);
    end;
      

  14.   

    谢谢~
    你说的这个方式我也是试过啦,我还是试过在public里面定义,其实都是一样的,
    症状就是这样,一运行,首先你不点dbgrid的任何地方的时候,edit4编辑框是没显示的,默认显示的是edit4;
    而当你点击dbgrid的时候,就象你说的,一开始不要点第一行,点其他地方,就直接开始变成-1了,之后再点其他地方的话,就没改变了,edit4就直接一直显示着-1
    会不会是我dbgrid里面有什么属性的东西没设置呢,该开的我都开了呀
    继续SOS....