Fazendo Arquivos EDI com C# aplicando POO Parte 1
Leonel Fraga de Oliveira 17/06/2009 00:00

Esta série de quatro artigos são republicações da série “Fazendo Arquivos EDI com C# aplicando POO” que coloquei, a algum tempo atrás, em meu site do Multiply.

Este é um artigo que propõe a construção de um lay-out de arquivo do tipo fixo-blocado, utilizando a linguagem C# e com técnicas de Programação Orientada a Objetos.

Um arquivo do tipo fixo-blocado é utilizado por várias empresas com a finalidade de trocar informações entre sistemas (daí o EDI - Electronic Data Interchange do título) através de troca de arquivos.

Sua característica principal é que os campos em cada um dos registros (linhas do arquivo) possuirem tamanho fixo (em quantidade de caracteres) e são organizados sequencialmente.

Um arquivo é composto de várias linhas, e cada linha de vários campos descritos acima; cada campo possui uma máscara, ou formatação.

Cada sistema que utiliza-se deste método possui um documento onde são descritas as características do arquivo, tais como o tamanho dos registros, tipos de registros e a formatação dos campos, o famigerado lay-out.

Geralmente, cada arquivo possui um registro Header (Cabeçalho), onde geralmente é apresentado campos que indicam a data de geração, tipo de arquivo, entre outros;
vários registros detalhe e um registro final (Trailler).

Para o artigo, vamos construir um lay-out bem simples, e um programa para apresentar os registros em tela, com os campos devidamente separados.

O lay-out proposto consiste em:

Descrição            Tipo      Tamanho   Posição Inicial  Obs.
 Nome                  X           40            1
 Data de Nascimento    D            8           41         DDMMAAAA
 Tipo de Pessoa        X            1           49         F ou J
 Documento             N(0)        20           50
 Saldo Atual           N(2)        12           70         10 posições, 2 decimais s/ separador

Primeiramente, vamos "transformar" o conceito de arquivo fixo blocado em objetos, ou seja, modelar as classes que irão compor o nosso projeto.

Bem, você poderia perguntar, "simplesmente posso construir um programa que separa substrings, aplica em cada campo e exibe na tela, não é"?

Sim, isso pode ser feito, eu também já fiz várias vezes dessa forma, sempre repetindo o mesmo código várias vezes, claro que com as devidas sutilezas em cada implementação.

Minha proposta neste artigo é a construção de um "motor", que tem a capacidade de interpretar qualquer tipo de layout, um mecanismo básico, que poderá ser implementado
em qualquer layout específico.

Retomando o raciocínio... Um arquivo do tipo fixo-blocado é uma *coleção* de registros; cada registro é uma *coleção* de campos, e estes campos possuem atributos tais como o seu tamanho de caracteres, o seu tipo (que pode ser alfanumérico, data, numérico, etc), uma máscara (por exemplo, DDMMAAAA - data sem separador), quantidade de casas decimais, no caso de numéricos e sua posição inicial dentro da linha.

Vejam o abuso da palavra *coleção*. Significa que utilizaremos bastante coleções em nosso projeto.

Vamos começar pela parte mais básica (e a mais complexa, por sinal) de um arquivo: os campos de cada registro. Cada campo possui os atributos conforme dito acima. Temos os seguintes atributos em cada campo:

- Tipo
- Descrição
- Tamanho
- Posições Inicial e Final
- Quantidade Casas Decimais

Podemos ainda ter:

- Valor Padrão
- Separadores de data, decimais, milhar, hora, etc.
- Ordem do campo no Registro.

Os tipos de campo, podem ser basicamente numéricos e alfanuméricos, sendo os outros derivados deste, com as suas respectivas máscaras de formatação, podendo formar datas separadas por barra, ponto, números decimais sem separador, entre muitos outros. Para delimitar os tipos com que a nossa classe de campo irá trabalhar, vamos representar cada tipo através de um item de uma enumeração, assim podemos saber quais tipos poderemos ter em cada campo. Veja a implementação a seguir:

 /// <summary>
 /// Representa cada tipo de dado possível em um arquivo EDI.
 /// </summary>
 public enum TTiposDadoEDI
 {
    /// <summary>
    /// Representa um campo alfanumérico, alinhado à esquerda e com brancos à direita. A propriedade ValorNatural é do tipo String
    /// </summary>
    ediAlpha,
    /// <summary>
    /// Representa um campo numérico inteiro alinhado à direita com zeros à esquerda. A propriedade ValorNatural é do tipo Int ou derivados
    /// </summary>
    ediInteiro,
    /// <summary>
    /// Representa um campo numérico com decimais, sem o separador de decimal. A propriedade ValorNatural é do tipo Double
    /// </summary>
    ediNumericoSemSeparador,
    /// <summary>
    /// Representa um campo numérico com decimais, com o caracter ponto (.) como separador decimal,
    /// alinhado à direita com zeros à esquerda. A propriedade ValorNatural é do tipo Double
    /// </summary>
    ediNumericoComPonto,
    /// <summary>
    /// Representa um campo numérico com decimais, com o caracter vírgula (,) como separador decimal,
    /// alinhado à direita com zeros à esquerda. A propriedade ValorNatural é do tipo Double
    /// </summary>
    ediNumericoComVirgula,
    /// <summary>
    /// Representa um campo de data no formato ddm/mm/aaaa. A propriedade ValorNatural é do tipo DateTime
    /// </summary>
    ediDataDDMMAAAA,
    /// <summary>
    /// Representa um campo de data no formato aaaa/mm/dd. A propriedade ValorNatural é do tipo DateTime
    /// </summary>
    ediDataAAAAMMDD,
    /// <summary>
    /// Representa um campo de data no formato dd/mm. A propriedade ValorNatural é do tipo DateTime, com o ano igual a 1900
    /// </summary>
    ediDataDDMM,
    /// <summary>
    /// Representa um campo de data no formato mm/aaaa. A propriedade ValorNatural é do tipo DateTime, com o dia igual a 01
    /// </summary>
    ediDataMMAAAA,
    /// <summary>
    /// Representa um campo de data no formato mm/dd. A propriedade ValorNatural é do tipo DateTime com o ano igual a 1900
    /// </summary>
    ediDataMMDD,
    /// <summary>
    /// Representa um campo de hora no formato HH:MM. A propriedade ValorNatural é do tipo DateTime, com a data igual a 01/01/1900
    /// </summary>
    ediHoraHHMM,
    /// <summary>
    /// Representa um campo de hora no formato HH:MM:SS. A propriedade ValorNatural é do tipo DateTime, com a data igual a 01/01/1900
    /// </summary>
    ediHoraHHMMSS,
    /// <summary>
    /// Representa um campo de data no formato DD/MM/AAAA. A propriedade ValorNatural é do tipo DateTime.
    /// </summary>
    ediDataDDMMAA,
    /// <summary>
    /// Representa um campo de data no formato DD/MM/AAAA, porém colocando zeros no lugar de espaços no ValorFormatado. A propriedade
    /// ValorNatural é do tipo DateTime, e este deve ser nulo caso queira que a data seja zero.
    /// </summary>
    ediDataDDMMAAAAWithZeros,
    /// <summary>
    /// Representa um campo de data no formato AAAA/MM/DD, porém colocando zeros no lugar de espaços no ValorFormatado. A propriedade
    /// ValorNatural é do tipo DateTime, e este deve ser nulo caso queira que a data seja zero.
    /// </summary>
    ediDataAAAAMMDDWithZeros
 }

Cada tipo suportado está comentado, dispensando maiores comentários a respeito deles.
Ah, quanto ao prefixo "T" em cada classe... coisas de quem veio do Delphi :-)

Agora, vamos implementar a classe básica de interpretação dos layouts, em partes:

 public class TCampoRegistroEDI
 {
     #region Variáveis Privadas
     private string _DescricaoCampo;
     private TTiposDadoEDI _TipoCampo;
     private int _TamanhoCampo;
     private int _QtdDecimais;
     private object _ValorNatural;
     private string _ValorFormatado;
     private int _OrdemNoRegistroEDI;
     private string _SeparadorDatas;
     private string _SeparadorHora;
     private int _PosicaoInicial;
     private int _PosicaoFinal;
     #endregion
  
     #region Propriedades
     /// <summary>
     /// Descrição do campo no registro EDI (meramente descritivo)
     /// </summary>
     public string DescricaoCampo
     {
         get { return _DescricaoCampo; }
         set { _DescricaoCampo = value; }
     }
  
     /// <summary>
     /// Tipo de dado de ORIGEM das informações do campo EDI.
     /// </summary>
     public TTiposDadoEDI TipoCampo
     {
         get { return _TipoCampo; }
         set { _TipoCampo = value; }
     }
  
     /// <summary>
     /// Tamanho em caracteres do campo no arquivo EDI (DESTINO)
     /// </summary>
     public int TamanhoCampo
     {
         get { return _TamanhoCampo; }
         set { _TamanhoCampo = value; }
     }
  
     /// <summary>
     /// Quantidade de casas decimais do campo, caso ele seja do tipo numérico sem decimais. Caso
     /// não se aplique ao tipo de dado, o valor da propriedade será ignorado nas funções de formatação.
     /// </summary>
     public int QtdDecimais
     {
         get { return _QtdDecimais; }
         set { _QtdDecimais = value; }
     }
  
     /// <summary>
     /// Valor de ORIGEM do campo, sem formatação, no tipo de dado adequado ao campo. O valor deve ser atribuido
     /// com o tipo de dado adequado ao seu proposto, por exemplo, Double para representar valor, DateTime para
     /// representar datas e/ou horas, etc.
     /// </summary>
     public object ValorNatural
     {
         get { return _ValorNatural; }
         set { _ValorNatural = value; }
     }
  
     /// <summary>
     /// Valor formatado do campo, pronto para ser utilizado no arquivo EDI. A formatação será de acordo
     /// com a especificada na propriedade TipoCampo, com numéricos alinhados à direita e zeros à esquerda
     /// e campos alfanuméricos alinhados à esquerda e com brancos à direita.
     /// Também pode receber o valor vindo do arquivo EDI, para ser decodificado e o resultado da decodificação na propriedade
     /// ValorNatural
     /// </summary>
     public string ValorFormatado
     {
         get { return _ValorFormatado; }
         set { _ValorFormatado = value; }
     }
  
     /// <summary>
     /// Número de ordem do campo no registro EDI
     /// </summary>
     public int OrdemNoRegistroEDI
     {
         get { return _OrdemNoRegistroEDI; }
         set { _OrdemNoRegistroEDI = value; }
     }
  
     /// <summary>
     /// Caractere separador dos elementos de campos com o tipo DATA. Colocar null caso esta propriedade
     /// não se aplique ao tipo de dado.
     /// </summary>
     public string SeparadorDatas
     {
         get { return _SeparadorDatas; }
         set { _SeparadorDatas = value; }
     }
  
     /// <summary>
     /// Caractere separador dos elementos de campos com o tipo HORA. Colocar null caso esta propriedade
     /// não se aplique ao tipo de dado.
     /// </summary>
     public string SeparadorHora
     {
         get { return _SeparadorHora; }
         set { _SeparadorHora = value; }
     }
  
     /// <summary>
     /// Posição do caracter inicial do campo no arquivo EDI
     /// </summary>
     public int PosicaoInicial
     {
         get { return _PosicaoInicial; }
         set { _PosicaoInicial = value; }
     }
  
     public int PosicaoFinal
     {
         get { return _PosicaoFinal; }
         set { _PosicaoFinal = value; }
     }
     #endregion

Note que temos os atributos que abstraimos no início deste artigo, e dois atributos mais "curiosos":

- ValorNatural, do tipo object: Irá receber o valor do campo no tipo de dado que ele representa, ou seja, se for número inteiro, um int, se for decimal, double,
data, DateTime e assim por diante. Através do tipo de dados iremos aplicar a formatação adequada.

- ValorFormatado, do tipo string: Irá receber o valor já formatado, no momento da interpretação de um arquivo, e fornecerá o valor formatado no momento da geração.

Temos também os construtores da classe, que irão inicializar as propriedades com valores padrão:

 #region Construtores
 /// <summary>
 /// Cria um objeto TCampoRegistroEDI
 /// </summary>
 public TCampoRegistroEDI()
 { }
  
 /// <summary>
 /// Cria um objeto do tipo TCampoRegistroEDI inicializando as propriedades básicas.
 /// </summary>
 /// <param name="pTipoCampo">Tipo de dado de origem dos dados</param>
 /// <param name="pTamanho">Tamanho em caracteres do campo (destino)</param>
 /// <param name="pDecimais">Quantidade de decimais do campo (destino)</param>
 /// <param name="pValor">Valor do campo (Origem), no tipo de dado adequado ao propósito do campo</param>
 /// <param name="pSeparadorHora">Separador de hora padrão; null para sem separador</param>
 /// <param name="pSeparadorData">Separador de data padrão; null para sem separador</param>
 /// <param name="pPosicaoInicial">Posição Inicial do Campo no Arquivo</param>
 public TCampoRegistroEDI(TTiposDadoEDI pTipoCampo, int pTamanho, int pDecimais, object pValor, string pSeparadorHora, string pSeparadorData, int pPosicaoInicial)
 {
     this._TipoCampo = pTipoCampo;
     this._TamanhoCampo = pTamanho;
     this._QtdDecimais = pDecimais;
     this._ValorNatural = pValor;
     this._SeparadorHora = pSeparadorHora;
     this._SeparadorDatas = pSeparadorData;
     this._OrdemNoRegistroEDI = 0;
     this._DescricaoCampo = "";
     this._PosicaoInicial = pPosicaoInicial - 1; //Compensa a indexação com base em zero
     this._PosicaoFinal = pPosicaoInicial + this._TamanhoCampo;
 }
 #endregion

Agora que vem a parte legal, que é onde será feita a formatação do valor informado através da propriedade ValorNatural em uma formatação condizente com o nosso lay-out:
No momento da geração do arquivo, vamos utilizar:

    /// <summary>
    /// Aplica formatação ao valor do campo em ValorNatural, colocando o resultado na propriedade ValorFormatado
    /// </summary>
    public void CodificarNaturalParaEDI()
    {
        switch (this._TipoCampo)
        {
            case TTiposDadoEDI.ediAlpha:
                {
                   this._ValorFormatado = this._ValorNatural.ToString().Trim().PadRight(this._TamanhoCampo, ' ');
                   break;
               }
           case TTiposDadoEDI.ediInteiro:
               {
                   this._ValorFormatado = this._ValorNatural.ToString().Trim().PadLeft(this._TamanhoCampo, '0');
                   break;
               }
           case TTiposDadoEDI.ediNumericoSemSeparador:
               {
                   string Formatacao = "{0:f" + this._QtdDecimais.ToString() + "}";
                   this._ValorFormatado = String.Format(Formatacao, this._ValorNatural).Replace(",","").Replace(".","").Trim().PadLeft(this._TamanhoCampo, '0');
                   break;
               }
           case TTiposDadoEDI.ediNumericoComPonto:
               {
                   string Formatacao = "{0:f" + this._QtdDecimais.ToString() + "}";
                   this._ValorFormatado = String.Format(Formatacao, this._ValorNatural).Replace(",", ".").Trim().PadLeft(this._TamanhoCampo, '0');
                   break;
               }
           case TTiposDadoEDI.ediNumericoComVirgula:
               {
                   string Formatacao = "{0:f" + this._QtdDecimais.ToString() + "}";
                   this._ValorFormatado = String.Format(Formatacao, this._ValorNatural).Replace(".", ",").Trim().PadLeft(this._TamanhoCampo, '0');
                   break;
               }
           case TTiposDadoEDI.ediDataAAAAMMDD:
               {
                   if ( (DateTime)this._ValorNatural != DateTime.MinValue)
                   {
                       string sep = (this._SeparadorDatas == null ? "" : this._SeparadorDatas.ToString());
                       string Formatacao = "{0:yyyy" + sep + "MM" + sep + "dd}";
                       this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                   }
                   else
                   {
                       this._ValorNatural = "";
                       goto case TTiposDadoEDI.ediAlpha;
                   }
                   break;
               }
           case TTiposDadoEDI.ediDataDDMM:
               {
                   if ((DateTime)this._ValorNatural != DateTime.MinValue)
                   {
                       string sep = (this._SeparadorDatas == null ? "" : this._SeparadorDatas.ToString());
                       string Formatacao = "{0:dd" + sep + "MM}";
                       this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                   }
                   else
                   {
                       this._ValorNatural = "";
                       goto case TTiposDadoEDI.ediAlpha;
                   }
                   break;
               }
           case TTiposDadoEDI.ediDataDDMMAAAA:
               {
                   if ((DateTime)this._ValorNatural != DateTime.MinValue)
                   {
                       string sep = (this._SeparadorDatas == null ? "" : this._SeparadorDatas.ToString());
                       string Formatacao = "{0:dd" + sep + "MM" + sep + "yyyy}";
                       this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                   }
                   else
                   {
                       this._ValorNatural = "";
                       goto case TTiposDadoEDI.ediAlpha;
                   }
                   break;
               }
           case TTiposDadoEDI.ediDataDDMMAA:
               {
                   if ((DateTime)this._ValorNatural != DateTime.MinValue)
                   {
                       string sep = (this._SeparadorDatas == null ? "" : this._SeparadorDatas.ToString());
                       string Formatacao = "{0:dd" + sep + "MM" + sep + "yy}";
                       this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                   }
                   else
                   {
                       this._ValorNatural = "";
                       goto case TTiposDadoEDI.ediAlpha;
                   }
                   break;
               }
           case TTiposDadoEDI.ediDataMMAAAA:
               {
                   if ((DateTime)this._ValorNatural != DateTime.MinValue)
                   {
                      string sep = (this._SeparadorDatas == null ? "" : this._SeparadorDatas.ToString());
                      string Formatacao = "{0:MM" + sep + "yyyy}";
                      this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                  }
                  else
                  {
                      this._ValorNatural = "";
                      goto case TTiposDadoEDI.ediAlpha;
                  }
                  break;
              }
          case TTiposDadoEDI.ediDataMMDD:
              {
                  if ((DateTime)this._ValorNatural != DateTime.MinValue)
                  {
                      string sep = (this._SeparadorDatas == null ? "" : this._SeparadorDatas.ToString());
                      string Formatacao = "{0:MM" + sep + "dd}";
                      this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                  }
                  else
                  {
                      this._ValorNatural = "";
                      goto case TTiposDadoEDI.ediAlpha;
                  }
                  break;
              }
          case TTiposDadoEDI.ediHoraHHMM:
              {
                  string sep = (this._SeparadorHora == null ? "" : this._SeparadorHora.ToString());
                  string Formatacao = "{0:HH" + sep + "mm}";
                  this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                  break;
              }
          case TTiposDadoEDI.ediHoraHHMMSS:
              {
                  string sep = (this._SeparadorHora == null ? "" : this._SeparadorHora.ToString());
                  string Formatacao = "{0:HH" + sep + "mm" + sep + "ss}";
                  this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                  break;
              }
          case TTiposDadoEDI.ediDataDDMMAAAAWithZeros:
              {
                  string sep = (this._SeparadorDatas == null ? "" : this._SeparadorDatas.ToString());
                  if ( (this._ValorNatural != null) || (!this.ValorNatural.ToString().Trim().Equals("")))
                  {
                      string Formatacao = "{0:dd" + sep + "MM" + sep + "yyyy}";
                      this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                  }
                  else
                  {
                      this._ValorFormatado = "00" + sep + "00" + sep + "0000";
                  }
                  break;
              }
          case TTiposDadoEDI.ediDataAAAAMMDDWithZeros:
              {
                  string sep = (this._SeparadorDatas == null ? "" : this._SeparadorDatas.ToString());
                  if (this._ValorNatural != null)
                  {
                      string Formatacao = "{0:yyyy" + sep + "MM" + sep + "dd}";
                      this._ValorFormatado = String.Format(Formatacao, this._ValorNatural);
                  }
                  else
                  {
                      this._ValorFormatado = "00" + sep + "00" + sep + "0000";
                  }
                  break;
              }
      }
  }

Note que nesta ocasião, dependendo do tipo de dado informado, fazemos a conversão do object em ValorNaturalpara string, aplicando a máscara informada na mesma, e retornando essa string na propriedade ValorFormatado

Já no momento da interpretação do campo, iremos utilizar o seguinte:

    /// <summary>
    /// Transforma o valor vindo do campo do registro EDI da propriedade ValorFormatado para o valor natural (com o tipo
    /// de dado adequado) na propriedade ValorNatural
    /// </summary>
    public void DecodificarEDIParaNatural()
    {
        if (this._ValorFormatado.Trim().Equals(""))
        {
            this._ValorNatural = null;
       }
       else
       {
           switch (this._TipoCampo)
           {
               case TTiposDadoEDI.ediAlpha:
                   {
                       this._ValorNatural = this._ValorFormatado.ToString().Trim();
                       break;
                   }
               case TTiposDadoEDI.ediInteiro:
                   {
                       this._ValorNatural = long.Parse(this._ValorFormatado.ToString().Trim());
                       break;
                   }
               case TTiposDadoEDI.ediNumericoSemSeparador:
                   {
                       string s = this._ValorFormatado.Substring(0, this._ValorFormatado.Length - this._QtdDecimais) + "," + this._ValorFormatado.Substring(this._ValorFormatado.Length - this._QtdDecimais, this._QtdDecimais);
                       this._ValorNatural = Double.Parse(s.Trim());
                       break;
                   }
               case TTiposDadoEDI.ediNumericoComPonto:
                   {
                       this._ValorNatural = Double.Parse(this._ValorFormatado.ToString().Replace(".", ",").Trim());
                       break;
                   }
               case TTiposDadoEDI.ediNumericoComVirgula:
                   {
                       this._ValorNatural = Double.Parse(this._ValorFormatado.ToString().Trim().Replace(".", ","));
                       break;
                   }
               case TTiposDadoEDI.ediDataAAAAMMDD:
                   {
                       if (!this._ValorFormatado.Trim().Equals(""))
                       {
                           string cAno = "";
                           string cMes = "";
                           string cDia = "";
                           if (this._SeparadorDatas != null)
                           {
                               string[] split = this._ValorFormatado.Split(this._SeparadorDatas.ToCharArray());
                               cAno = split[0];
                               cMes = split[1];
                               cDia = split[2];
                           }
                           else
                           {
                               cAno = this._ValorFormatado.Substring(0, 4);
                               cMes = this._ValorFormatado.Substring(4, 2);
                               cDia = this._ValorFormatado.Substring(6, 2);
                           }
                           if ((cDia.Equals("00") && cMes.Equals("00") && cAno.Equals("0000")))
                           {
                               this._ValorNatural = null;
                           }
                           else
                           {
                               this._ValorNatural = DateTime.Parse(cDia + "/" + cMes + "/" + cAno);
                           }
                       }
                       else
                       {
                           this._ValorNatural = null;
                       }
                       break;
                   }
               case TTiposDadoEDI.ediDataDDMM:
                   {
                       if (!this._ValorFormatado.Trim().Equals(""))
                       {
                           string cAno = "1900";
                           string cMes = "";
                           string cDia = "";
                           if (this._SeparadorDatas != null)
                           {
                               string[] split = this._ValorFormatado.Split(this._SeparadorDatas.ToCharArray());
                               cMes = split[1];
                               cDia = split[0];
                           }
                           else
                           {
                               cMes = this._ValorFormatado.Substring(2, 2);
                               cDia = this._ValorFormatado.Substring(0, 2);
                           }
                           this._ValorNatural = DateTime.Parse(cDia + "/" + cMes + "/" + cAno);
                       }
                       else
                       {
                           this._ValorNatural = null;
                       }
                      break;
                  }
              case TTiposDadoEDI.ediDataDDMMAAAA:
                  {
                      string cDia = "";
                      string cMes = "";
                      string cAno = "";
                      if (this._SeparadorDatas != null)
                      {
                          string[] split = this._ValorFormatado.Split(this._SeparadorDatas.ToCharArray());
                          cAno = split[2];
                          cMes = split[1];
                          cDia = split[0];
                      }
                      else
                      {
                          cDia = this._ValorFormatado.Substring(0, 2);
                          cMes = this._ValorFormatado.Substring(2, 2);
                          cAno = this._ValorFormatado.Substring(4, 4);
                      }
                      if ((cDia.Equals("00") && cMes.Equals("00") && cAno.Equals("0000")) || this._ValorFormatado.Trim().Equals(""))
                      {
                          this._ValorNatural = DateTime.Parse("01/01/1900"); //data start
                      }
                      else
                      {
                          this._ValorNatural = DateTime.Parse(cDia + "/" + cMes + "/" + cAno);
                      }
                      break;
                  }
              case TTiposDadoEDI.ediDataDDMMAA:
                  {
                      string cDia = "";
                      string cMes = "";
                      string cAno = "";
                      if (this._SeparadorDatas != null)
                      {
                          string[] split = this._ValorFormatado.Split(this._SeparadorDatas.ToCharArray());
                          cAno = split[2];
                          cMes = split[1];
                          cDia = split[0];
                      }
                      else
                      {
                          cDia = this._ValorFormatado.Substring(0, 2);
                          cMes = this._ValorFormatado.Substring(2, 2);
                          cAno = this._ValorFormatado.Substring(4, 2);
                      }
                      this._ValorNatural = DateTime.Parse(cDia + "/" + cMes + "/" + cAno);
                      break;
                  }
              case TTiposDadoEDI.ediDataMMAAAA:
                  {
                      string cDia = "01";
                      string cMes = "";
                      string cAno = "";
                      if (this._SeparadorDatas != null)
                      {
                          string[] split = this._ValorFormatado.Split(this._SeparadorDatas.ToCharArray());
                          cAno = split[1];
                          cMes = split[0];
                      }
                      else
                      {
                          cMes = this._ValorFormatado.Substring(0, 2);
                          cAno = this._ValorFormatado.Substring(2, 4);
                      }
                      this._ValorNatural = DateTime.Parse(cDia + "/" + cMes + "/" + cAno);
                      break;
                  }
              case TTiposDadoEDI.ediDataMMDD:
                  {
                      string cDia = "";
                      string cMes = "";
                      string cAno = "1900";
                      if (this._SeparadorDatas != null)
                      {
                          string[] split = this._ValorFormatado.Split(this._SeparadorDatas.ToCharArray());
                          cMes = split[0];
                          cDia = split[1];
                      }
                      else
                      {
                          cDia = this._ValorFormatado.Substring(2, 2);
                          cMes = this._ValorFormatado.Substring(0, 2);
                      }
                      this._ValorNatural = DateTime.Parse(cDia + "/" + cMes + "/" + cAno);
                      break;
                  }
              case TTiposDadoEDI.ediHoraHHMM:
                  {
                      string cHora = "";
                      string cMinuto = "";
                      if (this._SeparadorHora != null)
                      {
                          string[] split = this._ValorFormatado.Split(this._SeparadorHora.ToCharArray());
                          cHora = split[0];
                          cMinuto = split[1];
                      }
                      else
                      {
                          cHora = this._ValorFormatado.Substring(0, 2);
                          cMinuto = this._ValorFormatado.Substring(2, 2);
                      }
                      this._ValorNatural = DateTime.Parse(cHora + ":" + cMinuto + ":00");
                      break;
                  }
              case TTiposDadoEDI.ediHoraHHMMSS:
                  {
                      string cHora = "";
                      string cMinuto = "";
                      string cSegundo = "";
                      if (this._SeparadorHora != null)
                      {
                          string[] split = this._ValorFormatado.Split(this._SeparadorHora.ToCharArray());
                          cHora = split[0];
                          cMinuto = split[1];
                          cSegundo = split[2];
                      }
                      else
                      {
                          cHora = this._ValorFormatado.Substring(0, 2);
                          cMinuto = this._ValorFormatado.Substring(2, 2);
                          cSegundo = this._ValorFormatado.Substring(4, 2);
                      }
                      this._ValorNatural = DateTime.Parse(cHora + ":" + cMinuto + ":00");
                      break;
                  }
              case TTiposDadoEDI.ediDataDDMMAAAAWithZeros:
                  {
                      goto case TTiposDadoEDI.ediDataDDMMAAAA;
                  }
              case TTiposDadoEDI.ediDataAAAAMMDDWithZeros:
                  {
                      goto case TTiposDadoEDI.ediDataAAAAMMDD;
                  }
          }
      }
  }

Note que trabalhamos essencialmente com a conversão da string contida em ValorFormatado (obtida através da leitura do arquivo, que será detalhada na segunda parte
do artigo) nos tipos de dado correspondente à máscara informada, e retornando este objeto na propriedade ValorNatural.

Pronto, temos construída a classe que irá representar cada campo de um registro em um arquivo fixo-blocado. Note que esta classe é genérica, não foi informado nenhum atributo específico do layout que iremos construir, falado no início do artigo. Na segunda parte, vamos aplicar o conceito de POO sobre um registro de um arquivo.

Longo (principalmente os code-snippets :-)), não foi? Embora possamos fazer o proposto via ODBC (ainda não testei como se faz), esta série de artigos é mais para a aplicação do conceito de POO mesmo, embora eu já me utilizei deste código em alguns sistemas em produção :-)

Um abraço!

Leonel Fraga de Oliveira Leonel Fraga de Oliveira é formado em Processamento de Dados na Faculdade de Tecnologia de São Paulo (FATEC-SP - 2002) e anteriormente em Técnico em Eletrônica, pela ETE Professor Aprígio Gonzaga (lá em 1999).
Atualmente trabalha como Analista de Sistemas na Prefeitura Municipal de São Caetano do Sul - SP
Tem como hobbies DJing (também trabalha como DJ freelancer) e ciclismo, além da manutenção dos sites NeoMatrix Light e NeoMatrix Tech.
Gosta de música eletrônica, tecnologia, cinema (super fã de Jornada nas Estrelas), gastronomia e outras coisas mais.


Compartilhe nas redes sociais

   

Deixe seu comentário

comments powered by Disqus