Datamodule

Delphi

25/07/2007

Vocês colocam suas querys/tables no datamodule ou nos próprios forms que as usam?


Ahlex10100

Ahlex10100

Curtidas 0

Respostas

Rodfernandes

Rodfernandes

25/07/2007

Amigo,

Uso no DataModule, prefiro centralizar tudo em um só lugar.

Por exemplo, se você for utilizar uma mesma consulta em varios forms, basta refenciar o DM e usar suas propriedades. :D

Abraço


GOSTEI 0
Adriano Santos

Adriano Santos

25/07/2007

Amigo, Uso no DataModule, prefiro centralizar tudo em um só lugar. Por exemplo, se você for utilizar uma mesma consulta em varios forms, basta refenciar o DM e usar suas propriedades. :D Abraço

Com certeza, acho mais prático também além de ter forms mais organizados e ´sepaados´ das rotinas de acesso a dados e etc.


GOSTEI 0
Yakazuma1

Yakazuma1

25/07/2007

Mas e a questão de quando vários forms estarem trabalhando com a mesma tabela?


GOSTEI 0
Adriano Santos

Adriano Santos

25/07/2007

Mas e a questão de quando vários forms estarem trabalhando com a mesma tabela?

Qual o problema?
Normalmente eu crio o Data Module em run-time, ou seja, no momento que preciso usá-lo. Um exemplo disso: quando meu usuário abre a tela de Clientes no onCreate do form mando criar o Data Module.

procedure TForm1.FormCreate(Sender: TObject);
begin
  dmClientes := TdmClientes.Create(Self);
  //abre queries e etc
end;


e no onDestroy do mesmo form o Data Module é destruído junto.

procedure TForm1.FormDestroy(Sender: TObject);
begin
  dmClientes.Free;
end;

Você deve estar se perguntando: E se outra tela também usa o Data Module dmClientes? Vou criar novamente o dmClientes?
Sim, claro. É uma nova instância do dmClientes em memória em, provavelmente, outra estação da rede. Sem crise. ;)


GOSTEI 0
Yakazuma1

Yakazuma1

25/07/2007

Obrigado. Eu estava usando a sua dica também para outra coisa. Criei um form q quando ele for desativado (sair dele) ou fechado, ele vai ser destruído.

Fiz assim: no evento onDeactivate do próprio form escrevi form.Destroy;
tentei fazer o mesmo no OnClose, e deu Abstract Error. Alguém sabe o por que disso, e como destruir um form quando ele for fechado?


GOSTEI 0
Adriano Santos

Adriano Santos

25/07/2007

Obrigado. Eu estava usando a sua dica também para outra coisa. Criei um form q quando ele for desativado (sair dele) ou fechado, ele vai ser destruído. Fiz assim: no evento onDeactivate do próprio form escrevi form.Destroy; tentei fazer o mesmo no OnClose, e deu Abstract Error. Alguém sabe o por que disso, e como destruir um form quando ele for fechado?


Cara, primeira dica: NUNCA use o método Destroy do objeto. O Destroy só é aconselhável usar quando se tem certeza absoluta que o objeto esteja carregado em memória como por exemplo no desenvolvimento de componentes. Do contrário um Access Violation será acionado. Por que? O Destroy elimina a instância do componente, mas não testa antes se o mesmo é NIL. Já o Free testa antes de o objeto é NIL e então chama o método Destroy. Veja a declaração na unit System do Delphi:

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;


Já uma das formas de fazer a ´eliminação´ do form seria no onDestroy atribuir o valor nil ao form.

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Form1 := nil;
end;


e no onClose atribuir caFree a ação:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;


Porém, há aqueles que usam diretamente o método FreeAndNil que já faz as duas coisas.

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(Form1);
end;



GOSTEI 0
Felipeiw

Felipeiw

25/07/2007

Adriano, no exemplo que vc deu sobre o form de clientes, caso sua aplicacao seja mdi, e o usuario abrir o form, por exemplo de pedidos onde vc utilizara o dataset de cliente, nao ira dar conflito, ou vc tem datamodules separados? Se for o mesmo datamodule utilizado nos 2 forms, como fica?

Abs


GOSTEI 0
Adriano Santos

Adriano Santos

25/07/2007

Adriano, no exemplo que vc deu sobre o form de clientes, caso sua aplicacao seja mdi, e o usuario abrir o form, por exemplo de pedidos onde vc utilizara o dataset de cliente, nao ira dar conflito, ou vc tem datamodules separados? Se for o mesmo datamodule utilizado nos 2 forms, como fica? Abs

Boa pergunta :). Não utilizo MDI, não vejo nenhuma forte razão para usá-los. É mais complicado pra controlar, obsoleto (na minha opnião) e, também na minha opnião, fica com uma má aparência. Sempre usei SDI. Contudo, acredito que não tenha nenhum problema já que cada form cria uma nova instância do Data Module.

Alguém que trabalha com MDI poderia nos tirar dúvidas a respeito disso?


GOSTEI 0
Yakazuma1

Yakazuma1

25/07/2007

[quote:375e365e7e=´Adriano Santos´]
Obrigado. Eu estava usando a sua dica também para outra coisa. Criei um form q quando ele for desativado (sair dele) ou fechado, ele vai ser destruído. Fiz assim: no evento onDeactivate do próprio form escrevi form.Destroy; tentei fazer o mesmo no OnClose, e deu Abstract Error. Alguém sabe o por que disso, e como destruir um form quando ele for fechado?


Cara, primeira dica: NUNCA use o método Destroy do objeto. O Destroy só é aconselhável usar quando se tem certeza absoluta que o objeto esteja carregado em memória como por exemplo no desenvolvimento de componentes. Do contrário um Access Violation será acionado. Por que? O Destroy elimina a instância do componente, mas não testa antes se o mesmo é NIL. Já o Free testa antes de o objeto é NIL e então chama o método Destroy. Veja a declaração na unit System do Delphi:

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;


Já uma das formas de fazer a ´eliminação´ do form seria no onDestroy atribuir o valor nil ao form.

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Form1 := nil;
end;


e no onClose atribuir caFree a ação:

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;


Porém, há aqueles que usam diretamente o método FreeAndNil que já faz as duas coisas.

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(Form1);
end;
[/quote:375e365e7e]

Mas Adriano, se eu crio uma instância, não é necessário q eu a destrua?

Tenho outra dúvida também: criei um form q estava como Available. Usei
Application.CreateForm(TForm,Form);
Form.Show;

Eu posso deixar sem função alguma pra liberar ele, ou destruir? Por exemplo, se eu vou ter q colocar Free no Close, ou algo assim.


GOSTEI 0
Yakazuma1

Yakazuma1

25/07/2007

O q é o caFree? Há algum problema/diferença de usar FreeAndNil() dos outros métodos citados (caFree e Nil separados)?


GOSTEI 0
Adriano Santos

Adriano Santos

25/07/2007

Mas Adriano, se eu crio uma instância, não é necessário q eu a destrua?

Sim, é necessário. Do contrário você estará com seu Data Module em memória o tempo todo durante a execução de sua aplicação. É simples: se seu usuário está com todas as janelas fechadas e permanece somente na tela inicial do programa, por que deixar o Data Module carregado na memória? Por isso é aconselhável você destruir o objeto, no caso o DM, depois de fechar a tela que o usava.

Tenho outra dúvida também: criei um form q estava como Available. Usei Application.CreateForm(TForm,Form); Form.Show; Eu posso deixar sem função alguma pra liberar ele, ou destruir? Por exemplo, se eu vou ter q colocar Free no Close, ou algo assim.


Me corrijam se eu estiver errado, mas é o seguinte: o CreateForm é o método de criação de forms do objeto TApplication. Criando o componente (form) a partir deste método você está dando a responsabilidade de gerenciamento do objeto ao TApplication, sua aplicação. Ou seja, a própria aplicação fará a criação e destruição do objeto.
O Form1.Create é o método de criação do próprio objeto. E nele você indica quem será responsável por gerenciar sua instância...Self, ele mesmo, ou Application, sua aplicação.



O q é o caFree? Há algum problema/diferença de usar FreeAndNil() dos outros métodos citados (caFree e Nil separados)?

caFree é uma atribuição a variável Action no segundo parâmetro do evento onClose. Atribuindo caFree você está informando ao form que ele deve ser liberado de memória. As opções possíveis são:

TCloseAction = (caNone, caHide, caFree, caMinimize);

caNone = não faz nada;
caHide = esconde;
caFree = libera de memória;
caMinimize = minimiza a janela;

A classe TCloseAction está declarada na unit Forms do Delphi.
O FreeAndNil tem um papél diferente. Quando chamado libera de memória e esvazia, deixa nulo o ponteiro de memória que era apontado para a instância do form. Novamente peço que me corrijam se falei besteira.

Não há problema nenhum em usar de um jeito ou de outro.


GOSTEI 0
Rodolfo.pirolo

Rodolfo.pirolo

25/07/2007

Adriano,

Estou tentando utilizar essa sua dica para criar o data module em tempo de excecução, mas esta dando o seguinte erro ´Access violation at address 00582BB3 in module ´ConsultorioMedico.exe´. Read of address 00000060´.

Isto acontece quando tento executar a seguinte linha: tmpDM_Cadastro.cds_Pessoa.Open;

Segui os seus passos da seguinte maneira:
-[b:717b1f6eec]crio as variaveis assim:[/b:717b1f6eec]

implementation

uses uDM_Cadastro, uDM_Consulta;

var
tmpDM_Cadastro : TdmCadastro;
tmpDM_Consulta : TDMConsulta;

-[b:717b1f6eec]no Create do formulario:[/b:717b1f6eec]
procedure TformCadastroPessoa.FormCreate(Sender: TObject);
begin
inherited;
tmpDM_Cadastro := TdmCadastro.Create( Self );
tmpDM_Consulta := TDMConsulta.Create( Self );
end;

Deixei os DM principais ( DMCadastro e DMConsulta ) no auto-create forms, tentei deixa-los no available forms mas o erro continua.

Uso Delphi 2005.

Abraços

Rodolfo


GOSTEI 0
Adriano Santos

Adriano Santos

25/07/2007

Adriano, Estou tentando utilizar essa sua dica para criar o data module em tempo de excecução, mas esta dando o seguinte erro ´Access violation at address 00582BB3 in module ´ConsultorioMedico.exe´. Read of address 00000060´. Isto acontece quando tento executar a seguinte linha: tmpDM_Cadastro.cds_Pessoa.Open; Segui os seus passos da seguinte maneira: -[b:9d3707f4b2]crio as variaveis assim:[/b:9d3707f4b2] implementation uses uDM_Cadastro, uDM_Consulta; var tmpDM_Cadastro : TdmCadastro; tmpDM_Consulta : TDMConsulta; -[b:9d3707f4b2]no Create do formulario:[/b:9d3707f4b2] procedure TformCadastroPessoa.FormCreate(Sender: TObject); begin inherited; tmpDM_Cadastro := TdmCadastro.Create( Self ); tmpDM_Consulta := TDMConsulta.Create( Self ); end; Deixei os DM principais ( DMCadastro e DMConsulta ) no auto-create forms, tentei deixa-los no available forms mas o erro continua. Uso Delphi 2005. Abraços Rodolfo

Não entendi muito bem o que está fazendo, mas vamos lá.
Coloquei no meu ftp um exemplo básico de criação do DataModule em runtime. Dá uma olhada em www.doiscliques.com/pub/dm.zip veja se te ajuda a entender melhor.


GOSTEI 0
Rodolfo.pirolo

Rodolfo.pirolo

25/07/2007

Adriano,

Não sei o que estava fazendo de errado, pois comparei seu exemplo com o que já tinha feito, aparentemente esta tudo certo.

Pelo menos não deu mais erro de acces violation.

Muito obrigado pela dica e pelo exemplo.

Abraços

Rodolfo


GOSTEI 0
POSTAR