Manter Dataset aberto condicionalmente

Delphi

26/10/2005

Pessoal,

Estou modificando algumas coisas aqui num sistema, visando principalmente permitir o acesso a diversos forms simultaneamente ou não, porém estou com um problema. Uso sempre DataModule para armazenar os datasets e datasources (IBX) de praticamente tudo nos meus sistemas, apenas algumas poucas queries coloco no próprio form que a usa.

Normalmente ao abrir um form, eu abro os dm.datasets que serão usados por ele, e ao fechar o form eu fecho os datasets abertos. Porém um mesmo dataset, lá do DM, também é aberto por outro form, que por sua vez também o fecha ao sair... Mas e o form que ficou aberto que e continua precisando daquelas informações? O que faço?

Pensei em usar a propriedade TAG do dataset para armazenar um número referente ao primeiro form que abriu o dataset e somente fechar o dataset se o pedido de fechamento viesse deste mesmo form, os demais não fechariam o dataset se o ´dono´ dele, informado na propriedade tag do dataset, fosse outro.

Porém isso fica muito numérico para meu gosto (cada form teria que ser identificado por um número para ser colocado nessas tags), então pensei em criar variáveis globais no DM, uma para cada dataset, armazenando sempre que um dataset for aberto o nome do form ´dono´. E sempre que algum form for fechar o dataset verificar se dono do dataset é ele próprio, senão, não fecha o dataset.

Será que deu pra entender? Será que estou pensando corretamente ou viajei na maionese... O que me recomendariam fazer nestes casos?


Aerreira

Aerreira

Curtidas 0

Respostas

Bon Jovi

Bon Jovi

26/10/2005

O ideal que acho é que cada form deve usar uma instância diferente deste data module. Ou seja, tirar do auto create e criar/destruir em cada form o data module. Nao esquecendo também de apagar a variavel global de unit que o Delphi escreve de forma nao OO (var DataModule1: TDataModule1;). Cada classe de form deverá ter uma variavel privada para a instância do data module.

Outras coisas:

Ter um único data module pra tudo num sistema médio ou grande pode ficar confuso. Pra alguns conjuntos de regras de negócio é bom separar. E particularmente acho mais legal usar classes TObject em conjunto com datamodule.

DataSource acho melhor ficar melhor no Form.


GOSTEI 0
Bon Jovi

Bon Jovi

26/10/2005

[i:9816be9088]Cada classe de form deverá ter uma variavel privada para a instância do data module. [/i:9816be9088]
Complementando: com isso terá que setar o Connection e demais objetos em tempo de execução se quiser chamar de outra classe.


GOSTEI 0
Anfm

Anfm

26/10/2005

Eu costumo criar uma cópia do datamodule para cada form.

Para fazer isto faça o seguinte:

No uses da sua unit declare o unit do datamodule;

Na seção private declare uma variável que receberá a cópia do datamodule: DMLocal : TDataModule;

No on create do seu form coloque:

DMLocal := TDataModule.Create(Self)
DataSource1.DataSet := DMLocal.NomeTabela;


GOSTEI 0
Aerreira

Aerreira

26/10/2005

DMLocal := TDataModule.Create(Self) DataSource1.DataSet := DMLocal.NomeTabela;


Fiz o que você falou: o datamodule já está no uses do form, declarei dmLocal em private, coloquei um DataSource no form e chamei de dsConv, e coloquei o código abaixo no oncreate do form:

dmLocal := TDataModule.Create(Self);
dsConv.dataset := dmLocal.tbConv;

O problema nesse caso é que não existe dmLocal.tbConv (leia-se tbConv como o DataSet que está no DM), o que existe sim é dm.tbConv, ou seja apenas a tabela no DM original e não em dmLocal. Não faltou alguma coisa aí não? Ligar o dmLocal ao dm real?

Como criar uma instância diferente do mesmo DM em cada form ?
Desculpem a ignorância, mas realmente não faço esse tipo de coisa.


GOSTEI 0
Aerreira

Aerreira

26/10/2005

[quote:e8554fd7f0=´Bon Jovi´]Nao esquecendo também de apagar a variavel global de unit que o Delphi escreve de forma nao OO (var DataModule1: TDataModule1;).[/quote:e8554fd7f0]
O problema acima é: se eu tiro o ´var dm: Tdm;´ do datamodule eu fico com tudo que o sistema atualmente se referencia a ´dm...´ sem funcionar, então não sei se o dmLocal funciona mesmo ou não... Pois no teste que fiz acima com dmLocal não funcionou. Será que é porque ainda tenho o ´var dm: Tdm´ lá no datamodule ?


GOSTEI 0
Anfm

Anfm

26/10/2005

Então,

Onde vc está criando o Data Module local
dmLocal := TDataModule.Create(Self);

vc tem q se referenciar ao DataModule que vc já possui, ou seja, vc vai criar uma cópia dele com todos componentes que ele possui.

Suponhamos q o seu DataModule chame dmtabelas,
então vc deve criar da seguinte maneira:

dmLocal := Tdmtabelas.Create(Self);


A unit que contém o DataModule deve ser colocado no uses principal da Unit, onde estão as units forms, dialogs, etc.


GOSTEI 0
Aerreira

Aerreira

26/10/2005

Suponhamos q o seu DataModule chame dmtabelas, então vc deve criar da seguinte maneira:
dmLocal := Tdmtabelas.Create(Self);
A unit que contém o DataModule deve ser colocado no uses principal da Unit, onde estão as units forms, dialogs, etc.


Meu DataModule chama-se ´dm´, então tentei:
dmLocal := Tdm.Create(Self);
dsConv.dataset := dmLocal.tbConv;

Resultado: Undeclared Identifier na segunda linha

Outro teste (o que eu estava fazendo antes):
dmLocal := TDataModule.Create(Self);
dsConv.dataset := dmLocal.tbConv;

Resultado: o mesmo erro na segunda linha.

O nome da unit do DataModule é ´datamodule´ e o nome do form é ´dm´. Fiz os testes acima com o ´datamodule´ no uses após implementation, e também colocando no uses lá de cima, após interface. Não funcionou em nenhuma das duas situações.

Tá faltando alguma coisa... mas não sei o que.


GOSTEI 0
Firekiller

Firekiller

26/10/2005

Você poderia trabalhar com a sua idéia inicial de trabalhar com as tags... mas a cada form que abrisse (e que utilizasse o dataset), seria adicionado 1 na tag do dataset. Ao fechar o form, tira-se 1 da tag do dataset. Se o dataset estiver com a tag = 0 então, ele deve ser fechado, senão não. É uma forma mais simples de implementar o que já estava pronto.

Eu particularmente, trabalho com vários datamodules. Por exemplo, para o form de cadastro de clientes, tenho um datamodule que contem 1 dataset para conexão com a tabela de clientes. Para o form de vendas, tenho um datamodule com 1 dataset para a tabela vendas, 1 para Itens, 1 para Produtos e 1 para Clientes. Dessa forma aplico as regras que desejo para cada datamodule individualmente.
Para facilitar (quando devo abrir o que), crio procedimentos dentro do datamodule do tipo Abrir e Fechar, assim, para abrir o que preciso de um datamodule faço:

DmClientes.Abrir;
ou
DmClientes.Fechar;

Normalmente, antes de criar esses datamodules, crio um datamodule matriz que dará origem a todos os outros, nele é que coloco esse tipo de função, então trato, cada um de acordo com a necessidade. Assim, não preciso ficar criando instancias do datamodule dentro do sistema.


GOSTEI 0
Aerreira

Aerreira

26/10/2005

Você poderia trabalhar com a sua idéia inicial de trabalhar com as tags... mas a cada form que abrisse (e que utilizasse o dataset), seria adicionado 1 na tag do dataset. Ao fechar o form, tira-se 1 da tag do dataset. Se o dataset estiver com a tag = 0 então, ele deve ser fechado, senão não. É uma forma mais simples de implementar o que já estava pronto.


Taí, gostei da sua ideia de usar o tag para controlar ´quantos´ abriram o dataset e não ´quem´ como eu havia pensado, simplifica tudo, basta ir incrementando ao abrir e diminuindo ao pedir para fechar, mas realmente só fechar quando o tag estiver em 0.

Acredito que isso irá funcionar, mas fiquei curioso em ver a situação passada pelo ANFM e pelo BON JOVI com relação a criação instâncias locais para o DataModule, pena que ainda não funcionou... Alguem saberia dizer o que ainda está errado ?


GOSTEI 0
Bon Jovi

Bon Jovi

26/10/2005

O modo mais simples:
//Project1.dpr

program Project1;

uses
  Forms,
  Unit1 in ´Unit1.pas´ ,
  Unit2 in ´Unit2.pas´ {DataModule1: TDataModule};

{$R *.RES}

var
  Form1: TForm1;
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

//Form...

//Unit1.pas

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, Unit2, Grids, DBGrids;

type
  TForm1 = class(TForm)

    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    DataModule1: TDataModule1;
  public
    { Public declarations }
  end;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  DataModule1 := TDataModule1.Create(nil);
  DataSource1.DataSet := DataModule1.ADODataSet1;
end;

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

end.

//Unit1.DFM

object Form1: TForm1
  Left = 192
  Top = 107
  Width = 696
  Height = 480
  Caption = ´Form1´
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  object DBGrid1: TDBGrid
    Left = 4
    Top = 4
    Width = 320
    Height = 120
    DataSource = DataSource1
  end
  object DataSource1: TDataSource
    Left = 328
    Top = 4
  end
end

//Data module...
//Unit2.pas

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, ADODB;

type
  TDataModule1 = class(TDataModule)
    ADOConnection1: TADOConnection;
    ADODataSet1: TADODataSet;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.DFM}

end.

//Unit2.DFM

object DataModule1: TDataModule1
  Left = 272
  Top = 162
  Height = 480
  Width = 696
  object ADOConnection1: TADOConnection
    Left = 40
    Top = 20
  end
  object ADODataSet1: TADODataSet
    Connection = ADOConnection1
    Left = 124
    Top = 20
  end
end


Melhorando..
//dpr
program Project1;

uses
  Forms,
  Unit1 in ´Unit1.pas´ ,
  Unit2 in ´Unit2.pas´ {DataModule1: TDataModule},
  Unit3 in ´Unit3.pas´;

{$R *.RES}

var
  Form1: TForm1;
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

//pas
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, Grids, DBGrids, Unit3;

type
  TForm1 = class(TForm)
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
    Negocio1: TNegocio1;
  public
    { Public declarations }
  end;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Negocio1 := TNegocio1.Create;
end;

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

procedure TForm1.FormShow(Sender: TObject);
begin
  DataSource1.DataSet := Negocio1.Abre;
end;

end.

//dfm
object Form1: TForm1
  Left = 192
  Top = 107
  Width = 696
  Height = 480
  Caption = ´Form1´
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = ´MS Sans Serif´
  Font.Style = []
  OldCreateOrder = True
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object DBGrid1: TDBGrid
    Left = 4
    Top = 4
    Width = 320
    Height = 120
    DataSource = DataSource1
    TabOrder = 0
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = ´MS Sans Serif´
    TitleFont.Style = []
  end
  object DataSource1: TDataSource
    Left = 328
    Top = 4
  end
end

//pas
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, DbClient, ADODB, Provider;

type
  TDataModule1 = class(TDataModule)
    ADOConnection1: TADOConnection;
    ADODataSet1: TADODataSet;
    ClientDataSet1: TClientDataSet;
    DataSetProvider1: TDataSetProvider;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.DFM}

end.

//dfm
object DataModule1: TDataModule1
  OldCreateOrder = True
  Left = 272
  Top = 162
  Height = 480
  Width = 696
  object ADOConnection1: TADOConnection
    Left = 40
    Top = 20
  end
  object ADODataSet1: TADODataSet
    Connection = ADOConnection1
    Parameters = <>
    Left = 124
    Top = 20
  end
  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    Params = <>
    ProviderName = ´DataSetProvider1´
    Left = 292
    Top = 20
  end
  object DataSetProvider1: TDataSetProvider
    DataSet = ADODataSet1
    Constraints = True
    UpdateMode = upWhereKeyOnly
    Left = 208
    Top = 20
  end
end

//pas
unit Unit3;

interface

uses
  DbClient, Unit2;

type
  TNegocio1 = class(TObject)
  private
    DataModule1: TDataModule1;    
  public
    constructor Create; 
    destructor Destroy; override;
    function Abre: TClientDataSet;
    procedure Fecha;
  end;

implementation

function TNegocio1.Abre: TClientDataSet;
begin
  DataModule1.ClientDataSet1.Close;
  DataModule1.ADODataSet1.CommandText := ´SELECT...´;
  DataModule1.ClientDataSet1.Open;
  Result := DataModule1.ClientDataSet1;
end;

procedure TNegocio1.Fecha;
begin
  DataModule1.ClientDataSet1.Close;
end;

constructor TNegocio1.Create;
begin
  DataModule1 := TDataModule1.Create(nil);
end;

destructor TNegocio1.Destroy;
begin
  DataModule1.Free;
  inherited;
end;

end.



GOSTEI 0
Aerreira

Aerreira

26/10/2005

Bom dessa vez funcionou com as explicações do BonJovi.

Estou testando em apenas um form da aplicação para ver se funciona, que usa apenas dois datasets, em linhas gerais o que mudou com as últimas explicações foi:

No form:

- a declaração do DataModule vai para o uses da Interface

- é criada a variável privada ´dmLocal: Tdm;´ (acho que era isso que estava faltando, lembrando que meu DataModule principal chama-se ´dm´)

- no OnCreate do form, vai a criação da instância local do DM: ´dmLocal := Tdm.Create(nil);´ mais a ligação dos DataSources aos DataSets do dmLocal: ´dsConv.dataset := dmLocal.tbConv;´ e ´dsTab.dataset := dmLocal.tbTab;´

- no OnShow do form, vai a abertura dos datasets ´dmLocal.tbConv.open;´ e ´dmLocal.tbTab.open;´

- no OnClose do form, vai o fechamento dos datasets ´dmLocal.tbConv.close;´ e ´dmLocal.tbTab.close;´

- no OnDestroy do form, libero o dmLocal da memória: ´dmLocal.free;´

No DataModule:

- não muda nada, apenas passarei a usar os DataSets dentro dos forms e não no datamodule.


Funcionou, pois outros forms que abrem os datasets do DM original, continuam abrindo e fechando enquanto o datasets do form de teste continua aberto, ou seja, está sendo usado o dmLocal de forma independente do DM principal.

Não usei as funções que você apresenta em seu segundo exemplo como Abre e Fecha. Falando em segundo exemplo, se eu entendi vc tem uma unit (unit2) para o datamodule e outra unit (unit3) para tratar a outra instância do datamodule e não no próprio form como no seu primeiro exemplo. É isso?

De qualquer modo, vou testar implementando os DM locais em vários forms e ver se funciona bem. Te agradeço pelas dicas.

Efeito colateral: quando a instância do DM é criada o OnCreate do datamodule é executado, e é lá que identifico a localização do banco e abro o IBDataBase... Isso está correto? Provavelmente com isso estou abrindo o banco totalmente independente como se fosse outra aplicação.

Uma questão: se eu tiver muitos forms abertos, cada um com uma instância do DM com vários datasets abertos... isso não vai sobrecarregar muito a memória não?


GOSTEI 0
Aerreira

Aerreira

26/10/2005

Bom, quanto ao tópico fiquei com duas opções:

- Usar instâncias diferentes do DataModule em cada form da aplicação;

ou

- Abrir os DataSets no próprio DataModule original, controlando pela propriedade TAG quantas vezes o dataset foi aberto, e fechar apenas quando o último form solicitar o fechamento.

As duas soluções estão funcionando, agora resta a dúvida: qual das duas funcionará melhor com a aplicação funcionando, com umas 20 estações de rede num banco com tamanho previsto de aproximadamente uns 200Mb (tamanho baseado na aplicação atual em DOS) ?

A primeira solução dá um isolamento total entre os forms, porém acho que poderá ocupar muita memória, talvez também gerar mais tráfego na rede por abrir e fechar o banco em cada form, e não sei quais poderão ser as conseguencias em máquinas pequenas.

A segunda solução mantém tudo ligado. Num teste que fiz, abri o mesmo form mais de uma vez e a navegação numa tabela ocorre simultaneamente nas duas telas, com a primeira solução isso não aconteceria.

Alguem poderia dar uma opinião para tirar essa minha dúvida?


GOSTEI 0
Bon Jovi

Bon Jovi

26/10/2005

[i:2ee3bad4cb]´se eu entendi vc tem uma unit (unit2) para o datamodule e outra unit (unit3) para tratar a outra instância do datamodule e não no próprio form como no seu primeiro exemplo. É isso?´[/i:2ee3bad4cb]
É por aí, faço assim pra separar totalmente a interface grafica do usuário com as regras de negócio e acesso ao servidor de banco de dados. Colocar o ClientDataSet direto no form também é correto.

[i:2ee3bad4cb]´Efeito colateral: quando a instância do DM é criada o OnCreate do datamodule é executado, e é lá que identifico a localização do banco e abro o IBDataBase... Isso está correto? Provavelmente com isso estou abrindo o banco totalmente independente como se fosse outra aplicação.´[/i:2ee3bad4cb]
Basta vc criar um DataModule só para a conexao, assim abrirá somente uma vez a conexão.

[i:2ee3bad4cb]´Uma questão: se eu tiver muitos forms abertos, cada um com uma instância do DM com vários datasets abertos... isso não vai sobrecarregar muito a memória não?´[/i:2ee3bad4cb]
Depende do ponto de vista, mas eu considero que não, pois estará usando recursos sob demanda, não terá nada aberto a toa e sem malabarismos de tags. E não deixe de usar ClientDataSet, senão realmente estará cutucando muito os servidor. Outra saída tb seria trabalhar com clonagem de ClientDataSet, mas só gosto de usar quando é extremamente necessário.


GOSTEI 0
Bon Jovi

Bon Jovi

26/10/2005

[i:293aefaf11]´um banco com tamanho previsto de aproximadamente uns 200Mb´[/i:293aefaf11]
Isso não importa, pode ser 10 GB, portanto que logicamente vc não traga todos os registros da tabela, e sim o necessário que o usuário quer consultar, geralmente um único registro.


GOSTEI 0
Aerreira

Aerreira

26/10/2005

[quote:86d7b7a7c8=´Bon Jovi´][i:86d7b7a7c8]´um banco com tamanho previsto de aproximadamente uns 200Mb´[/i:86d7b7a7c8]
Isso não importa, pode ser 10 GB, portanto que logicamente vc não traga todos os registros da tabela, e sim o necessário que o usuário quer consultar, geralmente um único registro.[/quote:86d7b7a7c8]

Certo, isso já uso, na medida do possível, por praxe, mas veja uma questão:
Uma tela de atendimento de pacientes, onde tenho os seguintes datasets abertos (uns para atualização outros apenas para consulta): pacientes, convênios, planos, medicos, especialidades, atendimentos, itens do atendimento, serviços, materiais, medicamentos, circulares e parâmetros, considerando todos visualizando apenas um registro. Ainda assim são 12 datasets abertos numa instancia do DM. Em outra tela o usuário abre uma agenda com mais uns 10 datasets, e ao mesmo tempo está gerando um determinado relatório com mais uns 5 datasets em outro DM.

Será que isso fica melhor usando a opção de DM locais ou abrindo tudo num único DM controlando os datasets abertos? O que pesa menos na rede e também em termos de memória nas estações?


GOSTEI 0
Bon Jovi

Bon Jovi

26/10/2005

A cada tela que o usuário for abrir, possivelmente ele vai querer acessar os dados mais atualizados, com filtros diferentes e particularidades que possam sempre vir a surgir nessa outra tela.

Se as máquinas estão tão apertadas assim de recursos e as linhas acessadas são sempre as mesmas em diversos lugares (o que não entendo pq), use então clonagem de ClientDataSets, onde vai abrir os dados uma vez e cada clone terá navegação independente.


GOSTEI 0
Aerreira

Aerreira

26/10/2005

[quote:79892ffd83=´Bon Jovi´]A cada tela que o usuário for abrir, possivelmente ele vai querer acessar os dados mais atualizados, com filtros diferentes e particularidades que possam sempre vir a surgir nessa outra tela.
[/quote:79892ffd83]
Certo.

[quote:79892ffd83=´Bon Jovi´]Se as máquinas estão tão apertadas assim de recursos e as linhas acessadas são sempre as mesmas em diversos lugares (o que não entendo pq), use então clonagem de ClientDataSets, onde vai abrir os dados uma vez e cada clone terá navegação independente.[/quote:79892ffd83]

Não que as máquinas estejam apertadas, mas tenho a sensação de que os DM locais irão gerar muitos objetos em memória (cada DM com todos os componentes que ele tem, conexão, transaction, datasets, ´datasources´ sim porque não), enquanto na outra solução haveria um único DM a ser tratado. Não uso ClientDataSet e sim IBDataSet pois uso IBX/Delphi5.

Não entendi seu questionamento ´[i:79892ffd83]as linhas acessadas são sempre as mesmas em diversos lugares (o que não entendo pq)[/i:79892ffd83]´.

Como assim as mesmas linhas? Você quer dizer registros das tabelas? Em diversos lugares sim, como não? O usuário pode estar registrando informações sobre o atendimento de um paciente, em outra tela estar consultando / incluindo novos apontamentos na agenda de um médico, que também está atendendo o paciente da primeira tela, e ao mesmo tempo estar extraindo um relatório relativo aos atendimentos do mesmo médico no dia anterior... Isso é a realidade do negócio... Tudo ao mesmo tempo sim.. porque não... por isso a mesma informação (médico) é tratada em vários pontos ao mesmo tempo... porque não seria assim?


GOSTEI 0
Bon Jovi

Bon Jovi

26/10/2005

´a sensação de que os DM locais irão gerar muitos objetos em memória (cada DM com todos os componentes que ele tem´.
Sim, cada um com sua área de memória.

´conexão, transaction´
Como disse anteriormente, vc pode criar um DataModule só pra conexão e instancia-lo uma única vez.

´´datasources´ sim porque não´
DataSource serve pra ligar componentes visuais, ao ClientDataSet de preferência, então devem estar do lado cliente/interface gráfica com o usuário.

´Não uso ClientDataSet e sim IBDataSet pois uso IBX/Delphi5´
Mantendo IBDataSet abertos diretamente pro usuário em DBGrids ou DBCombos por exemplo podem gerar muito mais idas e voltas ao servidor do que o ClientDataSet (que pode ficar totalmente desconectado). Delphi 5 tb tem o ClientDataSet, podendo ser usado com o IBX.

Sobre esses dados de um médico, aí sim poderiam ficar em um único DataSet, pois não há navegação por ser uma única linha. Assim como poderiam ficar em variáveis. Caso contrário, clone.


GOSTEI 0
Aerreira

Aerreira

26/10/2005

Ok, pela questão do isolamento entre as operações, estou optando por instanciar os DMs localmente em cada form. E sim (obrigado pela dica), vou criar um outro DM apenas para a conexão com o banco (ex: dmCON) e ligar os datasets do DM principal (e suas instâncias locais) ao dmCON.DB e dmCON.TRAN.

Com relação aos DataSources, já li pessoas dizerem que é apenas uma questão de preferência e organização, muitos fazem como vc diz, porém muitos dizem ser errado, pois mistura coisas que deveriam estar em outro local, na prática, não muda nada. Prefiro manter as coisas mais organizadas deixando os datasources ao lado dos datasets, se eu precisar de algo um pouco diferente, aí sim coloco um datasource no form e trabalho com ele separado, mas como agora terei DMs proprios para cada form, faço com eles o que for necessário em cada instanciamento, mas mantenho os datasources no DM.

No meu caso, por exemplo, o dataset de convênios é usado em muitos forms, quase tudo no sistema lida com os dados de convênios, com isso eu teria uma infinidade de datasources ´dsConv´ espalhandos nos forms da aplicação. Se tenho instâncias do DM independentes para cada form, então porque não deixar apenas um único dsConv lá no DM e usar ele para as conexões com os componentes de cada form? Não é muito mais racional?

Com relação ao ClientDataSet, realmente eu nunca usei esse componente, está lá no MIDAS certo? Vou estulá-lo melhor para entender suas diferenças.

Este tópico aqui, pelo menos pra mim, foi bastante esclarecedor, espero que tenha sido para outras pessoas também. Assim que eu tiver uma posição mais clara sobre usar IBDataSet ou ClientDataSet, posto aqui neste tópico.

Um abraço,


GOSTEI 0
Bon Jovi

Bon Jovi

26/10/2005

[size=9:54a4384420][i:54a4384420]´No meu caso, por exemplo, o dataset de convênios é usado em muitos forms, quase tudo no sistema lida com os dados de convênios, com isso eu teria uma infinidade de datasources ´dsConv´ espalhandos nos forms da aplicação. Se tenho instâncias do DM independentes para cada form, então porque não deixar apenas um único dsConv lá no DM e usar ele para as conexões com os componentes de cada form? Não é muito mais racional´[/i:54a4384420][/size:54a4384420]
Sim, pode ser, tudo depende do caso mesmo.
[size=9:54a4384420][i:54a4384420]
´Assim que eu tiver uma posição mais clara sobre usar IBDataSet ou ClientDataSet, posto aqui neste tópico. ´[/i:54a4384420][/size:54a4384420]
Ok. Sobre Midas a questão não é usar IBDataSet ou ClientDataSet, e sim os dois ao mesmo tempo, o IBDataSet serveria apenas pra trazer os dados do servidor e manter na memória do ClientDataSet. Se está começando o projeto agora, vale a pena partir logo pra esse lado.


GOSTEI 0
Aerreira

Aerreira

26/10/2005

É... acabei tendo que ceder... vou ter que colocar os DataSources todos nos forms mesmo, pois somente em run-time eu tenho o dmLocal ativo e pronto para ser relacionado aos componentes do form, em design-time não tenho como relacionar os componentes do form a um datasource dentro de um DataModule que ainda não existe.

Daria certo se, via código, eu fizesse a ligação da propriedade datasource de todos os componentes de cada form ao dmLocal, mas isso seria coisa de maluco... Daria muito trabalho. Vou ter então que colocar os datasources no form para poder ligar os componentes neles, e ao instanciar o dmLocal eu apenas faço a ligação entre o datasouce ao dataset recem instanciado...

É isso.


GOSTEI 0
João

João

26/10/2005

Eu costumo criar uma cópia do datamodule para cada form.

Para fazer isto faça o seguinte:

No uses da sua unit declare o unit do datamodule;

Na seção private declare uma variável que receberá a cópia do datamodule: DMLocal : TDataModule;

No on create do seu form coloque:

DMLocal := TDataModule.Create(Self)
DataSource1.DataSet := DMLocal.NomeTabela;




No caso eu não tenho o dataSource posso usar o fdquery e outra é >>DMLocal : TDataModule; <<isso eu coloco no meu form né, e isso também >>

DMLocal := TDataModule.Create(Self)
DataSource1.DataSet := DMLocal.NomeTabela;<<

Então concluindo que não vai nada no datamodule?
GOSTEI 0
POSTAR