Fórum Erro, não passa mais de uma vez no loop da tabela? #376529

28/04/2010

0

O que estou fazendo errado neste código que depois do select esta passando apenas uma vez no loop sendo que tenho mais de um resultado no select?

Ja debuguei e vi que passa uma vez e depois na segunda vez depois no next, quando entra na linha do Eof ele pula para o final, não trazendo o restante das informações para serem gravados em outra tabela.

Eu vi que tem mais de uma informação no select pq coloquei este mesmo comando do senect em um button com um dbgrid mostrando o resultado.

procedure Tfrm_GerarContasReceberPorLote.BitBtn2Click(Sender: TObject);
var
  _Compara_DataCodigo : TCompara_Campos;
  _Idempresas, _IdCliente, _NomeCliente, _Numero_Fatura : string;
  _Valor_Total_Servicos, _Valor_Total_Parcelas : Real;
begin

  //Compara se ha excessão do codigo e data antes de fazer o update
  _Compara_DataCodigo := TCompara_Campos.Create; // instanciando a classe em memoria
  if _Compara_DataCodigo.comparar_datas_codigos(StrToInt(JvSpinEdit1.Text), StrToInt(JvSpinEdit2.Text), JvDateEdit1.Date, JvDateEdit2.Date) then
  begin
     Pt_MessageDlg('Atenção! Houve excessão nos valores passados para o filtro. Processo não executado.', mtInformation, [mbOK],0);
     JvSpinEdit1.SetFocus;
     Exit;
  end else
  begin
    _Compara_DataCodigo.Free; // liberando da memoria
    if Pt_MessageDlg('Atenção! Este processo irá gerar Duplicata de todos os movimentos envolvidos neste'+#10+#13+
                     'período informado, após este procedimento não haverá como reverter os lançamentos'+#10+#13+
                     'Deseja prosseguir com este processo?', mtInformation, [mbYes,mbNo],0) = mrYes then
    begin
      try
        Application.ProcessMessages; // Para não ficar com jeito de congelado
        {:gera o contas a receber}
        with qrylocal do
        begin
          close;
          sql.Clear;
          sql.add (' select ordemserv.idempresas,                                    ');
          sql.add ('        ordemserv.idclientes,                                    ');
          sql.add ('        ordemserv.nomeclie,                                      ');
          sql.add (' coalesce(sum(servicos.vrltotal),0) as Valor_Total_Servicos,     ');
          sql.add (' coalesce(sum(servicos.vrltotal),0) as Valor_Total_Parcela,      ');
          sql.add (' count(ordemserv.nomeclie) as quant_serv                         ');
          sql.add (' from ordemserv                                                  ');
          sql.add ('      inner join servicos                                        ');
          sql.add ('      on ordemserv.idordem = servicos.idordem                    ');
          sql.add (' where                                                           ');
          sql.add ('      servicos.idordem = ordemserv.idordem                       ');
          sql.add ('      and servicos.tipo = ''CONCLUÍDO''                          ');
          sql.add ('      and ordemserv.idclientes between :idclieini and :idcliefin ');
          sql.add ('      and ordemserv.emissao between :dataini and :datafin        ');
          sql.add ('      and ordemserv.nomecondutor is not null                     ');
          sql.add ('      and ordemserv.condpgto = :busca                            ');
          sql.add (' group by                                                        ');
          sql.add ('      ordemserv.idempresas,                                      ');
          sql.add ('      ordemserv.idclientes,                                      ');
          sql.add ('      ordemserv.nomeclie                                         ');
          ParamByName('idclieini').asinteger := StrToInt( JvSpinEdit1.Text );
          ParamByName('idcliefin').asinteger := StrToInt( JvSpinEdit2.Text );
          ParamByName('dataini').asdate      := JvDateEdit1.Date;
          ParamByName('datafin').asdate      := JvDateEdit2.Date;
          ParamByName('busca').AsString      := DBLookupComboBox1.Text;
          open;
          if not IsEmpty then
          begin
            DisableControls;
            First;
            while not Eof do
            begin
              _Idempresas           := qrylocal.FieldByName('idempresas').AsString;
              _IdCliente            := qrylocal.FieldByName('idclientes').AsString;
              _NomeCliente          := qrylocal.FieldByName('nomeclie').AsString;
              _Valor_Total_Servicos := qrylocal.FieldByName('Valor_Total_Servicos').AsCurrency;
              _Valor_Total_Parcelas := qrylocal.FieldByName('Valor_Total_Parcela').AsCurrency;
              if dm.contasreceber.Active = False then
                 dm.contasreceber.Active := True;
              dm.contasreceber.Append;
              dm.contasreceber.FieldByName('idordem').AsString            := _maxOrdemServ;
              _Numero_Fatura := TimeToStr(Time);
              dm.contasreceber.FieldByName('numero_documento').AsString   := _maxOrdemServ+_Remove_Char_Especial(_Numero_Fatura);
              dm.contasreceber.FieldByName('tipo_devedor').AsString       := 'CLIENTE';
              dm.contasreceber.FieldByName('idempresas').AsString         := _idempresas;
              dm.contasreceber.FieldByName('idcliente').AsString          := _IdCliente;
              dm.contasreceber.FieldByName('cliente').AsString            := _NomeCliente;
              dm.contasreceber.FieldByName('conta_contabil').AsString     := '111.200.001';
              dm.contasreceber.FieldByName('dtemissao').AsDateTime        := now;
              dm.contasreceber.FieldByName('dtlancamento').AsDateTime     := now;
              dm.contasreceber.FieldByName('dtvencimento').AsDateTime     := now;
              dm.contasreceber.FieldByName('valor_total').AsCurrency      := _Valor_Total_Servicos;
              dm.contasreceber.FieldByName('historico').AsString          := 'Recebimento de Serviços Prestados n/Data';
              dm.contasreceber.FieldByName('total_parcelas').AsInteger    := 1;
              dm.contasreceber.FieldByName('datauser').AsDateTime         := now;
              dm.contasreceber.FieldByName('bloqueado').AsString          := 'N';
              dm.contasreceber.FieldByName('nomecontacontabil').AsString  := 'CAIXA';
              dm.contasreceber.FieldByName('valor_da_parcela').AsCurrency := _Valor_Total_Parcelas;
              dm.contasreceber.FieldByName('numero_parcela').AsInteger    := 1;
              dm.contasreceber.FieldByName('liquidado').AsString          := 'N';
              dm.contasreceber.FieldByName('gerar_boleto').AsString       := 'N';
              dm.contasreceber.FieldByName('parcela_gerada_automatica').AsString  := 'S';
              dm.contasreceber.post;
              Next;
            end;
            EnableControls;
          end;
        end;
        {Munda a tabela para DUPLICATA não podendo mais manipular estes dados}
        with qrylocal do
        begin
          close;
          sql.Clear;
          { Muda o TIPO dos serviços de CONCLUÍDO para DUPLICATA para gerar o contas à receber }
          sql.add (' update servicos upd set upd.tipo = ''DUPLICATA''                                    ');
          sql.add (' where (exists(select ordemserv.idclientes, ordemserv.block, ordemserv.kms,          ');
          sql.add (' ordemserv.servico, ordemserv.idordem sequencial, ordemserv.nrordemserv controle,    ');
          sql.add (' ordemserv.emissao data_emisao, ordemserv.horaemissao hora_chamada,                  ');
          sql.add (' ordemserv.nomeclie cliente, ordemserv.solicitante nome_solicitante,                 ');
          sql.add (' ordemserv.condpgto condicao_pagamento, ordemserv.nomecondutor condutor,             ');
          sql.add (' ordemserv.centrocusto centro_custo, servicos.vrlservico valor_servico,              ');
          sql.add (' servicos.tipo, ordemserv.horadespacho hora_despacho, ordemserv.enddestino,          ');
          sql.add (' ordemserv.bairrodestino from ordemserv inner join servicos on                       ');
          sql.add (' ordemserv.idordem = servicos.idordem where ordemserv.idclientes                     ');
          sql.add (' between :idclieini and :idcliefin and  ordemserv.emissao between                    ');
          sql.add (' :dataini and :datafin and servicos.tipo = ''CONCLUÍDO''                             ');
          sql.add (' and ordemserv.nomecondutor is not null and ordemserv.condpgto = :busca              ');
          sql.add (' and upd.idservico = servicos.idservico))                                            ');
          ParamByName('idclieini').asinteger := StrToInt( JvSpinEdit1.Text );
          ParamByName('idcliefin').asinteger := StrToInt( JvSpinEdit2.Text );
          ParamByName('dataini').asdate      := JvDateEdit1.Date;
          ParamByName('datafin').asdate      := JvDateEdit2.Date;
          ParamByName('busca').AsString      := DBLookupComboBox1.Text;
          ExecSQL;
        end;

        dm.connection.Commit;
        _Refresh_Tabelas;

        Pt_MessageDlg('Dados processados com sucesso.', mtInformation,[mbOK],0);
      except
        on E: Exception do
        begin
          pt_messagedlg('Atenção! Não foi possível alterar os dados!'+#13+#10+
                        e.message, mtError, [mbOK], 0);
          dm.connection.Rollback;
          Abort;
        end;
      end;
    end else
    begin
      exit;
    end;

  end;

end;


Aproveitando também, gostaria de saber outra duvida

tenho uma tabela com os seguintes campos

Citação:
numero_documento------------cliente


1111-------------------------ADRIANO


2222-------------------------MARIA



e outra tabela assim
Citação:
numero_documento---------cliente------------tipo


null------------------------ADRIANO----------DUPLICATA


null------------------------ADRIANO----------DUPLICATA


null------------------------MARIA------------FATURA


nul------------------------MARIA-------------DUPLICATA


E preciso fazer com que neste segunda tabela seja preenchido o campo NUMERO_DOCUMENTO cfe seja do TIPO DUPLICATA

ficando assim Citação:
numero_documento---------cliente------------tipo


1111----------------------ADRIANO----------DUPLICATA


1111----------------------ADRIANO----------DUPLICATA


null------------------------MARIA------------FATURA


2222-----------------------MARIA-------------DUPLICATA
Adriano Dolce

Adriano Dolce

Responder

Posts

28/04/2010

Wesley Batista

Olá amigo,   Você tem certeza de que a tabela tem mais de um registro ? Tente ao inves de Next, coloca o nome da qry.next, veja se isso irá ajudar.   Com relação a segunda dúvida, você quer fazer isso via SQL ? OU via programação?

Espero te ajudado

Um abraço

Wesley Batista
e-mail : wesley@tdstecnologia.com.br
site : www.tdstecnologiarj.com.br

Responder

Gostei + 0

28/04/2010

Adriano Dolce

Olá amigo,

Sobre a primeira perguta: Sim tenho certeza absoluta que estão trazendo todas informações no select, contendo mais de um registro visto em uma grade.

Mudei colocando o nome do componente mesmo assim ele não deu certo


Segunda pergunta, o que seja mais pratico amigo

Pensei em algo assim, ou seja gravar (update) na tabela 2 cfe a condição

tipo


update table set numero_documento = parametro


where numero_documento is nul and 


tipo = duplicata and


cliente = (aqui tem que vir o parametro da tabela 1 camparando o cliente
 e alterando com o numero do documento)


Mais não estou sabendo montar amigo.

Obrigado pela ajuda.
Responder

Gostei + 0

28/04/2010

Adriano Dolce

Descobri qual era o primeiro problema Amigo.....

Seguinte, usei o mesmo dataset (componente) para montar o select e também para usar em uma função para carregar uma numeração que vai dentro do loop.

Ai ao passar na função o mesmo dataset da um close ai limpava o select, por isso não ia mais de uma vez....

Resolvido usei mais um componente dataset para a função, agora não limpa mais o select....


Agora a pendência está apenas nesta segunda duvida....

não estou sabendo montar amigo.

O que eu preciso é varrer a tabela 1 comparando coma tabela 2 para completar com os campos


Ja deixei uma procedure pronta para passar os parametros

procedure Tfrm_GerarContasReceberPorLote._MontaNumero_Doc(aNumeroFat, aNomeClie: String);
begin

  //Grava na tabela de serviços o numero da fatura gerada
  with qrylocal do
  begin
    close;
    sql.Clear;
    sql.add (' select * from contas_receber  ');
    open;

    if (not qrylocal.IsEmpty) then
    begin
      qrylocal.DisableControls;
      try
        qrylocal.First;
        while not Eof do
        begin

          with qryUpdate do
          begin
            close;
            sql.clear;
            sql.add (' update servicos set numero_fatura = :nrdoc   ');
            sql.add (' where numero_fatura is null and              ');
            sql.add (' tipo = ''DUPLICATA'' and nomeclie = :cliente ');
            ParamByName('nrdoc').AsString   := aNumeroFat;
            ParamByName('cliente').AsString := aNomeClie;
            ExecSQL;
            dm.connection.Commit;
          end;
          qrylocal.Next;
        end;
      finally
        qrylocal.EnableControls;
      end;
    end;
  end;

end;


O problema é saber de onde ou pego estes parametros

Muito obrigado pela ajuda amigo. 
Responder

Gostei + 0

29/04/2010

Adriano Dolce

Nem com uma trigger consegui....

CREATE TRIGGER MONTANUMERO_FATURA FOR CONTAS_RECEBER
ACTIVE AFTER INSERT OR UPDATE POSITION 0
as
declare variable numero_fatura varchar(60);
declare variable nomeclie varchar(60);
begin
  for select contas_receber.numero_documento, contas_receber.cliente
  from  contas_receber
      into :numero_fatura, :nomeclie
  do
  begin
    if (not exists(select numero_fatura from servicos where nomeclie = new.cliente
    and numero_fatura is null )) then

      update servicos set numero_fatura = :numero_fatura

      where numero_fatura is null and
      tipo = 'DUPLICATA' and nomeclie = :nomeclie;

  end
end


Será que estou fazendo errado?

Alguma dica ai pessoal?
Responder

Gostei + 0

29/04/2010

Adriano Dolce

Resolvido

{-----------------------------------------------------------}


        {  Transfere o numero da duplicata para fatura              }


        {-----------------------------------------------------------}





        with qrylocal do


        begin


          close;


          sql.Clear;


          sql.add (' select c.cliente, c.numero_documento from servicos 
s      ');


          sql.add (' inner join contas_receber c on s.nomeclie = 
c.cliente     ');


          sql.add (' where s.tipo = ''DUPLICATA'' and s.numero_fatura is
 null  ');


          sql.add (' order by c.cliente                                 
       ');


          open;


          if (not qrylocal.IsEmpty) then


          begin


            qrylocal.DisableControls;


            try


              qrylocal.First;


              while not Eof do


              begin





                _Numero_FaturaMax     := '';


                _Numero_FaturaMax     := 
qrylocal.fieldbyname('numero_documento').AsString;


                _NomeCliente          := '';


                _NomeCliente          := 
qrylocal.fieldbyname('cliente').AsString;





                _MontaNumero_Fatura(_Numero_FaturaMax, _NomeCliente);





                {Commita o qry em cache}


                if qryUpdate.CachedUpdates = True then // aqui verifica 
se o componente esta em cache


                begin                                  // se tiver 
aplica um aplyupdates (obrigatorio


                                                       // para 
componentes zquery


                   qryUpdate.ApplyUpdates;             // aplicado 
apenas quando o zqeury estiver em cache


                   dm.connection.Commit;





                end;


                qrylocal.Next;


              end;


            finally


              qrylocal.EnableControls;


            end;


          end;


        end;	


Código:
procedure 
Tfrm_GerarContasReceberPorLote._MontaNumero_Fatura(aNumeroFat, 
aNomeClie: String);


begin





  with qryUpdate do


  begin


    close;


    sql.clear;


    sql.add (' update servicos set numero_fatura = :nrdoc   ');


    sql.add (' where numero_fatura is null and              ');


    sql.add (' tipo = ''DUPLICATA'' and nomeclie = :cliente ');


    ParamByName('nrdoc').AsString   := aNumeroFat;


    ParamByName('cliente').AsString := aNomeClie;


    ExecSQL;


    if not IsEmpty then


      dm.connection.Commit;


  end;





end;


Responder

Gostei + 0

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

Aceitar