Fórum Erro Com Criação de TDataModule #421896

17/08/2012

0

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

Responder

Posts

17/08/2012

William

Colega notei que vc cria o DM_Expedicao mas não destrói, certo?

Esse Access Violation é disparado em qual momento?
Responder

Gostei + 0

18/08/2012

Marco Salles

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;

Responder

Gostei + 0

18/08/2012

William

Realmente Marco foi uma falha de interpretação minha, não me atentei ao detalhe do Self sendo passado como parâmetro no construtor!!
Responder

Gostei + 0

18/08/2012

Sidney Abreu

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.
Responder

Gostei + 0

18/08/2012

Sidney Abreu

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.
Responder

Gostei + 0

18/08/2012

Marco Salles

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 ?????
Responder

Gostei + 0

18/08/2012

Sidney Abreu

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
Responder

Gostei + 0

18/08/2012

Marco Salles

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
Responder

Gostei + 0

18/08/2012

Sidney Abreu

sim sim, obrigado
Responder

Gostei + 0

18/08/2012

Marco Salles

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
Responder

Gostei + 0

19/08/2012

Sidney Abreu

obrigado parceiro
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar