jeudi 10 décembre 2015

The error 'Grid index out of range' when switching between the databases

This is the procedure to display the Customer Database:

    procedure TfrmMain.mnuCustomerClick(Sender: TObject);
    var
      j: integer;
    begin

      con := TFDConnection.Create(nil);
      query := TFDQuery.Create(con);
      con.LoginPrompt := False;
      con.Open('DriverID=SQLite;Database=C:\Users\katiee\Documents\Embarcadero\Studio\Projects\ProgramDatabase;');
      query.Connection := con;
      query.sql.Text := 'SELECT * FROM CustDatabase ORDER BY ID';
      query.Open();
      query.First;

      sgdDatabases.colCount := 9;
      sgdDatabases.FixedCols := 0;
      for j := 0 to sgdDatabases.rowCount do
      sgdDatabases.ColWidths[j] := 100;

      sgdDatabases.Cells[0, 0] := 'ID';
      sgdDatabases.Cells[1, 0] := 'First Name';
      sgdDatabases.Cells[2, 0] := 'Last Name';
      sgdDatabases.Cells[3, 0] := 'Address';
      sgdDatabases.Cells[4, 0] := 'Town';
      sgdDatabases.Cells[5, 0] := 'County';
      sgdDatabases.Cells[6, 0] := 'Postcode';
      sgdDatabases.Cells[7, 0] := 'Telephone No.';
      sgdDatabases.Cells[8, 0] := 'E-Mail';

      row := 1;
      while not query.EOF do
      begin
        ID := query.FieldByName('ID').AsString;
        firstname := query.FieldByName('First Name').AsString;
        lastname := query.FieldByName('Last Name').AsString;
        address := query.FieldByName('Address').AsString;
        town := query.FieldByName('Town').AsString;
        county := query.FieldByName('County').AsString;
        postcode := query.FieldByName('Postcode').AsString;
        telno := query.FieldByName('TelNo').AsString;
        email := query.FieldByName('Email').AsString;

        sgdDatabases.Cells[0, row] := ID;
        sgdDatabases.Cells[1, row] := firstname;
        sgdDatabases.Cells[2, row] := lastname;
        sgdDatabases.Cells[3, row] := address;
        sgdDatabases.Cells[4, row] := town;
        sgdDatabases.Cells[5, row] := county;
        sgdDatabases.Cells[6, row] := postcode;
        sgdDatabases.Cells[7, row] := telno;
        sgdDatabases.Cells[8, row] := email;

        sgdDatabases.RowCount := sgdDatabases.RowCount + 1;
        row := row + 1;
        query.Next;

         end;
       end;

This is the procedure to display the Employee Database, which is basically identical except "SELECT * FROM EmplDatabase":

    procedure TfrmMain.mnuEmployeeClick(Sender: TObject);
    var
      i: integer;
    begin

      con := TFDConnection.Create(nil);
      query := TFDQuery.Create(con);
      con.LoginPrompt := False;
      con.Open('DriverID=SQLite;Database=C:\Users\kasio\Documents\Embarcadero\Studio\Projects\ProgramDatabase;');
      query.Connection := con;
      query.sql.Text := 'SELECT * FROM EmplDatabase ORDER BY ID';
      query.Open();
      query.First;

      sgdDatabases.colCount := 9;
      sgdDatabases.FixedCols := 0;
      for i := 0 to sgdDatabases.RowCount do
      sgdDatabases.ColWidths[i] := 100;

      sgdDatabases.Cells[0, 0] := 'ID';
      sgdDatabases.Cells[1, 0] := 'First Name';
      sgdDatabases.Cells[2, 0] := 'Last Name';
      sgdDatabases.Cells[3, 0] := 'Address';
      sgdDatabases.Cells[4, 0] := 'Town';
      sgdDatabases.Cells[5, 0] := 'County';
      sgdDatabases.Cells[6, 0] := 'Postcode';
      sgdDatabases.Cells[7, 0] := 'Telephone No.';
      sgdDatabases.Cells[8, 0] := 'E-Mail';

      row := 1;
      while not query.EOF do
      begin
        ID := query.FieldByName('ID').AsString;
        firstname := query.FieldByName('First Name').AsString;
        lastname := query.FieldByName('Last Name').AsString;
        address := query.FieldByName('Address').AsString;
        town := query.FieldByName('Town').AsString;
        county := query.FieldByName('County').AsString;
        postcode := query.FieldByName('Postcode').AsString;
        telno := query.FieldByName('TelNo').AsString;
        email := query.FieldByName('Email').AsString;

        sgdDatabases.Cells[0, row] := ID;
        sgdDatabases.Cells[1, row] := firstname;
        sgdDatabases.Cells[2, row] := lastname;
        sgdDatabases.Cells[3, row] := address;
        sgdDatabases.Cells[4, row] := town;
        sgdDatabases.Cells[5, row] := county;
        sgdDatabases.Cells[6, row] := postcode;
        sgdDatabases.Cells[7, row] := telno;
        sgdDatabases.Cells[8, row] := email;

        sgdDatabases.RowCount := sgdDatabases.RowCount + 1;
        row := row + 1;
        query.Next;

        end;
      end;

When I run the program, I can open either of the databases on the first click, but then if I click again on either of the Customer or Employee buttons or try to change the database, the following error shows: "Project ProjectQuote.exe raised exception class EInvalidGridOperation with message 'Grid index out of range'".

If I delete the line

sgdDatabases.RowCount := sgdDatabases.RowCount + 1;

from the code, it displays both databases, but only shows the first four rows from the database even if there's more.

(I am aware of the uselessly repeated code and no I can't use anything else other than TStringGrid)

Aucun commentaire:

Enregistrer un commentaire