Transferência de dados através de arquivos .txt - Parte VII


Projeto para receber os dados (cont.)


Código para receber o arquivo de transferência

Vamos colocar o código necessário para receber e gravar os dados que estão no arquivo de transferência.  No evento OnShow do formulário coloque a Listagem 6, depois dê um clique duplo no BtnRec insira a Listagem 7 no evento OnClick.

 

procedure TFRec.FormShow(Sender: TObject);

begin

  PnlStatus.Caption := 'Status : Sem Processo';

end;

Listagem 6 – Evento OnShow do formulário

 

procedure TFRec.BtnRecClick(Sender: TObject);

var

  // Variável do tipo arquivo

  ArqTransf: TextFile;

  LinStr, DtGera, HsGera, Versao: string;

  Reg1, Reg2, Lin: Integer;

begin

  // Informando a variável ArqTransf o

  // nome do arquivo que será lido

  AssignFile(ArqTransf, 'Transf.txt');

 

  ////////////////////////////////////////////////////

  //                                                //

  // Verificando os dados do arquivo para confirmar //

  // se ele é o arquivo desejado                    //

  //                                                //

  ////////////////////////////////////////////////////

 

  PnlStatus.Caption := 'Status : Capturando dados do arquivo';

  Application.ProcessMessages;

  // Pequeno delay para dá tempo ler a mensagem do PnlStatus,

  // devido o arquivo ser muito pequeno, pode ser removido

  // sem nenhum efeito sobre o resultado final

  Sleep(1000);

 

  // Abre o arquivo para ler as informações

  // contidades no mesmo a partir da primeira linha

  Reset(ArqTransf);

 

  // Enquanto não for o fim do arquivo - Eof (End of file)

  while not(Eof(ArqTransf)) do

    begin

      // Lê a linha atual e coloca seu conteudo na variável LinStr

      ReadLn(ArqTransf, LinStr);

 

      // Capturando os dados do Registro Tipo 0

      if (Copy(LinStr, 1, 1) = '0') then

        begin

          // Formatando a data da geração do arquivo para DD/MM/AAAA

          DtGera := Copy(LinStr, 8, 2) + DateSeparator +

            Copy(LinStr, 6, 2) + DateSeparator + Copy(LinStr, 2, 4);

          // Formatando a hora da geração do arquivo para HH:MM:SS

          HsGera := Copy(LinStr, 10, 2) + TimeSeparator +

            Copy(LinStr, 12, 2) + TimeSeparator + Copy(LinStr, 14, 2);

          // Versão do layout

          Versao := Copy(LinStr, 16, 5);

        end

 

      // Capturando os dados do Registro Tipo 9

      else if (Copy(LinStr, 1, 1) = '9') then

        begin

          // Quantidade de Registro Tipo 1

          Reg1 := StrToInt(Copy(LinStr, 2, 5));

          // Quantidade de Registro Tipo 2

          Reg2 := StrToInt(Copy(LinStr, 7, 5));

          // Quantidade total de linhas

          Lin := StrToInt(Copy(LinStr, 191, 5));

        end;

    end;

 

  PnlStatus.Caption := 'Status : Aguardando resposta do usuário';

 

  // Mostra os dados do arquivo e solicita

  // ao usuário a confirmação para continuar

  if (MessageDlg('Dados do arquivo a ser importado' +#13#13+

   'Dt. Gerado : ' + DtGera +#13+

   'Hora : ' + HsGera +#13+

   'Layout : ' + Versao +#13#13+

   'Qt. Registro Tipo 1 : ' + IntToStr(Reg1) +#13+

   'Qt. Registro Tipo 2 : ' + IntToStr(Reg2) +#13+

   'Qt. Total de Linhas : ' + IntToStr(Lin) +#13#13+

   'Continuar importação dos dados?',

   mtConfirmation, [mbYes, mbNo], 0) <> mrYes) then

    begin

      // Caso o usuário tenha desejado NÃO continuar

      PnlStatus.Caption := 'Status : Importação de dados cancelada';

      ShowMessage('Rotina cancelada');

      // Chama o evento OnShow do formuário

      FormShow(nil);

      // Sai do evento atual - OnClick do botão

      Exit;

    end;

 

  /////////////////////////////////////

  //                                 //

  // Importando os dados do arquivo  //

  //                                 //

  /////////////////////////////////////

 

  PnlStatus.Caption := 'Status : Iniciando importação dos dados';

  Application.ProcessMessages;

  Sleep(1000);

 

  // Abre o arquivo para ler as informações

  // contidades no mesmo a partir da primeira linha

  Reset(ArqTransf);

 

  // Enquanto não for o fim do arquivo - Eof (End of file)

  while not(Eof(ArqTransf)) do

    begin

      // Lê a linha atual e coloca seu conteudo na variável LinStr

      ReadLn(ArqTransf, LinStr);

 

      // Mostrando o processo de tranfêrencia

      PnlStatus.Caption := 'Status : Registro Tipo ' +

        Copy(LinStr, 1, 1) + ' ---> Linha ' + Copy(LinStr, 191, 5);

      Application.ProcessMessages;

      // Pequeno delay para dá tempo ler a mensagem do PnlStatus,

      // devido o arquivo ser muito pequeno, pode ser removido

      // sem nenhum efeito sobre o resultado final

      Sleep(250);

 

      // Capturando os dados do Registro Tipo 1

      // Dados do cliente

      if (Copy(LinStr, 1, 1) = '1') then

        begin

          // Caso não localize um registro com CPF igual ao valor

          // informado na linha atual criar um novo registro

          if not(CDSCliente.Locate('CPF' , Copy(LinStr, 7, 14), []))

            then CDSCliente.Append

          // Se localizar colocar o mesmo em modo de edição

          else CDSCliente.Edit;

 

          // O código do arquivo gerado será despresado pois,

          // caso seja um novo registro, ele será gerado pelo

          // trigger da tabela.

 

          CDSCliente.FieldByName('CPF').AsString := Copy(LinStr, 7, 14);

          CDSCliente.FieldByName('Nome').AsString := Trim(Copy(LinStr, 21, 50));

          CDSCliente.FieldByName('Ender').AsString := Trim(Copy(LinStr, 71, 50));

          CDSCliente.FieldByName('Bairro').AsString := Trim(Copy(LinStr, 121, 30));

          CDSCliente.FieldByName('Cidade').AsString := Trim(Copy(LinStr, 151, 30));

          CDSCliente.FieldByName('UF').AsString := Copy(LinStr, 181, 2);

          // Formatando a data de nascimento do arquivo para DD/MM/AAAA

          CDSCliente.FieldByName('DtNasc').AsString := Copy(LinStr, 189, 2) +

            DateSeparator + Copy(LinStr, 187, 2) +

            DateSeparator + Copy(LinStr, 183, 4);

 

          // Confirmando o registro

          CDSCliente.Post;

        end

 

      // Capturando os dados do Registro Tipo 2

      // Dados do produto

      else if (Copy(LinStr, 1, 1) = '2') then

        begin

          // Caso não localize um registro com codigo igual ao valor

          // informado na linha atual abrir um novo registro

          if not(CDSProduto.Locate('Codigo' , Trim( Copy(LinStr, 2, 12) ), []))

            then CDSProduto.Append

          // Se localizar apenas coloque o arquivo em modo de edição

          else CDSProduto.Edit;

 

          CDSProduto.FieldByName('Codigo').AsString := Trim(Copy(LinStr, 2, 12));

          CDSProduto.FieldByName('Descr').AsString := Trim(Copy(LinStr, 15, 50));

          // Formatando o valor para 9999999999999,99

          CDSProduto.FieldByName('Valor').AsString :=

            Copy(LinStr, 65, 13) + DecimalSeparator + Copy(LinStr, 78, 2);

 

          // Confirmando o registro

          CDSProduto.Post;

        end;

    end;

 

  // Atualiza o banco de dados com os registros

  // que estão armazenado em cache

  CDSCliente.ApplyUpdates(0);

  CDSProduto.ApplyUpdates(0);

 

  // Atualizando a informção que está em cache, nesse

  // caso em particular, se for um novo registro, o

  // Refresh trás o código gerado pelo SGBD

  CDSCliente.Refresh;

 

  // Fechando o arquivo de transferência

  CloseFile(ArqTransf);

 

  PnlStatus.Caption := 'Status : Importação concluída';

  ShowMessage('Rotina concluída');

 

  // Chama o evento OnShow do formuário

  FormShow(nil);

end;

Listagem 7 – Evento OnClick do BtnRec


Observações Finais

Embora tenhamos colocado um comando select sem um filtro, isso não é aconselhável ser feito, pelo contrário, isso deve ser evitado ao máximo, pois imagine uma empresa com um cadastro de cliente com milhares de registros (Ex. Empresas telefônicas), para consultar um cliente você não precisaria chama todos os registro. 

No nosso caso o select foi colocado sem a cláusula where apenas por questões didática, ou seja, para melhor visualização do que estava sendo feito, mas nunca se esqueça, um select sem um where é um pecado grave, uma blasfêmia.

No projeto que recebe o arquivo de transferência, não colocamos críticas sobre os dados obtidos, mas é altamente aconselhável que se passe por todo o arquivo, verificando campo a campo para saber se existe alguma inconsistência.  Caso as mesmas existam, deveram ser mostradas ao usuário para que ele possa tomar alguma decisão sobre o assunto.  Se não houver nenhuma inconsistência, ai sim, o sistema poderá gravar os dados do arquivo.


Conclusão

 

A transferência de dados entre empresas pode até ser trabalhosa, mas não é difícil, devemos apenas ter cuidado em elaborar um bom layout.  A elaboração do layout deve consumir o maior tempo em um projeto desse tipo.

Por outro lado, mesmo com um layout excelente, se a rotina que gera ou recebe o arquivo não for bem feita de nada adiantará o tempo gasto no mesmo.

Nossos dois projetos ficaram bem simples e fáceis de serem adaptados para outros sistemas e layouts, resta apenas que você inicie as alterações, sendo assim, mãos a obra.

Artigo criado por http://www.cassic.com.br/