Erro Com Criação de TDataModule

Delphi

17/08/2012

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?
Sidney Abreu

Sidney Abreu

Curtidas 0

Respostas

William

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?
GOSTEI 0
Marco Salles

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;

GOSTEI 0
William

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

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

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

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);


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

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

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

Sidney Abreu

17/08/2012

sim sim, obrigado
GOSTEI 0
Marco Salles

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

Sidney Abreu

17/08/2012

obrigado parceiro
GOSTEI 0
POSTAR