Erro Com Criação de TDataModule
Galera eu tenho um aplicação TDI, onde abro vários formulário ao mesmo tempo, e acontece que alguns desse formulários as vezes acessam os mesmo TDataModules, apenas muda o TClientDataSet. Por esse motivo eu tenho que criar o TDataModule em tempo de execução, ou seja, quando o Formulario for aberto. Só que os depois que eu abro, fecho e depois abro o mesmo formulario ele Acesses violation, ou seja, é como se o TClientDataSet e TDataModule não existem mais;
Segue abaixo os eventos do Formulario
OnCreate
if not Assigned(DmExpedicao) then
DmExpedicao := TDmExpedicao.Create(Self);
OnClose
Action := caFree;
OnDestroy
DmExpedicao.CdsCargas.Close;
Alguém já passou por isso? Alguém pode me ajudar?
Segue abaixo os eventos do Formulario
OnCreate
if not Assigned(DmExpedicao) then
DmExpedicao := TDmExpedicao.Create(Self);
OnClose
Action := caFree;
OnDestroy
DmExpedicao.CdsCargas.Close;
Alguém já passou por isso? Alguém pode me ajudar?
Sidney Abreu
Curtidas 0
Respostas
William
17/08/2012
Colega notei que vc cria o DM_Expedicao mas não destrói, certo?
Esse Access Violation é disparado em qual momento?
Esse Access Violation é disparado em qual momento?
GOSTEI 0
Marco Salles
17/08/2012
wllfl , a destruição do TdataModulo ocorre no evento Ondestroy do forumlário . Isto é de responsabilidade do
Delphi , pq ele indicou o form para ser o Pai do TdataModulo
DmExpedicao := TDmExpedicao.Create(Self);
Eu tb sugiro tentar colocar a instrução DmExpedicao:=nil;
OnDestroy
DmExpedicao.CdsCargas.Close;
DmExpedicao:=nil;
Delphi , pq ele indicou o form para ser o Pai do TdataModulo
DmExpedicao := TDmExpedicao.Create(Self);
Eu tb sugiro tentar colocar a instrução DmExpedicao:=nil;
OnDestroy
DmExpedicao.CdsCargas.Close;
DmExpedicao:=nil;
GOSTEI 0
William
17/08/2012
Realmente Marco foi uma falha de interpretação minha, não me atentei ao detalhe do Self sendo passado como parâmetro no construtor!!
GOSTEI 0
Sidney Abreu
17/08/2012
Primeiro quero agradecer a todos por terem me ajudado, mas MARCO ANTONIO eu não posso dar um NIL pq ele vai destruir totalmente e como eu disse eu trabalho com formulários TDI, então se estiver com os formulários de cargas e expedição abertos trabalhando, ambos usam o TDmExpedicao, se eu fechar o Formulário de cargas e der um NIL o formulário de expedição que ainda estou usando vai dar acesses violation quando eu precisar usar algum filtro pois o TDmExpedicao estará destruído.
GOSTEI 0
Sidney Abreu
17/08/2012
Primeiro quero agradecer a todos por terem me ajudado, mas MARCO ANTONIO eu não posso dar um NIL pq ele vai destruir totalmente e como eu disse eu trabalho com formulários TDI, então se estiver com os formulários de cargas e expedição abertos trabalhando, ambos usam o TDmExpedicao, se eu fechar o Formulário de cargas e der um NIL o formulário de expedição que ainda estou usando vai dar acesses violation quando eu precisar usar algum filtro pois o TDmExpedicao estará destruído.
GOSTEI 0
Marco Salles
17/08/2012
Primeiro quero agradecer a todos por terem me ajudado, mas MARCO ANTONIO eu não posso dar um NIL pq ele vai destruir totalmente e como eu disse eu trabalho com formulários TDI, então se estiver com os formulários de cargas e expedição abertos trabalhando, ambos usam o TDmExpedicao, se eu fechar o Formulário de cargas e der um NIL o formulário de expedição que ainda estou usando vai dar acesses violation quando eu precisar usar algum filtro pois o TDmExpedicao estará destruído.
Legal. eu conheço TDI e particularmnte acho útil . Mas tem alguns conceitos que me parecem confusos
1) eu não posso dar um NIL pq ele vai destruir totalmente
O Nil , não destroy nada
Quando vc testa
if not Assigned(DmExpedicao) then
DmExpedicao := TDmExpedicao.Create(Self);
Vc esta testando se o DmExpedicao não é Nil e não se ele existe ou deixa de existir. Ele pode ser <> nil e não
esta instanciado
veja um exemplo simples
var
Obj:TEdit; //pode ser qualquer classe
begin
if obj <> nil then
showmessage('como pode ser <> nil se eu não instanciei ???'); // Veja que a instrução é executada
2)se eu fechar o Formulário de cargas e der um NIL o formulário de expedição
O correto é vc ter para cada formulário um Campo apontando para este DataModulo
public
FDmExpedicao:TDataModule
...
Instancia ele no oncreate ou onshow
FDmExpedicao := TDmExpedicao.Create(Self);
usa e deixa o Ondetroy se encarregar do Resto
ps) Apesar de pouco utilizado esta arquitetura é mais indicada . Posso entrar mais no merito da questão se for o caso
3)
se eu fechar o Formulário de cargas e der um NIL o formulário de expedição que ainda estou usando vai dar acesses violation quando eu precisar usar algum filtro pois o TDmExpedicao estará destruído.
Mas no seu código não é O nil que o esta destruindo ... E o Proprio formulário que destroe todos os seus filhos
veja o que eu disse para o will
wllfl , a destruição do TdataModulo ocorre no evento Ondestroy do forumlário . Isto é de responsabilidade do
Delphi , pq ele indicou o form para ser o Pai do TdataModulo
DmExpedicao := TDmExpedicao.Create(Self);
Delphi , pq ele indicou o form para ser o Pai do TdataModulo
DmExpedicao := TDmExpedicao.Create(Self);
O parametro sel no constructor esta dizendo que o proprietário de DmExpedicao é o próprio form (self), logo quando vc
fecha o formulario e o libera da memória (action) , automaticamente ele Libera todos os objetos filhos
Por isto que vc recebe Acesso Violado ... Entendeu ?????
GOSTEI 0
Sidney Abreu
17/08/2012
Obrigado amigo, desculpa eu ter me expressado mal. bem eu declarei na public o que vc me pediu e deu certo, mas quando eu acrescentava a linha onDestroy DmExpedicao.CdsCargas.Close; e em seguida DmExpedicao := nil; ele dava acesses violation na linha DmExpedicao.CdsCargas.Close; isso depois de abrir e fechar o form
GOSTEI 0
Marco Salles
17/08/2012
Obrigado amigo, desculpa eu ter me expressado mal. bem eu declarei na public o que vc me pediu e deu certo,
è recomendação , apesar de pouco utilizado
mas quando eu acrescentava a linha onDestroy DmExpedicao.CdsCargas.Close; e em seguida DmExpedicao := nil; ele dava acesses violation na linha DmExpedicao.CdsCargas.Close; isso depois de abrir e fechar o form
estranho...
Se este formulário for reaberto e não recriado , vc deveria ter feito as verificações no onshow e não no oncreate
Neste caso como o DmExpedicao sera Nil , vc o estaria Recriando
no OnShow
if not Assigned(DmExpedicao) then
DmExpedicao := TDmExpedicao.Create(Self);
Mas de qualquer forma esta tudo ok agora
GOSTEI 0
Sidney Abreu
17/08/2012
sim sim, obrigado
GOSTEI 0
Marco Salles
17/08/2012
sim sim, obrigado
só corrigindo
2)se eu fechar o Formulário de cargas e der um NIL o formulário de expedição
O correto é vc ter para cada formulário um Campo apontando para este DataModulo
public /////////////////////// o correto é Private
FDmExpedicao:TDataModule
[]sds
GOSTEI 0
Sidney Abreu
17/08/2012
obrigado parceiro
GOSTEI 0