Problema para popular Clientdataset em tempo de execução para executar uma consulta SQL ?

MySQL

Delphi

01/02/2019

Boa tarde, sou novo por aqui.
Preciso configurar o CDS para guardar o resultado da consulta, mas sem arrastar os componentes, já que neste caso não estou usando nenhum form, mas me retorna erro 'Invalid Field Type' nos campos informados. Segue meu código:


begin
CDSEstoque := TClientDataSet.Create(Application);
SDSEstoque.Close;
CDSEstoque.Close;

CDSEstoque.FieldDefs.Clear;
CDSEstoque.FieldDefs.add('ID_PRODUTO', ftInteger);
CDSEstoque.FieldDefs.add('NOME_PRODUTO', ftString, 50);
CDSEstoque.FieldDefs.add('NCM', ftString, 8);
CDSEstoque.FieldDefs.add('QTDADE', ftCurrency);
CDSEstoque.FieldDefs.add('CUSTO_TOTAL', ftCurrency);
CDSEstoque.FieldDefs.add('CUSTO_UNI', ftCurrency);
CDSEstoque.FieldDefs.add('UND', ftString, 2);
CDSEstoque.CreateDataSet;

DataEstoque := FormatDateTime('yyyy-mm-dd', pDataFim);

SDSEstoque.SQLConnection := TDBExpress.getConexao;
SDSEstoque.CommandText := 'SELECT M.ID_PRODUTO, A.NOME_PRODUTO, A.NCM, SUM(M.QUANTIDADE) AS QTDADE, ' +
'SUM(M.VALOR_TOTAL) AS CUSTO_TOTAL, '+
'(SUM(M.VALOR_TOTAL) / SUM(M.QUANTIDADE)) AS CUSTO_UNI, B.SIGLA AS UND '+
'FROM movimento_produto M '+
'INNER JOIN produto A ON (A.ID = M.ID_PRODUTO) '+
'INNER JOIN unidade_produto B ON (B.ID = A.ID_UNIDADE) '+
'WHERE (M.DATA_MOVIMENTO <= '+QuotedStr(DataEstoque)+') '+
'AND QTDADE > 0 GROUP BY M.ID_PRODUTO ORDER BY A.NOME_PRODUTO;';

CDSEstoque.Open;
SDSEstoque.Open;
end;
Wellisson Ribeiro

Wellisson Ribeiro

Curtidas 0

Melhor post

Jucélio Silva

Jucélio Silva

01/02/2019

E ae Wellisson , blz cara ,

Aparentemente seu clientDataset CDSEstoque está OK, pode ser que o SDSEstoque esteja com algum problema nos tipos definidos para os fields....

segue o teste que fiz com o CDSEstoque :

procedure TForm1.FormCreate(Sender: TObject);
var CDSEstoque : TClientDataSet;
begin
CDSEstoque := TClientDataSet.Create(Application);

CDSEstoque.Close;

CDSEstoque.FieldDefs.Clear;
CDSEstoque.FieldDefs.add('ID_PRODUTO', ftInteger);
CDSEstoque.FieldDefs.add('NOME_PRODUTO', ftString, 50);
CDSEstoque.FieldDefs.add('NCM', ftString, 8);
CDSEstoque.FieldDefs.add('QTDADE', ftCurrency);
CDSEstoque.FieldDefs.add('CUSTO_TOTAL', ftCurrency);
CDSEstoque.FieldDefs.add('CUSTO_UNI', ftCurrency);
CDSEstoque.FieldDefs.add('UND', ftString, 2);
CDSEstoque.CreateDataSet;

CDSEstoque.Open;
CDSEstoque.Insert;
CDSEstoque.FieldByName('ID_PRODUTO').AsInteger := 1;
CDSEstoque.Post;


ShowMessage(CDSEstoque.FieldByName('ID_PRODUTO').AsString);
end;


Tenta debugar , quase certo que a zica etá no SDSEstoque ....
GOSTEI 1

Mais Respostas

Wellisson Ribeiro

Wellisson Ribeiro

01/02/2019

Opa, vou testar só me surgiu outra duvida, eu nao estou utilizando nenhum form, so pra entender mais ou menos a ideia, eu preciso fazer uma consulta, e retornar os dados dela, eu faria da forma desse exemplo abaixo?

procedure PopulaR02;
var
ConsultaSQL : String;
begin
CDSR02 := TSQLQuery.Create(nil);

ConsultaSQL := 'SELECT * FROM R02 WHERE ' +
'SERIE_ECF=' + QuotedStr(CdsECFImpressora.FieldByName('SERIE').AsString) +
' AND (DATA_MOVIMENTO BETWEEN ' +
QuotedStr(FormatDateTime('yyyy-mm-dd',StrToDate(DataInicial)))+ ' AND ' +
QuotedStr(FormatDateTime('yyyy-mm-dd',StrToDate(DataFinal)))+ ')';

CDSR02.SQLConnection := FDataModule.ConexaoPAF;
CDSR02.SQL.Text := ConsultaSQL;
CDSR02.Open;
CDSR02.First;
end;
GOSTEI 0
Jucélio Silva

Jucélio Silva

01/02/2019

Hum, então ai você teria um problema, se está criando o componente em run time, e está usando uma procedure, o objeto só existiria dentro dela, então ao fim desse processo seus dados sumiriam junto com seu objeto, sem falar que você teria deixado lixo na memoria se não limpasse esse objeto.

A sugestão e´, se não quer ter o objeto criado no projeto, teria que passar que no retorno de uma function, mas teria que ter outro para receber kkkk, então não ajudaria muito, outra opção seria criar o objeto como global, caso seja parte do mesmo form, se está usando uma unit de funções ai tem que ter o retorno mesmo e tratar.

Começa usando um objeto real se possível, deixa rodando e depois cria dinamicamente , assim você vai progredindo aos poucos.

O que faço é criar um dataModule e coloco os componente lá, uma dia é não fixar o tipo de dados no componente , isso só vai te dar dor de cabeça, opte por usar fields[INDEX] ou fieldByName('NOME_CAMPO') , isso te garante o controle sobre o processo.

GOSTEI 1
Wellisson Ribeiro

Wellisson Ribeiro

01/02/2019

Esse do datamodule, se nao me engano tem no projeto com alguns componentes lá, é que peguei este projeto em andamento e preciso fazer algumas modificacoes kkk, no caso se eu colocar la digamos o cds eu consigo usar ele na unit ?
GOSTEI 0
POSTAR