这是显示客户数据库的过程:
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;
这是显示Employee Database的过程,除了"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;
当我运行该程序时,我可以在第一次单击时打开任一数据库,但如果我再次单击Customer或Employee按钮或尝试更改数据库,则会出现以下错误:"Project ProjectQuote.exe已引发异常类EInvalidGridOperation,消息'网格索引超出范围'".
如果我删除该行
sgdDatabases.RowCount:= sgdDatabases.RowCount + 1;
从代码中,它显示两个数据库,但只显示数据库中的前四行,即使有更多.
(我知道无用的重复代码,除了TStringGrid,我不能使用其他任何东西)
这行代码看起来对我不对:
for j := 0 to sgdDatabases.rowCount do sgdDatabases.ColWidths[j] := 100;
StringGrid ColWidths
属性的[Index] 是列号,而不是行号,所以sgdDatabases.rowCount
应该与它无关.如果在上面的代码执行时,中行的网格数比列的数量越多,你会当j值达到它表示一个无效的列数的值获得一个"索引超出范围"错误.
在任何情况下,即使该代码在这方面有效,也会出现"一个一个"的错误sgdDatabases.rowCount
.行号是从零开始的,所以它应该是sgdDatabases.rowCount - 1
(假设你试图通过索引来引用特定的行).
更一般的一点是,您可以使用IDE的调试器单步执行代码; 如果你这样做,你会看到执行一个特定行时发生异常,这是开始寻找原因的地方.您应该始终在SO问题中包含异常的位置,因为读者不必猜测这一点.
通常,只要你去,IDE调试器就会发现异常,即使你没有单步执行
Tools | Debugger Options | Embarcadero Debuggers | Language Exceptions
在IDE中,选中复选框Notify on Language Exceptions
.
顺便说一句,如果您编写一个通用例程来从数据集填充StringGrid会更好,可能顺序如下:
procedure TForm1.DatasetToGrid(Dataset : TDataset; Grid : TStringGrid); var Col, Row : Integer; begin Grid.RowCount := 1; Row := 0; // The following gives the column headers the names of the // Dataset fields. for Col := 0 to Dataset.FieldCount - 1 do Grid.Cells[Col, Row] := Dataset.Fields[Col].FieldName; Inc(Row); Dataset.First; while not Dataset.Eof do begin for Col := 0 to Dataset.FieldCount - 1 do begin // Oops! we don't need this Row := Grid.RowCount; Grid.Cells[Col, Row] := DataSet.Fields[Col].AsString;; end; Dataset.Next; Grid.RowCount := Grid.RowCount + 1; Inc(Row); end; end;
这样做的好处之一就是你所有的错误都集中在一个地方,而不是重复的代码重复,所以如果你修复它们,你就完成了.