Problema para popular Clientdataset em tempo de execução para executar uma consulta SQL ?
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;
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
Curtidas 0
Melhor post
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 :
Tenta debugar , quase certo que a zica etá no SDSEstoque ....
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
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;
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
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.
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
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