我试图找到有相同错误的人,但我发现这个错误有很多原因。现在让我解释一下我的情况。我的应用程序有17个DBGrids,其中一些有查找字段。有一个具有三个普通字段和一个查找的特定字段。当我运行程序时它正常工作,但是当我在此表中注册某些内容时,关闭程序并再次运行它。它提出了这个例外:
项目引发了类异常'EDatabaseError',并带有以下消息: 无法对非活动数据集执行操作。没有地址: 5E0158。
我第一次打开“MATERIAL”表来添加新的寄存器:
procedure TfrmMateria.bbtAddClick(Sender: TObject);
var
prox: integer;
begin
//Adiciona um novo registro na tabela
dmOrcamentos.ztMaterial.Open;
dmOrcamentos.ztMaterial.Last;
prox := dmOrcamentos.ztMaterial.FieldByName('MP_ID').AsInteger + 1;
dmOrcamentos.zcOrcamento.StartTransaction;
dmOrcamentos.ztMaterial.Append;
dmOrcamentos.ztMaterial.FieldByName('MP_ID').AsInteger := prox;
dbgMaterial.SelectedIndex := 1;
tratabotoes;
end;
这是我用来设置我的PickList的代码:
procedure TfrmMateria.SetupGridPickList(const FieldName: string; const sql: string);
var
slPickList: TStringList;
Query: TZQuery;
i: integer;
begin
slPickList := TStringList.Create;
Query := TZQuery.Create(self);
try
Query.Connection := dmOrcamentos.zcOrcamento;
Query.SQL.Text := sql;
Query.Open;
//Preenche a String list
while not Query.EOF do
begin
slPickList.Add(Query.Fields[0].AsString);
Query.Next;
end; //while
//Coloca a lista na coluna correta
for i := 0 to dbgMaterial.Columns.Count - 1 do
if dbgMaterial.Columns[i].FieldName = FieldName then
begin
dbgMaterial.Columns[i].PickList := slPickList;
Break;
end;
finally
slPickList.Free;
Query.Free;
end;
end;
顺便说一句,我在FormCreate上调用了SetupGridPickList:
procedure TfrmMateria.FormCreate(Sender: TObject);
begin
SetupGridPickList('UNIDADE_DESC', 'SELECT UNIDADE_DESC FROM UNIDADES_MEDIDA');
end;
我用来保存DBGrid的代码:
procedure TfrmMateria.bbtSaveClick(Sender: TObject);
begin
//Salva alterações feitas na tabela
if dmOrcamentos.ztMaterial.State in [dsEdit, dsInsert] then
begin
dmOrcamentos.ztMaterial.Post;
dmOrcamentos.zcOrcamento.Commit;
dmOrcamentos.ztMaterial.Close;
dmOrcamentos.ztMaterial.Open;
tratabotoes;
end
else
begin
dmOrcamentos.zcOrcamento.StartTransaction;
dmOrcamentos.ztMaterial.Post;
dmOrcamentos.zcOrcamento.Commit;
dmOrcamentos.ztMaterial.Close;
dmOrcamentos.ztMaterial.Open;
tratabotoes;
end;
end;
当我关闭表格时:
procedure TfrmMateria.FormClose(Sender: TObject; var canClose: boolean);
begin
//Teste para saber se a tablea está "aberta" para
if dmOrcamentos.ztMaterial.State in [dsEdit, dsInsert] then
begin
//Pergunta se deseja salvar
if MessageBox(frmMateria.Handle, 'Deseja salvar os dados pendentes?',
'ONZE - AVISO', MB_YESNO + MB_SYSTEMMODAL + MB_ICONQUESTION) = idYes then
begin
dmOrcamentos.ztMaterial.Post;
dmOrcamentos.zcOrcamento.Commit;
dmOrcamentos.ztMaterial.Close;
tratabotoes;
CanClose := True;
end {Fim pergunta se deseja salvar}
else
begin
dmOrcamentos.ztMaterial.Cancel;
dmOrcamentos.zcOrcamento.Rollback;
tratabotoes;
canClose := True;
end;
end{Fim do teste da planilha aberta}
else
begin
canClose := True;
dmOrcamentos.ztMaterial.Close;
end;
end;
点击“主页”按钮
procedure TfrmMateria.bbtHomeClick(Sender: TObject);
begin
//Pergunta para voltar ao menu inicial
if MessageBox(frmMateria.Handle, 'Deseja voltar ao menu inicial?',
'ONZE - AVISO', MB_YESNO + MB_SYSTEMMODAL + MB_ICONQUESTION) = idYes then
begin
//Limpar da memória e fechar
frmMateria.Release;
frmMateria := nil;
dmOrcamentos.ztMaterial.Close;
end;
end;
数据库设置:
TABLES: | MATERIAL | UNIDADES_MEDIDA |
|----------------------------|-------------------|
FIELDS: | MP_ID (PRIMARY KEY)| UNIDADE_ID (PK) |
| MP_DESC | UNIDADE_DESC |
| MP_VALOR |-------------------|
| MP_UNIDADE_ID (FOREIGN KEY)|
|----------------------------|
在我的程序中,“MATERIAL”表还有一个字段,即LOOKUP字段: “UNIDADE_DESC”具有以下属性: KeyField:MP_UNIDADE_ID DataSet:ztUnidade 查找键:UNIDADE_ID 结果字段:UNIDDE_DESC
它除了显示消息外没有显示任何内容并关闭。 问题是,如果我手动从数据库中删除此寄存器数据(我使用IBExpert)并再次运行程序,它将恢复正常工作。 此外,我没有查找字段的所有表都在保存,而查找字段的表则没有。希望你们能帮助我,我不知道为什么会这样。
我使用:ZEOS连接和FireBird 2.5数据库。
这是程序停止的地方:在ZAbstractRODataset中 在此代码部分:
function TZAbstractRODataset.Lookup(const KeyFields: string;
const KeyValues: Variant; const ResultFields: string): Variant;
var
RowNo: Integer;
FieldRefs: TObjectDynArray;
FieldIndices: TIntegerDynArray;
OnlyDataFields: Boolean;
SearchRowBuffer: PZRowBuffer;
ResultValues: TZVariantDynArray;
begin
OnlyDataFields := False;
Result := Null;
RowNo := InternalLocate(KeyFields, KeyValues, []); <---- **HERE**
FieldRefs := nil;
FieldIndices := nil;
if RowNo < 0 then
Exit;
当我放置“HERE”时,当我使用断点并将鼠标放在“KeyFields”上时,它显示“UNIDADE_ID”,这是我在表格中使用的查找的关键字段,如果我将它放在“KeyValues”中“它显示”1“。
OBS¹:我有另一种形式,几乎相同的代码,唯一不同的部分是它被引用的表。此表单有五个查找字段,其中一个字段实际来自此“MATERIAL”表。所有字段都正常工作,如果我在其上保存一个寄存器并再次打开,程序就不会停止。