前辈,小弟初学DELPHI,现练习的工资程序要实现这摸个功能:通过在员工列表(person表)中双机
员工号,使主窗体的员工号输入框(i_person_id),然后再设置该员工的工资。相应的代码如下:
procedure TF_main.DBGrid1DblClick(Sender: TObject);
begin
  if DM_main.Q_person_list.Active then
    i_person_id.Text:=DM_main.Q_person_list['ID'];
end;i_person_id得到员工号后,有个判断,如果基本工资表中无此员工的记录,就添家之。代码如下:
procedure TF_main.i_person_idChange(Sender: TObject);
begin
  if (Pos(' ',i_person_id.Text)=0) and DM_main.Database.Connected then
  begin //判断输入完整并且数据库连接
    With DM_main do
    begin
      Q_person.Close;
      Q_person.Params.ParamValues['PERSON']:=i_person_id.Text;
      Q_person.Open;
      if Q_person.RecordCount=1 then
      begin
        i_person_name.Text:=Q_person['NAME'];
        //i_depart_id.Text:=Q_person['DEPARTMENT'];
        T_salary_set.Filter:='PERSON='''+i_person_id.Text+'''';
        T_salary_set.Filtered:=True;
        T_salary_set.Open;
        if T_salary_set.RecordCount=0 then
         T_salary_set.AppendRecord([i_person_id.Text,0]);
         T_salary_1.Filter:='T_salary_1='''+i_person_id.Text
          +''' AND YEARMONTH=''0000000''';
        T_salary_1.Filtered:=True;
        T_salary_1.Open;
        T_salary_2.Filter:='PERSON='''+i_person_id.Text
          +''' AND YEARMONTH='''+i_yearmonth.Text
          +''' AND OTHER_TYPE=''0''';
        T_salary_2.Filtered:=True;
        T_salary_2.Open;
        T_salary_3.Filter:='PERSON='''+i_person_id.Text
          +''' AND YEARMONTH='''+i_yearmonth.Text
          +''' AND (OTHER_TYPE=''1'' OR OTHER_TYPE=''2'')';
        T_salary_3.Filtered:=True;
        T_salary_3.Open;
        T_salary_4.Filter:='PERSON='''+i_person_id.Text
          +''' AND YEARMONTH='''+i_yearmonth.Text
          +''' AND OTHER_TYPE=''3''';
        T_salary_4.Filtered:=True;
        T_salary_4.Open;
      end;
      Q_person.Close;
    end;
  end
  else
  begin //数据不完整
    with DM_main do
    begin
      T_salary_set.Close;
      T_salary_1.Close;
      T_salary_2.Close;
      T_salary_3.Close;
    end;
    i_person_name.Text:='';
  end;
end;
其中的if T_salary_set.RecordCount=0 then
         T_salary_set.AppendRecord([i_person_id.Text,0]);
就是说如果表中无此员工的记录,就添家之。但再运行程序时,如果基本工资表中已经有此员工的记录,
程序也去添加,从而发生异常。
是FILTER表达式写的不对吗?
我用的是SQL SERVER 2000
    请各位前辈多多指点!!!
     小弟多谢了!!

解决方案 »

  1.   

    1. 设置断点,看看问题到底发生在哪一句
    2. 你的T_salary_1等是什么,query? table? clientdataset? ...?
    3. 我的感觉,一个数据集在设置filter之前要先关闭,设置完后再打开:
            T_salary_1.close;
            T_salary_1.Filter:='...........';
            T_salary_1.Filtered:=True;
            T_salary_1.Open;
    4. 查找特定数据集中是否有特定的记录,有很多方法:Locate, FindKey, GotoKey, setRange等;如果特定的记录只有一条,用Locate, Findkey可能更好些;filter, setRange适合筛选批量的数据(一家之言)
      

  2.   

    第一个问题:在每次给Filter赋值时,先将filtered置为false
    第二个问题:filter的值的引号问题,你要表达的意思很明显是:person="123"
    可在filter中不是这要写的,要这样写:'person='+''''(这个地方全是单引号)+i_person_id.text+''''如下面这个地方:
    T_salary_set.Filter:='PERSON='''+i_person_id.Text+'''';
            T_salary_set.Filtered:=True;
    改成:
            T_salary_set.Filtered:=false;
            T_salary_set.Filter:='PERSON=+''''+i_person_id.Text+'''';
            T_salary_set.Filtered:=True;其它地方类似。
      

  3.   

    TO oracle_lover(数据库情人)和wxlm:
         前辈,谢谢您的答复。昨天有点急事,问题没说清楚。这个工资程序段用到3个表,person表(员工基本信息表),salary-set表(基本工资表),salary-other表(其他工资项目表,例如固定福利津贴、月度奖金、月度福利津贴、扣发)。salary-set表的结构如下:/* Table: SALARY_SET, Owner: MISDBA */
    CREATE TABLE SALARY_SET (PERSON CHAR(6) NOT NULL,
            SALARY FLOAT,
    CONSTRAINT SALARY_SET_PEROSN PRIMARY KEY (PERSON));
    salary-other表结结构如下:/* Table: SALARY_OTHER, Owner: MISDBA */
    CREATE TABLE SALARY_OTHER (ID INTEGER NOT NULL,
            YEARMONTH CHAR(7) NOT NULL,
            PERSON CHAR(6) NOT NULL,
            OTHER_TYPE CHAR(1) NOT NULL,
            NAME VARCHAR(10) NOT NULL,
            MONEY FLOAT,
            DESCRIPTION VARCHAR(200),
    CONSTRAINT SALARY_OTHER_ID PRIMARY KEY (ID));其中的OTHER_TYPE CHAR(1) NOT NULL是类型(0奖金,1福利,2津贴,3扣发)。
    问题的起源是在设置基本工资时,最后一条记录只能保存员工号person,而工资SALARY没有被保存(仍然为默认值0)。???
    基本工资设置是这样实现的:双机员工列表中的员工号,使员工号输入框(i_person_id,TMASKEDIT)得到员工号,然后在基本工资输入框(i_salary: TDBEdit),这个TDBEdit的属性设置如下:
    DATASOURSE是DM——MAIN。DS——SALARY——SET(DM——MAIN是数据模块,DS——SALARY——SET的DATASET属性是T_salary_set,T_salary_set的tablename属性是salary_set),DATAFIELD属性是salary。
        输入完一个员工的基本工资后,双机员工列表中下一个员工号,上一条记录就保存了,但问题是设置完最后一个员工的基本工资时,没有下一个员工号可以双机,此时无论把光标移动到其他的任何地方,最后一条记录也只有员工号,而工资SALARY没有被保存(仍然为默认值0)。
         先前问的提示“不能在表中插入重复的记录”的原因就是在设置完最后一个员工的基本工资后,想通过双机其他员工号来移动记录指针来保存最后一条记录时
    违反了person在salary-set中是主键不能重复插入。
          今天我照你们说的先关闭filter,设置完后再打开,也是不行;
    wxlm说的T_salary_set.Filtered:=false;
            T_salary_set.Filter:='PERSON='+''''+i_person_id.Text+'''';
            T_salary_set.Filtered:=True;
    也过也不行,最后我改成加一个query1实现,如下:
    if Q_person.RecordCount=1 then
          begin
            i_person_name.Text:=Q_person['NAME'];
             with query1 do
              query1.close;
              query1.sql.clear;
              query1.sql.add('select * from  salary_set where PERSON='+''''+i_person_id.Text+'''');
              query1.open;
              T_salary_set.Open;
              if query1.RecordCount=0 then
              T_salary_set.AppendRecord([i_person_id.Text,0]);
              T_salary_1.Filter:='T_salary_1='''+i_person_id.Text
              +''' AND YEARMONTH=''0000000''';
            T_salary_1.Filtered:=True;
            T_salary_1.Open;
              .
              .
    这样到是不出“不能在表中插入重复的记录”的提示了,但也是不能保存最后一条记录的基本工资,前辈有什么方法可以实现 保存最后一条记录的基本工资?
    小弟多谢了!!!
    T_salary_set和T_salary_1,2,3,4都是TTABLE,T_salary_set的TABLENAME 
    是salary_set,T_salary_1,2,3,4的TABLENAME 都是T_salary_other(通过不同的过滤条件,分别在4个DBGRID中显示固定福利津贴、月度奖金、月度福利津贴、扣发,对他的具体介绍请看http://expert.csdn.net/Expert/topic/1271/1271309.xml?temp=.1529962