while not ( executa milhões de vezes) até travar

29/12/2005

0

Ola pessoal, eu estava tentando fazer um loop como eu ja havia visto por aqui, mas encontrei um problema. Ele não para ... simplesmente executa tantas vezes que o sistema trava, tipo assim 250 vezes. O que será que fiz de errado, só mais um detalhe ele chegou a funcionar algumas vezes depois começou com isso. o código é esse ai.

procedure TForm_movimentos_cx.SpeedButton2Click(Sender: TObject);
var id_produto:integer; quantidade:double;
begin
if bancos.IBT_vendasSITUACAO.Value=´Em Aberto´ then
begin
bancos.IBT_itens_venda.First;
while not bancos.IBT_itens_venda.Eof do
begin
id_produto:=bancos.IBT_itens_vendaID_PRODUTOS.Value;
bancos.IBT_produtos.Locate(´COD_PRODUTO´, id_produto, []);
quantidade:=bancos.IBT_itens_vendaQUANTIDADE.Value;
bancos.IBT_produtos.Edit;
bancos.IBT_produtosSALDO.Value:=bancos.IBT_produtosSALDO.Value - quantidade;
bancos.IBT_produtos.Post;
bancos.IBT_produtos.ApplyUpdates;
bancos.IBT_produtos.Refresh;
bancos.IBT_produtos.Transaction.CommitRetaining;
gera_cod_movimento;
bancos.IBT_movimento_item.Insert;
bancos.IBT_movimento_itemCODIGO.Value:=cod_mov_novo;
bancos.IBT_movimento_itemDOCUMENTO.Value:=´Vendas´;
bancos.IBT_movimento_itemID_ITEM.Value:=bancos.IBT_produtosCOD_PRODUTO.Value;
bancos.IBT_movimento_itemTIPODEMOVIMENTO.Value:=´S´;
bancos.IBT_movimento_itemDATA_MOVIMENTO.Value:=date;
bancos.IBT_movimento_itemQUANTIDADE.Value:=quantidade;
bancos.IBT_movimento_itemVALOR.Value:=bancos.IBT_itens_vendaVALOR_UNIT.Value;
bancos.IBT_movimento_itemDOC_NUMERO.Value:=bancos.IBT_itens_vendaID_VENDAS.AsString;
bancos.IBT_movimento_item.Post;
gera_cod_mov_cx;
bancos.IBT_mov_cx_ent.Insert;
bancos.IBT_mov_cx_entCODIGO.Value:=cod_cx_novo;
bancos.IBT_mov_cx_entID_CAIXA.Value:=bancos.IBT_caixaCODIGO.Value;
bancos.IBT_mov_cx_entDATA_MOVIMENTO.Value:=date;
bancos.IBT_mov_cx_entFORMA_PAGAMENTO.Value:=bancos.IBT_vendasFOR_PAGAMENTO.Value;
bancos.IBT_mov_cx_entHISTORICO.Value:=´Venda´+´ - ´+ bancos.IBT_vendasOPERACAO.Value;
bancos.IBT_mov_cx_entNUM_DOC.Value:=bancos.IBT_vendasCODIGO.AsString;
bancos.IBT_mov_cx_entVALOR_REAL.Value:=bancos.IBT_vendasSUBTOTAL.Value;
bancos.IBT_mov_cx_entDESCONTO.Value:=bancos.IBT_vendasVALOR_DESCONTO.Value;
bancos.IBT_mov_cx_entVALOR_GERAL.Value:=bancos.IBT_vendasVALOR_TOTAL.Value;
bancos.IBT_mov_cx_ent.Post;
bancos.IBT_mov_cx_ent.ApplyUpdates;
bancos.IBT_mov_cx_ent.Refresh;
bancos.IBT_mov_cx_ent.Transaction.CommitRetaining;
calcula;
bancos.IBT_vendas.Edit;
bancos.IBT_vendasSITUACAO.Value:=´Baixado´;
bancos.IBT_vendas.Post;
bancos.IBT_vendas.ApplyUpdates;
bancos.IBT_vendas.Refresh;
bancos.IBT_vendas.Transaction.CommitRetaining;
bancos.IBT_itens_venda.Next;
end;
end else
begin
showmessage(´O Boleto ja está fechado´);
end;
end;

Gostaria de uma ajudinha ( de novo) rsrs.


Chip_set

Chip_set

Responder

Posts

29/12/2005

Emerson Nascimento

procedure TForm_movimentos_cx.SpeedButton2Click(Sender: TObject);
var
  id_produto:integer; quantidade:double;
begin
  if bancos.IBT_vendasSITUACAO.Value=´Em Aberto´ then
  begin
    bancos.IBT_itens_venda.First;
    while not bancos.IBT_itens_venda.Eof do
    begin
      id_produto:=bancos.IBT_itens_vendaID_PRODUTOS.Value;
      bancos.IBT_produtos.Locate(´COD_PRODUTO´, id_produto, []);
      quantidade:=bancos.IBT_itens_vendaQUANTIDADE.Value;
      bancos.IBT_produtos.Edit;
      bancos.IBT_produtosSALDO.Value:=bancos.IBT_produtosSALDO.Value - quantidade;
      bancos.IBT_produtos.Post;
      bancos.IBT_produtos.ApplyUpdates;
      bancos.IBT_produtos.Refresh;
      bancos.IBT_produtos.Transaction.CommitRetaining;
      gera_cod_movimento;
      bancos.IBT_movimento_item.Insert;
      bancos.IBT_movimento_itemCODIGO.Value:=cod_mov_novo;
      bancos.IBT_movimento_itemDOCUMENTO.Value:=´Vendas´;
      bancos.IBT_movimento_itemID_ITEM.Value:=bancos.IBT_produtosCOD_PRODUTO.Value;
      bancos.IBT_movimento_itemTIPODEMOVIMENTO.Value:=´S´;
      bancos.IBT_movimento_itemDATA_MOVIMENTO.Value:=date;
      bancos.IBT_movimento_itemQUANTIDADE.Value:=quantidade;
      bancos.IBT_movimento_itemVALOR.Value:=bancos.IBT_itens_vendaVALOR_UNIT.Value;
      bancos.IBT_movimento_itemDOC_NUMERO.Value:=bancos.IBT_itens_vendaID_VENDAS.AsString;
      bancos.IBT_movimento_item.Post;
      gera_cod_mov_cx;
      bancos.IBT_mov_cx_ent.Insert;
      bancos.IBT_mov_cx_entCODIGO.Value:=cod_cx_novo;
      bancos.IBT_mov_cx_entID_CAIXA.Value:=bancos.IBT_caixaCODIGO.Value;
      bancos.IBT_mov_cx_entDATA_MOVIMENTO.Value:=date;
      bancos.IBT_mov_cx_entFORMA_PAGAMENTO.Value:=bancos.IBT_vendasFOR_PAGAMENTO.Value;
      bancos.IBT_mov_cx_entHISTORICO.Value:=´Venda´+´ - ´+ bancos.IBT_vendasOPERACAO.Value;
      bancos.IBT_mov_cx_entNUM_DOC.Value:=bancos.IBT_vendasCODIGO.AsString;
      bancos.IBT_mov_cx_entVALOR_REAL.Value:=bancos.IBT_vendasSUBTOTAL.Value;
      bancos.IBT_mov_cx_entDESCONTO.Value:=bancos.IBT_vendasVALOR_DESCONTO.Value;
      bancos.IBT_mov_cx_entVALOR_GERAL.Value:=bancos.IBT_vendasVALOR_TOTAL.Value;
      bancos.IBT_mov_cx_ent.Post;
      bancos.IBT_mov_cx_ent.ApplyUpdates;
      bancos.IBT_mov_cx_ent.Refresh;
      bancos.IBT_mov_cx_ent.Transaction.CommitRetaining;
      calcula;
      bancos.IBT_vendas.Edit;
      bancos.IBT_vendasSITUACAO.Value:=´Baixado´;
      bancos.IBT_vendas.Post;
      bancos.IBT_vendas.ApplyUpdates;
      bancos.IBT_vendas.Refresh;
      bancos.IBT_vendas.Transaction.CommitRetaining;

      bancos.IBT_itens_venda.Next;
    end;
  end
  else
    showmessage(´O Boleto ja está fechado´);
end;


aparentemente está tudo certo.
verifique se as rotinas:
[i:34cf79d6bf]gera_cod_movimento;
gera_cod_mov_cx;
calcula;[/i:34cf79d6bf]
não reposicionam o ponteiro de registros da tabela [b:34cf79d6bf]bancos.IBT_itens_venda[/b:34cf79d6bf]


Responder

29/12/2005

Chip_set

olha só eu retirei o final do código e tudo rodou, agora fiquei sem entender.

bancos.IBT_vendas.Edit;
bancos.IBT_vendasSITUACAO.Value:=´Baixado´;
bancos.IBT_vendas.Post;
bancos.IBT_vendas.ApplyUpdates;
bancos.IBT_vendas.Refresh;
bancos.IBT_vendas.Transaction.CommitRetaining;


Responder

29/12/2005

Michael

Observando seu código, notei que vc chama ApplyUpdates e ´comita´ a transação a cada iteração do loop. A não ser por uma razão bem específica, isto quebra a atomicidade do processo. Se algum erro acontecer dentro do loop, as alterações já terão sido feitas no banco e vc não poderá desfazê-las com Rollback, e isso irá deixará seu banco inconsistente. Isso vale mesmo se forem várias transações distintas.

Rotinas de baixa são um excelente exemplo da utilidade de transações: ou salva tudo, ou não salva nada.

Eu deixaria o ApplyUpdates fora do loop, junto com o Commit, e não CommitRetaining. Seu uso não é aconselhado pq deixa a transação aberta mais tempo do que deveria, e isso pode gerar deadlocks dos registros sendo processados.

Outra coisa: [b:c36731db65]Refresh [/b:c36731db65]refaz a consulta, e posiciona o cursor no início do DataSet. Como parece que [b:c36731db65]Itens_vendas[/b:c36731db65] é uma tabela detalhe de [b:c36731db65]Vendas[/b:c36731db65], pode ser isso a causa do loop infinito. Cada vez que vc atualiza Vendas, o cursor volta para o começo do DataSet e vc processa os mesmos registros de novo.

[]´s


Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

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

Aceitar