Array
(
)

Problemas ao executar ClientDataSet em tempo de execução

Danielnascimento
   - 18 set 2004

tenho o seguinte trecho de codigo

type

TPesquisa = class(TObject)
public
DataSource: TDataSource;
qry: TSQLQuery;
dsp: TDataSetProvider;
cds: TClientDataSet;

constructor Create;
function Pesquisar(): Integer;
end;

implementation

{ TPesquisa }

uses dmpoo;

constructor TPesquisa.Create;
begin
qry := TSQLQuery.Create(Nil);
DataSource := TDataSource.Create(Nil);
dsp := TDataSetProvider.Create(Nil);
cds := TClientDataSet.Create(Nil);

qry.SQLConnection := DataModule1.SQLConnection1;
DataSource.DataSet := cds;
dsp.DataSet := qry;
cds.ProviderName := dsp.Name;
end;

function TPesquisa.Pesquisar(): Integer;
begin
cds.Close;
qry.SQL.Add(´SELECT * FROM TAB_PESSOA´);
cds.ProviderName := dsp.Name;
cds.Open;
result := 1;
end;


quando instancio o objeto e executo o metodo pesquisar... é retornada a exceção:

MISSING DATA PROVIDER OR DATA PACKET

Gostaria que alguém me sugerisse uma solução...
Ou apontasse o problema em meu código...

Abraços a todos
Daniel Nascimento


Beppe
   - 18 set 2004

Solução: Atribua um nome único ao TDataSetProvider.
#Código

dsp.Name := ´MeuProvedor´;

Racionalização: Em tempo de projeto, quando você insere um componente ou controle no formulário, a IDE do Delphi gera um nome automáticamente a ele. Quando você o cria via código, ele é criado sem nome.

PS: Pelo trecho de código que você apresentou, está esquecendo de liberar os componentes. Se você não o faz no destruidor, pode passar Self no construtor de cada componente de dados, assim eles são liberados automaticamente com a sua instância de TPesquisa.


Danielnascimento
   - 18 set 2004

constructor TPesquisa.Create;
begin
qry := TSQLQuery.Create(Nil);
DataSource := TDataSource.Create(Nil);
dsp := TDataSetProvider.Create(Nil);
cds := TClientDataSet.Create(Nil);
qry.SQLConnection := DataModule1.SQLConnection1;
dsp.Name := ´DataSetProviderTeste´;
dsp.DataSet := qry;
cds.ProviderName := dsp.Name;
DataSource.DataSet := cds;
end;

function TPesquisa.Pesquisar(): Integer;
begin
cds.Close;
qry.SQL.Add(´SELECT * FROM TAB_PESSOA´);
cds.Open;
result := 1;
end;

a correção foi realizada conforme sugerido...


porém o erro descrito no 1 post ainda persiste

[]s
Daniel Nascimento


Beppe
   - 18 set 2004


Citação:
a correção foi realizada conforme sugerido...

Sério? Ainda estou vendo os nil no lugar... :?

Mude de nil para Self ao menos no construtor do provedor e do dataset cliente. Simulei seu exemplo e rodou perfeitamente assim.


Danielnascimento
   - 18 set 2004

unit tstPOO;

interface

uses
SysUtils, Classes, DBXpress, DB, SqlExpr, FMTBcd, Provider, DBClient;

type

TPesquisa = class(TObject)
public
DataSource: TDataSource;
qry: TSQLQuery;
dsp: TDataSetProvider;
cds: TClientDataSet;

constructor Create;
destructor Destroy; Override;
function Pesquisar(): Integer;
end;

implementation

{ TPesquisa }

uses dmpoo;

constructor TPesquisa.Create;
begin
qry := TSQLQuery.Create(nil);
DataSource := TDataSource.Create(nil);
dsp := TDataSetProvider.Create(nil);
cds := TClientDataSet.Create(nil);
qry.SQLConnection := DataModule1.SQLConnection1;
dsp.Name := ´DataSetProviderTeste´;
dsp.DataSet := qry;
cds.ProviderName := dsp.Name;
DataSource.DataSet := cds;
end;

destructor TPesquisa.Destroy;
begin
qry.Free;
DataSource.Free;
dsp.Free;
cds.Free;
inherited;
end;

function TPesquisa.Pesquisar(): Integer;
begin
cds.Close;
qry.SQL.Add(´SELECT * FROM TAB_PESSOA´);
cds.Open;
result := 1;
end;

end.


Amigo ai está a unit do objeto!!!

bem modifiquei o objeto qry, e cds, para

qry := TSQLQuery.Create(Self)
e
cds := TClientDataSet.Create(Self)

e a seguinte mensagem ocorreu!!!

Incompatibles types... TComponent and TPesquisa...


ou seja tipos incompatíves....

Como vc havia sugerido criei tb o destrutor destruindo os objetos criados...!!!! acho que agora esta ok... porem o erro permanede :shock:
ja nao tenho mais ideias do que realizar...

não seria pedir demais para vc listar o código que vc esta testando ai??
Agradeço pela sua ajuda Beppe... esta sendo de grande valia!!!


[]s
Daniel Nascimento


Beppe
   - 19 set 2004

Me desculpe...eu fiz o teste destro do TForm1, mas criando os componentes via código, como você fez. Não cheguei a testar com um derivado direto de TObject, como é TPesquisa.

Eu tinha sugerido duas alternativas para efetuar o controle da memória(os componentes que nunca eram liberados). Uma delas resolve o seu problema que você relatou, então aconselho a fazer isto.

Primeiro, descenda TPesquisa de TComponent. Assim poderá passá-lo como proprietário dos outros componentes, e de quebra fazer o ´memory management´.

Segundo, remova o destruídor. A liberação de componentes é feita automática no seu caso, ao destruir a instância de TPesquisa.

Se ficou alguma dúvida, poste aí.


Danielnascimento
   - 19 set 2004

Olá beepe...


cara valeu pela ajuda...

deu certinho aqui...

to te devendo essa!!!

[]s
Daniel Nascimento


Beppe
   - 19 set 2004

Estamos aqui pra isso! :wink:


Christian_adriano
   - 18 dez 2004

Olá Colega ´Beppe´,

Estou com um ´probleminha´, estou criando um CDS (TClientDataSet) em tempo de execução, até ae tudo bza, só q quero ´Atribuir o DataSetProvider´ que está ´ligado´ com um DBEdit.

Tentei o seguinte:

FQrPesquisa.ProviderName := TClientDataSet(FZCampo.DataSource.DataSet).ProviderName;

Onde:
FQrPesquisa = TClientDataSet;
FZCampo = TDBEdit;

Obs. No campo ´FZCampo´ esta ´ligado´ com DataSource q está ligado em um outro CDS. Só quero pegar o DataSetProvider desse CDS que esta ´ligado´ com o TDBEdit (FZCampo).

Desde de já agradeço atenção.

[]´s.

Christian.


Rômulo Barros
   - 20 dez 2004

Acredito q você ainda não tenha solucionado o problema.
Para linkar o DataSetProvider ao ClientDataSet, faça:

#Código

ClientDataSet.SetProvider(DataSetProvider);


No seu caso, ficaria assim:

#Código
Cds.SetProvider(Dsp);


:arrow: Espero ter esclarecido a situação.