Fórum Fechar formulário após lançar todas parcelas #623791

25/07/2025

0

Pessoal, tenho uma rotina de gravação de parcelas, onde o processo é feito manualmente, pro meio da leitura de um código de barras.
Basicamente o usuario informa o numero de parcelas em um TEdit, lê o código, que preenche automaticamente os campos e grava, mas sem fechar o formulário até que atinja o número de parcelas.
Estou apanhando com o For, pois da forma que está, não fecha o formulário ao lançar a ultima parcela

      for i := 1 to StrToInt(EdParcelas.Text) do
      begin
         //rotinas de gravação da parcela
         tabela.append;
         tabela.post;

        //mostra ao usuario quantas parcelas faltam
        edparcelasrestantes := edparcelas - i;

        //aqui limpo os campos para que recebam os dados do novo código de barras
        edCliente.Enabled := False;
        EdNota.Enabled    := False;
        edBarras.Clear;
        edBarras.SetFocus;
        Abort;
      end;

     Form.Close;
     FrmDm.trBoletos.CommitRetaining;
  end;
Renan

Renan

Responder

Post mais votado

29/07/2025

O problema principal está no uso do Abort dentro do for, que interrompe todo o fluxo da procedure, inclusive o próprio loop. Isso faz com que apenas a primeira iteração seja executada, e o restante nunca ocorra.

Explicação do seu cenário
Você quer que:

O usuário informe a quantidade de parcelas (EdParcelas.Text);
Cada vez que um código de barras for lido, os dados sejam gravados;
Ao atingir o número de parcelas desejado, o formulário se feche.

Solução sugerida
Você não deve usar um for tradicional com Abort nesse caso, porque o processo é interativo e depende da leitura manual de cada código de barras.
Em vez disso, use uma variável de controle de parcelas já lançadas e vá tratando a lógica a cada leitura de código de barras, com controle externo.

Exemplo::
procedure TFrmParcelas.edBarrasKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then // Pressionou Enter após ler o código de barras
begin
Inc(ParcelasLancadas);

// Grava a parcela
tabela.Append;
// Preencha os campos da tabela com os dados lidos
tabela.Post;

// Atualiza o campo de parcelas restantes
EdParcelasRestantes.Text := IntToStr(StrToInt(EdParcelas.Text) - ParcelasLancadas);

if ParcelasLancadas >= StrToInt(EdParcelas.Text) then
begin
FrmDm.trBoletos.CommitRetaining;
Close;
end
else
begin
// Limpa campos e prepara para a próxima leitura
edCliente.Enabled := False;
EdNota.Enabled := False;
edBarras.Clear;
edBarras.SetFocus;
end;
end;
end;

Considerações
Abort deve ser evitado nesse tipo de lógica. Ele é útil para interromper exceções ou validações, mas não para controle de fluxo.
O for é inadequado quando o processo depende de ações do usuário entre iterações. Use variáveis de controle e eventos (como OnKeyPress, OnClick, etc.).

Raimundo Pereira

Raimundo Pereira
Responder

Gostei + 1

Mais Posts

25/07/2025

Arthur Heinrich

Esse for executa um loop de n parcelas, mas, como último comando, você introduziu o comando Abort.

Ao chegar ao final do primeiro loop, o comando Abort executa uma exceção e aborta a rotina, não executando os comandos finais (Close e Commit).

Por essa razão, seu forma não fecha.
Responder

Gostei + 0

28/07/2025

Renan

Pois é, não estou achando uma forma de manter o formulário aberto para lançar a segunda parcela.
Se troco o Abort por Exit, a rotina lança as 2 parcelas sem a interação do usuário.

Acho que terei de usar If ao inves do For neste caso.
Responder

Gostei + 0

30/07/2025

Renan

Olá, Raimundo.

Foi exatamente assim que eu fiz.
Obrigado pela explicação.
Responder

Gostei + 0

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

Aceitar