Erro Violação de Acesso
Saudações, estou enfrentando o seguinte problema:
Tenho no meu sistema um form para entrada de movimentação.
Nele há uma procedure que persiste os dados de um CDS - que está no DM - num banco FB, também ela chama outra procedure que mostra o andamento do processo através de uma progressbar.
Esta procedure roda normalmente se chamada na própria unit, mas quando a chamo de outra unit (formx.procedure) ocorre erro de violação de acesso.
Pelo que percebí, ao tentar alterar a propriedade de um componente qualquer, o erro é gerado.
Eu preciso rodá-la chamando pelo DM, no evento AfterPost de um CDS que lá está para garantir este processamento realizado pela procedure após os dados deste CDS serem persistidos.
Como resolver?
P.S. desculpem se não fui claro no problema e obrigado por qualquer ajuda.
Tenho no meu sistema um form para entrada de movimentação.
Nele há uma procedure que persiste os dados de um CDS - que está no DM - num banco FB, também ela chama outra procedure que mostra o andamento do processo através de uma progressbar.
Esta procedure roda normalmente se chamada na própria unit, mas quando a chamo de outra unit (formx.procedure) ocorre erro de violação de acesso.
Pelo que percebí, ao tentar alterar a propriedade de um componente qualquer, o erro é gerado.
Eu preciso rodá-la chamando pelo DM, no evento AfterPost de um CDS que lá está para garantir este processamento realizado pela procedure após os dados deste CDS serem persistidos.
Como resolver?
P.S. desculpem se não fui claro no problema e obrigado por qualquer ajuda.
Luciano.badoe
Curtidas 0
Respostas
Massuda
18/12/2007
...
Esta procedure roda normalmente se chamada na própria unit, mas quando a chamo de outra unit (formx.procedure) ocorre erro de violação de acesso.
...
Erros de Access Violation geralmente estão associados a tentar usar um objeto que ou não foi criado ainda ou já foi destruído. No seu caso, o tal formx provavelmente já foi destruído quando você tenta usar de outra unit.
GOSTEI 0
Luciano.badoe
18/12/2007
Caro Massuda:
Na verdade o que ocorre é o seguinte:
O formX está em modal, nela há um DBGrid cujo CDS está no Data Module.
A procedure está na unit do formX.
Tento executá-la chamando pelo DataModule, no evento AfterPost do CDS, e ai gera o erro.
Se executá-la chamando da unit do formX (onde ela está) não dá erro.
Pelo que posso entender, quando a chamo de fora da unit em que ela está, mesmo com o form ativo, ela não consegue acessar os componentes contidos nele, poi o erro se dá quando tento atualizar um ProgressBar.
Obrigado.
Na verdade o que ocorre é o seguinte:
O formX está em modal, nela há um DBGrid cujo CDS está no Data Module.
A procedure está na unit do formX.
Tento executá-la chamando pelo DataModule, no evento AfterPost do CDS, e ai gera o erro.
Se executá-la chamando da unit do formX (onde ela está) não dá erro.
Pelo que posso entender, quando a chamo de fora da unit em que ela está, mesmo com o form ativo, ela não consegue acessar os componentes contidos nele, poi o erro se dá quando tento atualizar um ProgressBar.
Obrigado.
GOSTEI 0
Massuda
18/12/2007
Mostre como você cria e exibe o tal formx.
GOSTEI 0
Luciano.badoe
18/12/2007
Estou usando uma procedure para criar e exibir o form.
A chamada apartir do form principal é essa:
A chamada apartir do form principal é essa:
procedure TfrmMain.actDebFolhaExecute(Sender: TObject);
begin
AbreForm(TfrmDBFolha, frmDBFolha);
end;
procedure AbreForm(aClasseForm: TComponentClass; aForm: TForm);
begin
Application.CreateForm(aClasseForm, aForm);
try
aForm.ShowModal;
finally
aForm.Release;
aForm := nil;
end;
end;
GOSTEI 0
Massuda
18/12/2007
Imaginava que você estava usando algo desse tipo. Não gosto desse tipo de design, mas...
AbreForm recebe o parametro aForm por valor, o que significa que aForm é uma cópia de frmDbFolha. Por isso, dentro de AbreForm, quando aForm recebe um valor, esse valor que não é passado para frmDBFolha (pois aForm é uma cópia).
Quando o evento do datamodule dispara, provavelmente ele usa frmDBFolha, que, pelo motivo exposto acima, não tem um valor válido, gerando o AV.
Acho que a solução mais simples é mudar AbreForm para usar passagem de parametros por referencia...
AbreForm recebe o parametro aForm por valor, o que significa que aForm é uma cópia de frmDbFolha. Por isso, dentro de AbreForm, quando aForm recebe um valor, esse valor que não é passado para frmDBFolha (pois aForm é uma cópia).
Quando o evento do datamodule dispara, provavelmente ele usa frmDBFolha, que, pelo motivo exposto acima, não tem um valor válido, gerando o AV.
Acho que a solução mais simples é mudar AbreForm para usar passagem de parametros por referencia...
procedure AbreForm(aClasseForm: TComponentClass; var aForm: TForm); ...
GOSTEI 0
Luciano.badoe
18/12/2007
[b:15fdbeeab1]Massuda[/b:15fdbeeab1]
Obrigado pela explicação, entendí perfeitamente o problema.
Vou fazer a correção que sugeriu e testar, mas quando vc diz
Você se refere ao metodo usado para abrir o form? Se for o caso, me informe (se possível) um método mais adequando. Estou começando a desenvolver de Delphi, e quero me abtuar às melhores práticas.
obrigado.
Obrigado pela explicação, entendí perfeitamente o problema.
Vou fazer a correção que sugeriu e testar, mas quando vc diz
Imaginava que você estava usando algo desse tipo. Não gosto desse tipo de design
Você se refere ao metodo usado para abrir o form? Se for o caso, me informe (se possível) um método mais adequando. Estou começando a desenvolver de Delphi, e quero me abtuar às melhores práticas.
obrigado.
GOSTEI 0
Luciano.badoe
18/12/2007
[b:9da6e00001]Massuda[/b:9da6e00001]
Como fica a chamada para CriaForm com a alteração de parâmetro por referência?
Estou tendo este erro: ´[i:9da6e00001]Types of actual and formal var parameters must be identical[/i:9da6e00001]´ quando tento compilar, deixando a chamada como estava.
Tentei alterar a chamada, criando uma variável do tipo TForm, e atribuindo em sua propriedade name o nome do form a ser criado, e passá-la para CriaForm, porém ocorre uma excessão de objeto já existente...
Help...
Como fica a chamada para CriaForm com a alteração de parâmetro por referência?
Estou tendo este erro: ´[i:9da6e00001]Types of actual and formal var parameters must be identical[/i:9da6e00001]´ quando tento compilar, deixando a chamada como estava.
Tentei alterar a chamada, criando uma variável do tipo TForm, e atribuindo em sua propriedade name o nome do form a ser criado, e passá-la para CriaForm, porém ocorre uma excessão de objeto já existente...
Help...
GOSTEI 0