ClientDataSet extendido

Delphi

28/04/2014

Ola a todos, estou criando um ClientDataSet que acessa diretamente a baso de dados (o dataSetProvider e a query são implícitos). eu já consegui acessar a base de dados e exibir os registro.

Meu problema é que preciso criar internamente o dataSetProvider e a query antes de chamar o Field Editor. alguém saberia como fazer isso?
Benjamim Jr

Benjamim Jr

Curtidas 0

Respostas

Eliel Martins

Eliel Martins

28/04/2014

Olá Benjamim,

Não sei se entendi corretamente, mas eu faria deste modo.

Var
  qAUTO    : TSQLQuery;
  Dsp_Auto : TDataSetProvider;
  Cds_Auto : TClientDataSet;
begin
  {Rotina para liberação de pedidos que são comodatos,troca}
    qAUTO               := TSQLQuery.Create(Self);
    qAUTO.SQLConnection := DmBase.SESSAO;

    Dsp_Auto            := TDataSetProvider(Self);
    Dsp_Auto.DataSet    := qAUTO;

    Cds_Auto            := TClientDataSet.Create(Self);
    Cds_Auto.ProviderName := 'Dsp_Auto';
end;
  


Senão for isso, por gentileza explique mais detalhado.

Atenciosamente,

Eliel Gonçalves Martins.
GOSTEI 0
Benjamim Jr

Benjamim Jr

28/04/2014

Infelizmente não é isso. Quando vamos criar o acesso ao banco de normalmente se usa a seguinte estrutura:

ADOConnection1,
ADOQuery1.Connection:= ADOConnection1
DataSetProvider1.DataSet:= ADOQuery1
ClientDataSet1.ProviderName:= DataSetProvider1.name

Dessa forma apos informar corretamente os dados da conexão e o sql no query é possível clicar com o botão direito sopre o ClientDataSet1 selecionar "Fields Editor..", clicar com o botão direito na tela que se abre e selecionar "Add All Fields" para adicionar todos os campos no ClientDataSet. Porem no componente que estou tentando desenvolver o ADOQuery1e o DataSetProvider1 são criados dinamicamente (não existem em tempo de projeto), dessa forma o a sequencia de ações descritas dispara a mensagem de erro "Missing data provider or data packet".

O intuito deste componente é reduzir o numero de objetos no DataModule e simplificar o processo de configuração já que o próprio ClientDataSet teria uma propriedade Connection e uma SQL.
GOSTEI 0
Benjamim Jr

Benjamim Jr

28/04/2014

up
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

28/04/2014

no seu caso será algo como:

FADOQuery := TADOQuery.Create(Self);
FADOQuery.Connection:= FADOConnection;

FDatasetProvider := TDatasetProvider.Create(Self);
FDatasetProvider.Dataset := FADOQuery;

FClientDataSet := TClientDataSet.Create(Self);
FClientDataSet.SetProvider(FDatasetProvider); // aqui 'seta' corretamente o provider
GOSTEI 0
Benjamim Jr

Benjamim Jr

28/04/2014

interessante! eu ó conhecia a propriedade providername e usando ela com "self" no create não funcionava.
Assin que tiver um tempo na empresa amanha vou testar e posto o resultado aqui.
GOSTEI 0
Benjamim Jr

Benjamim Jr

28/04/2014

Acabei de testar e funcionou!

O único problema que apareceu foi quando eu alterava a propriedade Active para true pela segunda, aparecia o erro "missing data provider or data packet".
Eu resolvi o erro sobrescrevendo a propriedade, abaixo segue todo o código do componente.

unit ClientDataSetEx;

interface

uses
  Classes, DBClient, ZConnection, WideStrings, ZDataset, Provider, SysUtils,
  Designintf, DesignEditors, DesignMenus, Variants, Dialogs, DB;

type
  TClientDataSetEx = class(TClientDataSet)
  private
    fSQL: TWideStrings;
    fConnection: TZConnection; 
    fQuery: TZQuery;
    fDataSetProvider: TDataSetProvider;
    function GetSQL: TWideStrings;
    function GetActive: Boolean;
    procedure SetSQL(const Value: TWideStrings);
    procedure SetConnection(const Value: TZConnection);
    procedure SetActive(const Value: Boolean);
  protected
    procedure QueryChanged(Sender: TObject);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Active: Boolean read GetActive write SetActive;
    property Connection: TZConnection read fConnection write SetConnection;
    property SQL: TWideStrings read GetSQL write SetSQL;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Extras', [TClientDataSetEx]);
end;

{ TClientDataSetEx }

constructor TClientDataSetEx.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FSQL := TWideStringList.Create;
  TWideStringList(FSQL).OnChange := QueryChanged;

  fQuery:= TZQuery.Create(Self);
  fDataSetProvider:= TDataSetProvider.Create(Self);
  fDataSetProvider.DataSet:= fQuery;

  Self.SetProvider(fDataSetProvider); // aqui 'seta' corretamente o provider
end;

function TClientDataSetEx.GetActive: Boolean;
begin
  Result:= inherited Active;
end;

function TClientDataSetEx.GetSQL: TWideStrings;
begin
  Result := FSQL;
end;

procedure TClientDataSetEx.QueryChanged(Sender: TObject);
begin
  fQuery.SQL.Text:= Self.fSQL.Text;

  if not (csLoading in ComponentState) then
    Close;
end;

procedure TClientDataSetEx.SetActive(const Value: Boolean);
begin                   
  Self.SetProvider(fDataSetProvider);
  inherited Active:= Value;
end;

procedure TClientDataSetEx.SetConnection(const Value: TZConnection);
begin
  fConnection := Value;
  fQuery.Connection:= fConnection;
end;

procedure TClientDataSetEx.SetSQL(const Value: TWideStrings);
begin
  fSQL.Assign(Value);
end;

end.
GOSTEI 0
POSTAR