Fórum Problema em referenciar Componentes #347846

24/10/2007

0

Tenho um problema. Por exemplo:

Em um botao eu crio um ClientDataSet e seto seu nome com um prefixo+valor

Var
NomePapel: String

ClientDataSet := TClientDataSet.Create(Form1);
ClientDataSet.Name := ´ClientDataSet´ + NomePapel; ClientDataSet.FieldDefs.Add(´Serie´,ftString,7,false);

E em um outro botao eu preciso adicionar dados a esse ClientDataSet, para eu preciso acessa-lo montando dinamicamente seu nome, como por exemplo:

(´ClientDataSet´ + ´Papel1´).Append;
(´ClientDataSet´ + ´Papel1´).Fieldbyname(´Serie´).AsString := ´K45´;

Sei que dessa forma nao funciona, mais é apenas uma forma de exemplicar. Tentei de varias formas mais nao consegui.

Eu vi exemplos onde eu posso ter uma variavel global e no momento da criacao associar o objeto criado a essa variavel global e depois utilizar essa variavel para referenciar o objeto. Mas eu nao posso ter variaveis globais estaticas pois eu nao sei quantos objetos serao criados.

Como posso resolver esse problema ?

Abracos.


Kleysonr

Kleysonr

Responder

Posts

24/10/2007

Joaoshi

Colega, isto não vai resolver todo o problema, mas deve ajudar.

para teste coloque no form alguns componentes, e no evento do button1 coloque o codigo abaixo:


procedure TForm1.Button1Click(Sender: TObject);
var sArquivo:TClientDataSet;
nX:Integer;
begin
sArquivo:= TClientDataSet.Create(Self);
sArquivo.Name := ´Arquivo1´;
Try
For nX := 0 to Form1.ComponentCount -1 do
ListBox1.Items.add (Form1.Components[nX].Name);
Finally
sArquivo.Free;
End;
end;


Espero ter ajudado.


Responder

Gostei + 0

24/10/2007

Micheus

[b:776b7f1e72]kleysonr[/b:776b7f1e72], minha sugestão é que no OnClick do seu botão que adiciona os dados:
procedure Form1.BtnGravarClick(sender :TObject);
var
  CDS :TClientDataSet;
begin
  CDS := FindComponent(´ClientDataSet´ + ´Papel1´) as TClientDataSet;
  if Assigend(CDS) then  // encontrou componente
  begin
    CDS.Append;
    CDS.Fieldbyname(´Serie´).AsString := ´K45´;
    ...
    CDS.Post;
  end;
end;

é claro que vc deverá já ter algum meio de saber qual dataset irá acessar (o seu nome: Papel1, Papel2,...)


Responder

Gostei + 0

24/10/2007

Kleysonr

Joaoshi isso nao me atende muito.

Olha so meu problema. Eu vou criar varios clientdataset (nao sei quantos) e esses dataset´s vao ser populados com dados. Entao eu vou estar recebendo constante de uma fonte externas dados para serem atualizados em um dbgrid, e desse dado que vem da parte externa tem um pedaco do nome que usei para setar a propriedade nome do ClientDataSet. E como o fluxo desses dados que chegam é muito grande e rapido eu nao posso ficar fazendo um loop nos componentes para achar o que eu quero, eu precisaria acessar diratamente o componente.

Nao existe uma forma de montar o nome e acessar diretamente ? Fazer um typecast ou alguma coisa assim ? Algo no estilo do exemplo abaixo ?

procedure AlterarDado(papel: string)
begin
TClientDataSet(´ClientDataSet´ + papel).Append;
...
end;


Responder

Gostei + 0

24/10/2007

Kleysonr

Micheus,

Funcionou, eu havia testado dessa forma:
CDS := FindComponent(´ClientDataSet´ + ´Papel1´) as TClientDataSet;

So que nao tinha funcionado pois eu nao tinha colocado ´as TClientDataSet´. Agora com esse complemento foi.

Com o comando FindComponent eu acredito que ele faca um loop procurando o componente e testando o nome. Para uma aplicacao em tempo real com varias alteracoes ao mesmo tempo isso pode causar um overhead. Nao existe uma forma de acessar o componente direto ?

Mas mesmo assim, valeu !!









procedure Form1.BtnGravarClick(sender :TObject);
var
CDS :TClientDataSet;
begin
CDS := FindComponent(´ClientDataSet´ + ´Papel1´) as TClientDataSet;
if Assigend(CDS) then // encontrou componente
begin
CDS.Append;
CDS.Fieldbyname(´Serie´).AsString := ´K45´;
...
CDS.Post;
end;
end;

é claro que vc deverá já ter algum meio de saber qual dataset irá acessar (o seu nome: Papel1, Papel2,...)
_________________
´Há sempre, pelo menos, dois modos de fazer uma mesma coisa.
Mesmo que sejam: certo e errado.´ (Micheus)


Responder

Gostei + 0

24/10/2007

Micheus

Com o comando FindComponent eu acredito que ele faca um loop procurando o componente e testando o nome.
exato. Será ´varrida´ toda a lista de componentes do seu Form.

Para uma aplicacao em tempo real com varias alteracoes ao mesmo tempo isso pode causar um overhead. Nao existe uma forma de acessar o componente direto ?
Isto até seria relevante se seu form/datamodule contiver muitos componentes.
Se for o caso, vc poderia utilizar um TStringList global a este seu form/datamodule e nele armazenar os TClientDataSet´s adicionados dinamicamente - é o único jeito de ter uma lista menor para procurar.
Deve ficar algo mais ou menos assim:
type
  Form1 = class(TForm)
    ...
  private
    CDSList :TStringList;
  end;

...
procedure TForm1.Form1Create(sender :TObject);
begin
 // aloca lista
  CDSList := TStringList.Create;
  ...
end;

procedure TForm1.FormDestroy(sender :TObject);
var
  Idx :Integer;
begin
 // libera componentes CDS da lista 
  for Idx := 0 to CDSList.Count -1 do
    if Assigned(CDSList.Objects[Idx]) then
      (CDSList.Objects[Idx] as TClienteDataSet).Free;
 // libera lista alocada
  CDSList.Free;
  ...
end;

// onde vc faz a criação do CDS dinamicamente...
procedure TForm1.IncluirDataSet...
Var
  NomePapel: String
  CDS :TClientDataSet;
begin
  ClientDataSet := TClientDataSet.Create(Form1);
  ClientDataSet.Name := ´ClientDataSet´ + NomePapel;
  ClientDataSet.FieldDefs.Add(´Serie´,ftString,7,false); 
  ...
 // adiciona o CDS à lista
  CDSList.AddObject(ClientDataSet.Name, ClientDataSet);
end;

// onde vc grava os dados dinamicamente...
procedure Form1.BtnGravarClick(sender :TObject);
var
  Idx :Integer;
  CDS :TClientDataSet;
begin
  if CDSList.Find(´ClientDataSet´ + ´Papel1´, Idx) then
  begin
    CDS := TClientDataSet(CDSList.Objects[Idx]);
    CDS.Append;
    CDS.Fieldbyname(´Serie´).AsString := ´K45´;
    ...
    CDS.Post;
  end;
end;

...
end.



Responder

Gostei + 0

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

Aceitar