无法对非活动数据集执行操作 - Lazarus

时间:2015-06-30 16:45:50

标签: delphi runtime-error pascal freepascal lazarus

我试图找到有相同错误的人,但我发现这个错误有很多原因。现在让我解释一下我的情况。我的应用程序有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”表。所有字段都正常工作,如果我在其上保存一个寄存器并再次打开,程序就不会停止。

0 个答案:

没有答案