Tanto no código que você postou no DevMedia, quanto no que postou aqui, percebo que você inicializa o tabCadastro, no evento OnCreate do form TfrmCadFuncionarios, a partir da atribuição do endereço do dataset que existe no datamodule dmCadFuncionarios, também criado neste evento. Isto deve estar funcionando bem para o caso de quando você utilizar o botão de inclusão (btnNovo) - ao menos em uma primeira execução - porque neste momento, você chama o método NovoRegistro da classe TfrmPai o qual criará o form frmCadFuncionarios, que na seqüência será mostrado (ShowModal) e, ao ser fechado o form, este será eliminado através da chamada FreeAndNil.
Entretanto, quando você utiliza o botão btnEditar, o seu método Editar, simplesmente utiliza a variável tabCadastro - que estará apontando para onde??? (Sabe-se lá. Esse o motivo do erro logo na primeira linha em que você a referencia)
Acho que duas observações seriam pertinentes:
1) o dmCafFuncionarios, assim como o frmCadFuncionarios, deveria estar sendo liberado da memória - o que não consta do código (talvez, no OnDestroy ou OnClose do frmCadFuncionarios você esteja fazendo isto, mas não citou)
2) ao usar a opção de edição, pela lógica, você deveria novamente criar o frmCadFuncionarios, o que criaria o dmCadFuncionarios e inicializaria as variáveis dos datasets, e então, antes de chamar o ShowModal, posicionaria o dataset no registro desejado.
Abraços
Certo a Estrutura de Herança é essa q você diz mesmo. Quanto a liberar da memoria,estou liberando o DataModule no
Evento OnClose como fui aconselhado pelo Discorpio no DevMedia:
procedure TfrmConsFuncionarios.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
inherited;
dmConsFuncionarios.cdsFuncionarios.Close;
FreeAndNil(dmConsFuncionarios);
end;
e agora os metodos Editar e Inserir estao assim:
procedure TfrmPai.Editar(ClasseForm: TFormClass;pID: Integer);
var
form : TForm;
begin
Try
application.CreateForm(ClasseForm,form);
tabCadastro.Close;{o erro de violaçao de memoria continua}
tabCadastro.FetchParams;
tabCadastro.Params.ParamByName('pID').AsInteger := pID;
tabCadastro.Open;
form.ShowModal;
Finally
FreeAndNil(form);
End;
end;
procedure TfrmPai.NovoRegistro(ClasseForm: TFormClass);
var
form : TForm;
begin
Try
application.CreateForm(ClasseForm,form);
tabCadastro.Cancel;{o erro de violaçao de memoria continua}
tabCadastro.Append;
tabCadastro.FieldByName('ID').AsInteger := GenProximoID(Generator);
form.ShowModal;
Finally
FreeAndNil(form);
End;
end;
Ao liberar um formulario com FreeAndNil(form) não é preciso liberar também no OnClose correto?
Os parametros vem do Evento OnCreate como disse antes:
procedure TfrmCadFuncionarios.FormCreate(Sender: TObject);
begin
inherited;
dmCadFuncionarios := TdmCadFuncionarios.Create(Self);
dmCadFuncionarios.cdsCadastro.Open;
tabCadastro := dmFuncionarios.cdsFuncionarios;
Generator := 'GEN_FUNCIONARIOS_ID';
end;