9 de julho de 2009

Lendo arquivos texto com ADO

Apesar do sucesso e da grande disseminação do formato XML, há ainda uma vasta gama de situações em que o uso de arquivos texto (TXT) é mais conveniente. Há um Cliente recente da ABC71, por exemplo, que está vindo de um sistema COBOL desenvolvido por eles mesmos. Esse Cliente terá que se integrar ao sistema da Nota Fiscal Eletrônica mas não haverá tempo hábil para implantar o Omega, que possui esta integração de forma nativa. A solução, neste caso, foi fazer com que o sistema COBOL gerasse arquivos no formato texto com campos de tamanho fixo para que pudéssemos colocar as informações no fluxo para a Receita.

Uma forma simples de realizar a leitura desses arquivos texto foi usar o driver ODBC para Arquivos Texto da Microsoft, que acredito ser distribuido com o Windows. Tendo um driver ODBC, fica fácil acessar os dados através de uma conexão ADO já que se usa mecanismos bem conhecidos de acesso a bancos de dados.

O conceito de uso de arquivos TXT como banco de dados é simples: todos os arquivos TXT colocados numa determinada pasta são considerados parte do banco, sendo que cada arquivo é tratado como uma tabela diferente desse banco. Nesses arquivos, cada linha corresponde a um registro. Para ligar tudo isso, é preciso criar um arquivo que descreve como os dados estão organizados em cada TXT; tal arquivo é apropriadamente nomeado schema.ini já que o que ele descreve é justamente o esquema do banco de dados.

O arquivo schema.ini é um arquivo texto comum, criado para ter uma seção para cada tabela. Assim, o nome da "tabela" vai entre um par abre/fecha colchetes numa linha e, nas linhas subsequentes, são colocadas configurações gerais para a "tabela" e uma lista com a definição dos "campos", com seus nomes e tipos de dado esperado. O quadro abaixo mostra um exemplo de schema.ini com duas tabelas. Explico em seguida o significado de cada parâmetro.
[mestre.txt]
ColNameHeader=False
Format=FixedLength
MaxScanRows=0
DateTimeFormat=YYYYMMDD
CharacterSet=ANSI
Col1=EMPRESA Long width 4
Col2=FILIAL Long width 4
Col3=INFNFE_ID Char width 47
Col4=TOTAL Float width 19
Col5=DATA_ALTER Date width 8
[detalhes.txt]
ColNameHeader=False
Format=FixedLength
MaxScanRows=0
DateTimeFormat=YYYYMMDD
CharacterSet=ANSI
Col1=INFNFE_ID Char width 47
Col2=SEQ_NF Long width 4
Col3=CODIGO Char width 60
Col4=QTDE Float width 19
Col5=VALOR Float width 19
Col6=DATA_ALTER Date width 8

Nesse exemplo, referenciei dois arquivos como tabelas: mestre.txt e detalhes.txt, cada uma descrita em sua própria seção e cada parâmetro inserido numa linha separada. O significado dos parâmetros é o seguinte:
  • ColNameHeader indica se a primeira linha do arquivo texto especifica o nome das colunas. No meu caso, os arquivos têm apenas dados, razão pela qual informei False nas duas "tabelas".
  • Format É o modo como os valores dos campos estão distribuídos nas tabelas. Informei FixedLength porque no meu caso cada campo terá uma quantidade fixa de caracteres em todas as linhas (registros) do arquivo. Esse parâmetro poderia ainda assumir os valores TabDelimited (onde o valor de cada campo seria separado por um caracter de tabulação), CSVDelimited (se ao invés do TAB o separador for uma Vírgula) ou Delimited (caso você queira estipular um separador diferente).
  • MaxScanRows Esta configuração é usada somente quando se usa o gerenciador do ODBC do Windows para configurar o schema.ini. O número especificado nele determina quantos registros (linhas) o Gerenciador deve ler antes de tentar determinar os tipos de dados dos campos. Tentei usar o Gerenciador mas não fui muito feliz; preferi criar na mão ...
  • DateTimeFormat diz qual é o formato das datas incluídas no arquivo. O valor YYYYMMDD significa que, no meu caso, as datas terão 4 dígitos para o ano, 2 para o mês e 2 para o dia, sem separadores.
  • CharacterSet é o codepage para os caracteres a serem usados. Especifiquei o conjunto Ansi, que é o valor padrão e atende a maioria dos casos.
Todos esses parâmetros e outros que não usei são explicados no MSDN.

Em seguida, vêm os parâmetros começados com COL que descrevem as colunas (campos) da tabela TXT. A sintaxe é
Coln=NOME TIPO [COMPRIMENTO]

Onde:
  • n é um número sequencial, isto é, o primeiro campo é Col1, o segundo Col2 e assim por diante.
  • NOME é um nome único para o meu campo. Pode-se usar esses nomes em comandos SELECT para extrair informações do banco de dados.
  • TIPO é um dos tipos de dados permitidos.
  • [COMPRIMENTO] indica a extensão do campo em quantidade de caracteres. Para o formato de arquivo FixedLength, esse comprimento é obrigatório para todos os campos; nos demais formatos informe apenas para campos do tipo Char.

Para usar no ADO, crie uma conexão com uma Connection String apropriada, como no exemplo:
m_strCnxn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\PastaTxt;Extended Properties=""Text;HDR=No"""
m_Cnxn.Open strCnxn, "", ""

O caminho c:\PastaTxt é o local onde coloquei os arquivos TXT e o SCHEMA.INI. Veja que não foi necessário criar uma fonte de dados ODBC para se conectar! Para finalizar, você pode submeter queries a esse banco de dados usando o Execute da conexão:
Set m_ResultSet = m_Cnxn.Execute("select * from mestre.txt")

É interessante observar que foi informado o nome do arquivo TXT como se fosse um nome de tabela.


Um comentário :

Diego Ferreira disse...

Excelente!! Aqui na empresa pego muitos sistemas feito em Cobol e para extrair os dados para o nosso banco nem sempre é legal. Agora tenho mais uma maneira de fazer essa conversão! Obrigado pela dica.

Diego Ferreira

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.