Fechar formulário após lançar todas parcelas
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
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
Curtidas 0
Melhor post
Raimundo Pereira
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.).
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.).
GOSTEI 1
Mais Respostas
Arthur Heinrich
25/07/2025
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.
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.
GOSTEI 0
Renan
25/07/2025
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.
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.
GOSTEI 0
Renan
25/07/2025
Olá, Raimundo.
Foi exatamente assim que eu fiz.
Obrigado pela explicação.
Foi exatamente assim que eu fiz.
Obrigado pela explicação.
GOSTEI 0