比方说:
用DBGrid显示ADOQuery的多表查询结果(一个学生成绩表)如下:
学号 姓名 性别 语文成绩 数学成绩
0001 张三 男 0 0
0002 李四 女 0 0
....
我现在想在DBGrid中修改各课成绩。我在DBGrid.OnColExit事件中编写代码,基本上能够实现修改。但有个小问题:就是在DBGrid中修该完0001学生的数学成绩后,将鼠标点击到0002号学生那行的时候,0001号数学成绩并没有改变,也就是说从一行换到另外一行ONColExit事件并没有触发!。。我该怎么办总不能要求用户修改完某条记录的最后一个字段的值后,还必须用鼠标点一下同一行的另外一个字段修改才生效吧。
大家经验比我丰富,碰到的情况比我多。。帮我想想用什么方法解决。
谢谢

解决方案 »

  1.   

    在OnColExit写事件是这样的,是在改变COL时触发事件
    另需要在DBGrid所连接的DataSource的onDataChange中写上OnColExit中的事件即可满足你的要求!
      

  2.   

    直接修改就是,光标移到另一行就能提交修改,不用写什么OnColExit事件....
      

  3.   

    hqhhh(枫叶) 我试了onDataChange事件,但行不通,可能是我没明白你的意思,,你能不能说详细一点。。谢谢。。  DBigrid显示的:学号 姓名 性别 语文 数学
    0001 张三 男 0 0
    0002 李四 女 0 0其中 ,语文成绩,数学成绩,不是实际存在的字段,都是子查讯形成的,所以我要取的某为学生的
    (学号,语文,成绩),(学号,数学,成绩)分别在singleScore(单课表)中修改他的各课成绩,所以不能象 smiler007(笑一笑) 那样回自动提交修改的必须自己在某个事件中编写修改代码。
    下面是我在DBGrid.OnColExit事件中写的代码,大家帮我看看:
    begin:
    if (DBGrid1.SelectedIndex<4) or(DBGrid1.SelectedField.FieldName='总分')  then
       exit;    //don't operate sname,sno,sgeny,scno if StarIsThere then
      begin
        with DBGrid1.SelectedField do
        begin
          TheLabel := DisplayLabel;
          Delete(TheLabel, 1, 2);
          DisplayLabel := TheLabel;
          CourseName:=DisplayLabel;
          score:=value;
        end;
      end; ENo:=CurrentENo;
     SNo:=dbgrid1.Fields[0].value;
     self.UpdateSingleScore(Eno,Sno,CourseName,Score);
      

  4.   

    不好意思。按错键了没写好就‘提交’。。更正:
    var
      Eno:integer;
      courseName,SNo:string;
      score:double;
    begin
      if (DBGrid1.SelectedIndex<4) then
       exit;    //don't update 学号,姓名,性别  SNo:=dbgrid1.Fields[0].value;          //get the SNo from the current Row of DBGrid
      CourseName:=DBGrid1.SelectedField.fieldName;//get the courseName 
      Score:=DBGrid1.SelectedField.value;           //get the score value
     
      self.UpdateSingleScore(Sno,CourseName,Score); //update the sudent's singlecourse scoreend;
    上一帖是我发错了,为了清晰点,我把我的代码,简要的列出来了大家帮忙,我的目的就是要在DBGrid中修改完某一单元格的值后,立即执行上面的代码谢谢我的表的结构:http://community.csdn.net/Expert/topic/4146/4146859.xml?temp=.213833
      

  5.   

    你不需要在DBGrid中写事件,
    应该改为:DBGrid所对应的数据集中的“语文”、“数学”字段的OnChange中写
    下面的例子只是按你定义的变量,定义的过程写的!
    procedure TForm1.ADOQuery1aaaChange(Sender: TField);
    var
      Eno:integer;
      courseName,SNo:string;
      score:double;begin
    begin
      SNo := Sender.DataSet.Fields.Fields[0].Value;
      courseName := Sender.FieldName;
      score := Sender.AsFloat;
      UpdateSingleScore(Sno,CourseName,Score); //update the sudent's singlecourse score
    end;
      

  6.   

    写错了一点:
    procedure TForm1.ADOQuery1aaaChange(Sender: TField);
    var
      Eno:integer;
      courseName,SNo:string;
      score:double;//begin //多个begin
    begin
      SNo := Sender.DataSet.Fields.Fields[0].Value;
      courseName := Sender.FieldName;
      score := Sender.AsFloat;
      UpdateSingleScore(Sno,CourseName,Score); //update the sudent's singlecourse score
    end;
      

  7.   

    hqhhh(枫叶) 不管怎么样非常感谢你的热心参与,谢谢。。
    但你的方法对我这种情况可能不合适:因为,我的数据集:ADOQuery1中的SQL是在程序中写的,原因是:那些科目更本不可能是固定下来的,不同的年级不同的考试的科目肯定会变的。
    高一考了语文,数学他们的成绩表就是:
    学号 姓名 性别 语文 数学
    0001 张三 男 0 0
    0002 李四 女 0 0
    但高二若考的是外语,物理,历史,那他们的成绩表就应该是:
    学号 姓名 性别 外语 物理  历史
    0003 王五 男 0 0     0
    0004 赵六 女 0 0     0所以ADOQuery1的SQl不能明确的写为类似如:
    select sno,sname,ssex, (select score from 学生课目成绩表 where sno=a.sno and CourseName='语文') as 语文, (select score from 学生课目成绩表 where sno=a.sno and cno='数学') as 数学from 学生表 a 我的解决方法是把各个年级某次考试的科目,保存在
    ExameCourse表(ENo,EGrade,CourseName...)中//考试代号,考试年级,该年级考试科目。这样在DBGrid中生成我们习惯的那种成绩格式的时候,先从ExameCourse表中取的当前考试的某个年级的所有考试科目,然后根据考试科目记录,用循环动态生成ADOQuery1的SQL语句。代码如下:
    数据集ADOQueryExameCourse返回该年级的考试科目查询集,sqlstr是需要生成的ADOQuery1的SQL语句。 //---create the sqlstr for  building one grade's scoretable such as:
     //---学号,班号,姓名,性别,数学,语文,外语,物理... 
     sqlstr:='select a.sno as 学号,b.Scno as 班号,sname as 姓名,sgeny as 性别 ';
     sqlstr1:=',(select score from singleScore where eno=:p0 and sno=a.sno and courseName=';
      
      while not ADOQueryExameCourse.Eof do
          //这个循环就是根据考试的课程生成:
          //(select score from 学生课目成绩表 where sno=a.sno and cno='数学') as 数学这部分
        begin
        course:=ADOQueryExameCourse.fieldbyname('courseName').AsString;
            //get coursename from the database table ExameCourse 
        sqlstr:=sqlstr+sqlstr1+''''+course+''''+')as '+course;
        adoquery1.Next;
        end;
      sqlstr:=sqlstr+' from student a,stuinclass b where a.sno=b.sno and cgrade=:p1 ';
      ADOQuery1.SQL.Add(sqlstr);//adoquery1,同DBGrid1相联的数据集
    //student:学生表,stuinclass:学生在班级中的信息表,
    //singleScore:真正的成绩表(Eno,sno,courseName,score)上面是我的生成普通显示格式,课程会变的代码,能实现我的要求,,现在就是在修改成绩的时候,不知道在哪个事件中写代码。。
      

  8.   

    其实同样可实现你的要求:
    方法如下:
    1.定义一个公共的过程
    procedure aaaChange(Sender: TField);
    var
      Eno:integer;
      courseName,SNo:string;
      score:double;
    begin
      SNo := Sender.DataSet.Fields.Fields[0].Value;
      courseName := Sender.FieldName;
      score := Sender.AsFloat;
      UpdateSingleScore(Sno,CourseName,Score); //update the sudent's singlecourse score
    end;2.在你打开的数据集中
    如果第4、5、6个字段需要修改,则设置如下:
      ADOQuery1.Fields.Fields[4].OnChange := aaaChange;
      ADOQuery1.Fields.Fields[5].OnChange := aaaChange;  
      ADOQuery1.Fields.Fields[6].OnChange := aaaChange;不知楼主还有什么不明白的吗?