Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Problema Com "break"


Guinho.TI

Pergunta

É o seguinte,

Depois de muito custo, consegui montar uma rotina que lê um arquivo e procura nele uma String que indica que houve o fim na execução de um script.Agora estou tendo dois problemas:

1. Não consigo inserir múltiplos comandos dentro do If. Quando eu faço isso, ele só resolve o que estiver no Else. Temporariamente, criei vários If´s pra solucionar isto.

2. Quando eu incluo a linha "if completo=false then break;" o programa me devolve para os dois casos (true/false) a Mensagem "Script em andamento", mas se eu retiro novamente, o programa funciona corretamente.

Arq: TStringList;
i: Integer;
FileName:string;
linha:String;
temp:String;
completo:boolean;

begin

Arq := TStringList.Create; (*** INSTANCIA A VARIÁVEL ***)

try

FileName := 'C:\log.txt';

if FileExists(FileName) then
Arq.LoadFromFile('C:\log.txt');


for i := 0 to Arq.Count - 1 do   (*** PERCORRE AS LINHAS (ÍNDICES) ***)
begin
linha:=Arq[i];

{se esta string estiver no LOg, significa que a execução terminou}

if (AnsiContainsText(linha, '= Exit Status) = True) then
completo:= True;


{Se a o Log finalizou, recebe o número do Status. Se não finalizou, completo é false}
if completo=true
then
temp := Trim(AnsiRightStr(linha, Length(linha) - Pos(':', linha)))
else
completo:=false;


if completo=false then break;

end; //End For

if completo=true
then
Showmessage('Script Finalizado!')
else
showmessage('Script em Andamento);

finally
FreeAndNil(Arq); //  LIBERA A VARIÁVEL DA MEMÓRIA

end;//end do try/finally
end.

Link para o comentário
Compartilhar em outros sites

11 respostass a esta questão

Posts Recomendados

  • 0

{Se a o Log finalizou, recebe o número do Status. Se não finalizou, completo é false}
if completo=true
then
   begin
        temp := Trim(AnsiRightStr(linha, Length(linha) - Pos(':', linha)))
        break;
   end
else
   begin
      completo:=false;
      continue;
   end; 

end; //End For

quando voce usa o break o comando for para de executar mesmo que não tenha chegado ao fim, então a logica é fazer o for rodar ate o seu final para depois testar se a o Log finalizou. Mas se acontece dele finalizar antes do fim do for, ai neste caso voce pode interromper o for usando o break

Editado por Jhonas
Link para o comentário
Compartilhar em outros sites

  • 0

Ainda tenho uma dúvida:

Este caso funcionou direito pois eu estou fazendo a leitura de somente um arquivo.

A real intenção deste programa é ler uma série de arquivos de logs. Todos os Logs são salvos no Banco de Dados, mas alguns dados como Data de Término e Status só podem ser atualizados após o término de um Script, ou seja, quando programa insere no mesmo a String " = Exit Status" .

Esta rotina que estou tentando criar vai servir para isso: Ler todos os logs, salvar no BD, verificar os que finalizados, inserir no BD as informações dos finalizados e reler até que todos estejam finalizados. Então a lógica que eu quero é essa:

-Se tiver finalizado, salva os dados no BD e passa para o próximo Log .

-Se não tiver finalizado, passa para o próximo Log.

Será um Loop diário até que todos os arquivos estejam finalizados e inseridos no BD.

Neste caso, a rotina acima funcionará corretamente ou eu terei que fazer ainda algumas alterações?

Desde já agradecido...

Link para o comentário
Compartilhar em outros sites

  • 0

A mesma rotina funcionara para todos os seus arquivos, no entanto voce tera que fazer algumas modificações para ler todos os seus arquivos em sequencia. Voce pode optar por usar um for externo, ou um case, ou uma leitura de um arquivo texto com os nomes dos seus arquivos, ou uma leitura direta do banco de dados, já que voce vai salvar nele ... as opções de codigo depende de como os Logs são gerados, processados e guardados.

Link para o comentário
Compartilhar em outros sites

  • 0

Bom, a estrutura para a leitura sequencial do todos os Logs já estah pronta e funcionando. O único erro é nesta parte, pois o antiga rotina nem sempre está coletando o FIM dos Scripts. Eles já estão como terminados, ou seja, com a String "Exit Status", mas o BD não tem os dados "Status" e "data Término", o que faz o usuário imaginar que o Script está em andamento ainda. O que eu estou fazendo é recontruir a Procedure que foi feita por outro estagiário. Segue abaixo a que está dando erro(que foi feita por outra pessoa):

procedure ArquivoLog.Atualizar(dirArqLog: String);
var
  arquivo:TStringList; //Variável que vai carregar e manipular o arquivo
  linha:String; //Variável em que será colocada a linha lida do arquivo
  cont:integer; //Contador para informar qual o número da linha corrente;
  indice:integer; //Indice para coleta dos dados na lista
  temp:String;  //Variável onde ficarão as informações temporárias da linha lida do arquivo
  completo:Boolean;  //Variável para informar se o arquivo de log está completo (True) ou não (False),
                      //Muda para true quando encontra o rodapé padrão dos arquivos de log
  arqErro:TStringList; //Objeto para carregar os erros existentes no arquivo de erro e salvá-los junto com os novos
  erros:TStringList;  //Objeto para guardar os erros gerados pelo sistema e passá-los para o objeto arqErro
  func:Funcoes;
  nomeArq:String;

begin

  nomeArq := ExtractFileName(dirArqLog);
  arquivo := TStringList.Create;
  completo := False;

  Writeln('>> Atualizando dados do arquivo...');

  cont := 0;
  self.CaminhoLog := dirArqLog;

  try
    CopyFile(PChar(dirArqLog), Pchar('CopyLogTWS_Log_' + nomeArq), false);
    arquivo.LoadFromFile('CopyLogTWS_Log_' + nomeArq);
    DeleteFile(Pchar('CopyLogTWS_Log_' + nomeArq));

    {LENDO DADOS DO ARQUIVO DE LOG - CABECALHO}
    indice := 0;
    while (indice < arquivo.Count - 1) do
          begin
          cont := cont + 1;
          linha := arquivo[indice];

                //Nome do script
               if ((cont = 4) and (completo = False)) then
                  begin
                  temp := AnsiRightStr(linha, Length(linha) - Pos(':', linha) - 1);

                       if (AnsiContainsText(temp, ' ')=True) then
                          temp := AnsiLeftStr(temp, Pos(' ', temp) - 1);
                          temp := AnsiRightStr(temp, Length(temp) - LastDelimiter('\', temp));

                       if (AnsiContainsText(temp, '.')=True) then
                          temp := AnsiLeftStr(temp, pos('.', temp) - 1);
                          self.NomeScript := temp;
                    end

                  //Número do job
                 else if ((cont = 5) and (completo = False)) then
                 begin
                 temp := AnsiRightStr(linha, Length(linha) - LastDelimiter(':', linha));
                 self.Job := StrToInt(Trim(temp));
                 Break;  {DEPOIS DE LER O NUMERO DO JOB, NÃO É NECESSÁRIO LER OS OUTROS DADOS
                    DO CABEÇALHO PORQUE O NOME DO SCRIPT E O NUM DO JOB FORMAM A CHAVE PRIMÁRIA DA TABELA}
                 end;

    indice := indice + 1;

    end;  //TÉRMINO DO WHILE DE LEITURA DOS DADOS DO CABEÇALHO

      {LENDO OS DADOS DO ARQUIVO DE LOG - RODAPÉ}
    indice := arquivo.Count;


      while (indice > arquivo.Count - 10) do
            begin
            indice := indice - 1;
            linha := arquivo[indice];

          //Se a string for encontrada, significa que o arquivo está completo

          if (AnsiContainsText(linha, '= Exit Status') = True) then
             begin
              completo := True;
              func := Funcoes.Create;
              temp := Trim(AnsiRightStr(linha, Length(linha) - Pos(':', linha)));

             END;

          if (func.IsInteger(temp) = True) then
               self.Status := StrToInt(temp)
          else
               begin
               completo := False;
               break;
          end;//fim do IF

              //Data de término
              while (indice < arquivo.Count) do
                begin
                  linha := arquivo[indice];
                  temp := AnsiMidStr(linha, Pos('/', linha) - 2,  LastDelimiter(':', linha) - Pos('/', linha) + 8);
                  if (func.IsDate(temp) = True) then
                      begin
                        self.Termino := StrToDateTime(temp);
                        completo := True;
                        Break;
                    end
                  else
                        completo := False;

                        indice := indice + 1;
                  end;

              Break;

            end;

        end;  //TÉRMINO DO WHILE DE LEITURA DO ARQUIVO - RODAPÉ



    {VERIFICANDO SE O TERMINO DO ARQUIVO FOI ENCONTRADO, CASO NEGATIVO O PROCESSO DE ATUALIZAÇÃO É ABORTADO}
    if (completo = True) then
      begin
        //Lendo todo o conteúdo do arquivo de log
        self.LogScript := arquivo.Text;
      end
    else
      begin
        Writeln('-- MSG: A atualizacao dos dados do arquivo de log não foi realizada');
        Writeln('-- MSG: O log ainda esta em andamento');
        exit; //Saindo da função sem atualizar o arquivo
      end;

  except  //TRATAMENTO DA EXCEÇÃO - O log ainda está em andamento, os dados não podem ser atualizados
    on e:EFileStreamError do
      begin
        Writeln('-- MSG: A atualizacao dos dados do arquivo de log não foi realizada');
        Writeln('-- MSG: O log ainda esta em andamento');
        Exit;
      end;
    on e:Exception do
      begin
        temp := DateTimeToStr(Now, formatoData);
        Writeln('## ' + temp);
        Writeln('-- ERRO: Ocorreu um erro durante a atualizacao dos dado do arquivo');
        Writeln('-- MSG:  ' + e.Message);

        if (self.config.DiretorioArqErro <> '') then
          begin
            arqErro := TStringList.Create;
            erros := TStringList.Create;
            erros.Append('');
            erros.Append('## ' + temp);
            erros.Append('-- ERRO: Ocorreu um erro quando o sistema tentava atualizar o arquivo de log ' + dirArqLog);
            erros.Append('-- MSG:  ' + e.Message);
            if (FileExists(self.config.DiretorioArqErro) = True) then
              arqErro.LoadFromFile(self.config.DiretorioArqErro);
            arqErro.AddStrings(erros);
            arqErro.SaveToFile(self.config.DiretorioArqErro);
            erros.Destroy;
            arqErro.Destroy;
          end;
        self.numErros := self.numErros + 1;
        Exit;
      end;
  end;

  {A PARTIR DESSE PONTO TODOS OS DADOS PARA ATUALIZAÇÃO FORAM COLETADOR DO ARQUIVO,
  O CÓDIGO ABAIXO FARÁ A ATUALIZAÇÃO NO BANCO DE DADOS}

  try
    with self.modConn.queryUpdateArqLog.Parameters do
      begin
        ParamByName('NomeScr').Value := self.NomeScript;
        ParamByName('Job').Value := self.Job;
        ParamByName('Termino').Value := self.Termino;
        ParamByName('Status').Value := self.Status;
        ParamByName('LogScript').Value := arquivo.Text;
      end;

    //Atualizando os dados do arq de log no Banco de Dados
    self.modConn.queryUpdateArqLog.ExecSQL;

    //Mostrando os dados do Arquivo de Log atualizado
    Writeln('>> OS DADOS DO ARQUIVO DE LOG FORAM ATUALIZADOS COM SUCESSO');
    Writeln('>> NOME SCRIPT:  ' + self.NomeScript);
    Writeln('>> No DO JOB:    ' + IntToStr(self.Job));
    Writeln('>> TERMINO:      ' + DateTimeToStr(self.Termino, self.formatoData));
    Write('>> STATUS:       ' + IntToStr(self.Status));
    if (self.Status = 0) then
      Writeln(' (OK)')
    else
      Writeln(' (ERRO)');
  except
    on e:Exception do
      begin
        Writeln('## ' + DateTimeToStr(Now, formatoData));
        Writeln('-- ERRO: Ocorreu um erro durante a atualizacao dos dados do arquivo no BD');
        Writeln('-- MSG:  ' + e.Message);
      end;
  end;
end;

Acredito então estar indo no caminho certo. Aceito sugestões!

Abc

Editado por Guinho.TI
Link para o comentário
Compartilhar em outros sites

  • 0

Tenta esta mudança no codigo:

if (func.IsInteger(temp) = True) then
               begin
                  self.Status := StrToInt(temp);
                  break;
               end
          else
               completo := False;


              //Data de término
              while (indice < arquivo.Count) do
                begin
                  linha := arquivo[indice];
                  temp := AnsiMidStr(linha, Pos('/', linha) - 2,  LastDelimiter(':', linha) - Pos('/', linha) + 8);
                  if (func.IsDate(temp) = True) then
                      begin
                        self.Termino := StrToDateTime(temp);
                        completo := True;
                        Break;
                    end
                  else
                        completo := False;

                        indice := indice + 1;
                  end;

            end;

        end;  //TÉRMINO DO WHILE DE LEITURA DO ARQUIVO - RODAPÉ

Link para o comentário
Compartilhar em outros sites

  • 0

De acordo com o que aprendi até agora, modifiquei algumas linhas do código. Enquanto eu tento fazer alguns testes por aqui, gostaria que vocês analisassem desde já, se pelo menos a estrutura está certa, mesmo que ainda não funcione do jetio que eu preciso. Se possível, gostaria que alguém pudesse me explicar também a diferença do BREAK e do CONTINUE.

while (indice > arquivo.Count - 10) do
        begin
            indice := indice - 1;
            linha := arquivo[indice];

               //Se a string for encontrada, significa que o arquivo está completo

          if (AnsiContainsText(linha, '= Exit Status') = True) then
             completo:= True;

             if completo=true
                then
                    begin
                         func := Funcoes.Create;
                         temp := Trim(AnsiRightStr(linha, Length(linha) - Pos(':', linha)));
                         temp := StrtoInt(temp);
                         break;
                    end
                else
                         begin
                         completo:=false;
                         continue;
                         end;

                if (func.IsInteger(temp) = True)
                   then
                       begin
                            self.Status := StrToInt(temp);
                            break;
                       end
                   else
                            completo := False;



                        //Data de término
              while (indice < arquivo.Count) do
                begin
                  linha := arquivo[indice];
                  temp := AnsiMidStr(linha, Pos('/', linha) - 2,  LastDelimiter(':', linha) - Pos('/', linha) + 8);
                  if (func.IsDate(temp) = True) then
                      begin
                        self.Termino := StrToDateTime(temp);
                        completo := True;
                        Break;
                    end
                  else
                        completo := False;

                        indice := indice + 1;
                  end;

            end;

        end;  //TÉRMINO DO WHILE DE LEITURA DO ARQUIVO - RODAPÉ

Link para o comentário
Compartilhar em outros sites

  • 0

O break causa a quebra do fluxo de controle para sair de um for, while, ou uma senteça repeat

O Continue permite o fluxo de controle proceder a próxima interação para o comando for, while ou uma senteça repeat

Em ultima analise eu desvincularia um while do outro ( mas somente testando para saber o que seria melhor )

Link para o comentário
Compartilhar em outros sites

  • 0

Vamos ver se eu entendi ou piorei a situação. No meu caso, quando o a String "Exit Status" é encontrada, significa que o LOG finalizou. Se o log finalizou, devem ser coletados os outros dados, Status e data Término, ou seja, vai até o final. Se não finalizou, pula para leitura do outro log.

Sendo assim, este trecho está correto?

if completo=true
                then
                    begin
                         func := Funcoes.Create;
                         temp := Trim(AnsiRightStr(linha, Length(linha) - Pos(':', linha)));
                         temp := StrtoInt(temp);
                         break;
                    end
                else
                         begin
                         completo:=false;
                         continue;
                         end;

Quanto ao While eu vou tentar desvinculá-los e digo como ficou.

Abc

Link para o comentário
Compartilhar em outros sites

  • 0
quando o a String "Exit Status" é encontrada, significa que o LOG finalizou. Se o log finalizou, devem ser coletados os outros dados, Status e data Término, ou seja, vai até o final.

O codigo esta correto, mas acho que voce poderia tentar algo assim:

while (indice > arquivo.Count - 10) do
        begin
            indice := indice - 1;
            linha := arquivo[indice];

               //Se a string for encontrada, significa que o arquivo está completo

          if (AnsiContainsText(linha, '= Exit Status') = True) then
             begin
                func := Funcoes.Create;
                temp := Trim(AnsiRightStr(linha, Length(linha) - Pos(':', linha)));
                temp := StrtoInt(temp);
                if (func.IsInteger(temp) = True) then
                   begin
                       self.Status := StrToInt(temp);
                       break;
                   end
                else
                   completo:=false;

            end;

        end;  //TÉRMINO DO WHILE DE LEITURA DO ARQUIVO - RODAPÉ

                  //Data de término
        while (indice < arquivo.Count) do
          begin
            linha := arquivo[indice];
            temp := AnsiMidStr(linha, Pos('/', linha) - 2,  LastDelimiter(':', linha) - Pos('/', linha) + 8);
            if (func.IsDate(temp) = True) then
               begin
                  self.Termino := StrToDateTime(temp);
                  completo := True;
                  Break;
               end
            else
               completo := False;

            indice := indice + 1;
          end;

Link para o comentário
Compartilhar em outros sites

  • 0

Esperei um dia para ver como ficaria a atualização dos LOGS e deu certo! Os Logs que estavam dando erro atualizaram e os que iniciaram ontem e finalizaram hoje atualizaram normalmente após a alteração do código. Espero que não ocorra mais erros. Valeu mesmo pela atenção, Jhonas!

Abc

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...