用cxgrid遍历来修改数据,是用ado的eof,和cxGrid1DBTableView1.DataController.IsEOF ,cxGrid1DBTableView1.Controller.FocusedRow.IsLast 来判断是否到末位,但还是越界了,求各位大大看看
procedure TfrmBatchExtend.sbtnExtendClick(Sender: TObject);
var
  rowIndex: Integer;
  q: TADOQuery;
  sDate, sName, s: string;
  f: TIniFile;
begin
  if (eExtend.Text = '0') or (eExtend.Text = '') then
  begin
    ShowMessage('延期月份最少为1个月');
    Exit;
  end;  f := TIniFile.Create(ExtractFilePath('D:\APark\APark.adf'));
  sName := f.ReadString('Options','LastUser','0001');  q := TADOQuery.Create(Self);
  q.ConnectionString := 'Provider=SQLOLEDB.1;Password=' + b_sPassword + ';Persist Security Info=True;User ID=sa;Initial Catalog=APark;Data Source=' + b_sDBServer;
  q.SQL.Text := 'select * from T1_Operator where mID = '+sName+'';
  q.Open;
  sName := q.FieldByName('Name').AsString;
  q.Close;
  q.SQL.Text := '';
  
  with qryBatch do
  begin
    if not Active then
     Open;
    rowIndex := 0;
    First;
    while not Eof  do
    begin
      if cxGrid1DBTableView1.ViewData.Records[rowIndex].Values[0] = null then
        Exit;
      if cxGrid1DBTableView1.ViewData.Records[rowIndex].Values[0] = '1' then
      begin
        Edit;
        //t3表修改有效期,t4表插入一条记录
        if FieldByName('Expiry').AsString = '' then
          FieldByName('Expiry').AsDateTime := Now;        sDate := FieldByName('Expiry').AsString;
        FieldByName('Expiry').AsDateTime := IncMonth(FieldByName('Expiry').AsDateTime,StrToInt(edtTemp.Text));        q.SQL.Add(' insert into t4_fee(mID,DateTime,FeeType,ExtendStart,ExtendEnd,FeeIndeed,FeeShould,Operator) '+
            'values('+FieldByName('mid').AsString+',getdate(),3,cast('+sDate+' as datetime)'+
            ',cast('+FieldByName('Expiry').AsString+' as datetime),'+eFeeTotal.Text+','+eFeeTotal.Text+','''+sName+''')');        q.ExecSQL;
      end;      if  (cxGrid1DBTableView1.ViewData.Records[rowIndex].Values[0] = '0') or
        (cxGrid1DBTableView1.ViewData.Records[rowIndex].Values[0] = '1') then
        Next;      Inc(rowIndex);      if cxGrid1DBTableView1.DataController.IsEOF then
        Exit;      if cxGrid1DBTableView1.Controller.FocusedRow.IsLast then
        Exit;
    end;
    Edit;
    UpdateBatch(arAll);
    q.Destroy;
  end;
end;

解决方案 »

  1.   

          if  (cxGrid1DBTableView1.ViewData.Records[rowIndex].Values[0] = '0') or
            (cxGrid1DBTableView1.ViewData.Records[rowIndex].Values[0] = '1') then
            Next;
     
          Inc(rowIndex);每次不一定都执行了qrybatch.next; 但rowindex每次+1,在QRY.EOF=TRUE时,rowindex就会越界!!
      

  2.   


    因为需要进行group by,所以会多出group by 的行数,只能跳过去不赋值
      

  3.   

    你的数据集循环结构有问题
    1、要充分利用数据集的Eof判断语句。
    2、你的语句已到尾部,继续读入数据的错误。
    3、Next执行不应加入条件,这样会造成循环的不同步。  
    建议以下试试:
    procedure TfrmBatchExtend.sbtnExtendClick(Sender: TObject);
    var
      rowIndex: Integer;
      q: TADOQuery;
      sDate, sName, s: string;
      f: TIniFile;
    begin
      if (eExtend.Text = '0') or (eExtend.Text = '') then
      begin
        ShowMessage('延期月份最少为1个月');
        Exit;
      end;  f := TIniFile.Create(ExtractFilePath('D:\APark\APark.adf'));
      sName := f.ReadString('Options','LastUser','0001');  q := TADOQuery.Create(Self);
      q.ConnectionString := 'Provider=SQLOLEDB.1;Password=' + b_sPassword + ';Persist Security Info=True;User ID=sa;Initial Catalog=APark;Data Source=' + b_sDBServer;
      q.SQL.Text := 'select * from T1_Operator where mID = '+sName+'';
      q.Open;
      sName := q.FieldByName('Name').AsString;
      q.Close;
      q.SQL.Text := '';
      
      with qryBatch do
      begin
        if not Active then
         Open;
        rowIndex := 0;
        First;
        while not Eof  do
        begin
          Inc(rowIndex);
          if cxGrid1DBTableView1.ViewData.Records[rowIndex].Values[0] = null then
            Exit;
          if cxGrid1DBTableView1.ViewData.Records[rowIndex].Values[0] = '1' then
          begin
            Edit;
            //t3表修改有效期,t4表插入一条记录
            if FieldByName('Expiry').AsString = '' then
              FieldByName('Expiry').AsDateTime := Now;        sDate := FieldByName('Expiry').AsString;
            FieldByName('Expiry').AsDateTime := IncMonth(FieldByName('Expiry').AsDateTime,StrToInt(edtTemp.Text));        q.SQL.Add(' insert into t4_fee(mID,DateTime,FeeType,ExtendStart,ExtendEnd,FeeIndeed,FeeShould,Operator) '+
                'values('+FieldByName('mid').AsString+',getdate(),3,cast('+sDate+' as datetime)'+
                ',cast('+FieldByName('Expiry').AsString+' as datetime),'+eFeeTotal.Text+','+eFeeTotal.Text+','''+sName+''')');        q.ExecSQL;
          end;
          Next;
        end;
        Edit;
        UpdateBatch(arAll);
        q.Destroy;
      end;
    end;
      

  4.   


    http://image.baidu.com/detail/newindex?col=&tag=&pn=0&pid=35513963359&aid=401012732&user_id=1100643875&setid=-1&sort=0&newsPn=&star=&fr=&from=2
    因为group by后,group by的列也会当成一行,需要跳过去
      

  5.   

    或者说cxgrid中的groupbyBox 中的列下拉时的事件