Cómo leer archivos planos con ADO.NET (versión Visual Basic 2005)
Hace poco más de un año escribí este artículo que describe una técnica para leer archivos planos utilizando el OleDB provider de ADO.NET. Es uno de los artículos de este sitio que ha recibido más comentarios, y entre ellos está uno que dejó fredy que me hizo re-hacer el ejemplo en Visual Basic 2005 para comprobar que no fuera un error de código—en realidad él hizo la mayor parte de la chamba para "traducir" la rutina.
No voy a explicar mucho la lógica del código—para eso te dejo de tarea que leas el artículo original—aquí simplemente te comparto cómo se vería la rutina en VB:
Imports System.IO
Imports System.Data
Imports System.Data.OleDb
Module Utilerias
Public Enum TipoDeArchivoPlano
Delimited
Fixed
End Enum
Public Function LeerArchivoPlano(ByVal archivo As FileInfo, _
ByVal tieneEncabezado As Boolean, _
ByVal tipoDeArchivo As TipoDeArchivoPlano) As DataTable
If (Not archivo.Exists) Then
Throw New FileNotFoundException("No se encontró el archivo especificado")
End If
Dim conEncabezado As String = IIf(tieneEncabezado, "YES", "NO")
Dim connectionString As String = _
String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};" + _
"Extended Properties='text;HDR={1};FMT={2}'", _
archivo.DirectoryName, conEncabezado, tipoDeArchivo.ToString())
Dim dt As DataTable = New DataTable("miTabla")
Using conn As OleDbConnection = New OleDbConnection(connectionString)
Using da As OleDbDataAdapter = New OleDbDataAdapter( _
"SELECT * FROM " + archivo.Name, conn)
da.Fill(dt)
End Using
End Using
Return dt
End Function
End Module
Para probarla, hice una aplicación sencilla en ASP.NET que mostrara los datos de un archivo .CSV que está dentro de un subdirectorio del sitio web.

El archivo jason.csv contiene:
Producto,Cantidad,Precio
Sierra eléctrica,1,250
Máscara de hockey,1,15.50
Machete,5,2.70
Detergente para ropa (con quita-manchas),1,10
Delantal,2,7.25
Afilador,3,5
La página dentro de la solución que en realidad solo tiene un GridView. Este es el contenido de Default.aspx:
<%@ Page Language="VB" AutoEventWireup="false"
CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Leer un archivo plano con VB 2005</title>
</head>
<body>
<form id="miFormulario" runat="server">
<div>
<asp:GridView ID="miGridView" runat="server">
</asp:GridView>
</div>
</form>
</body>
</html>
Finalmente, para mandar llamar la rutina y bindear—¿enlazar?—los datos al GridView, solo agregué esto en el code-behind:
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub miFormulario_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles miFormulario.Load
If Not Page.IsPostBack Then
Dim archivo As FileInfo = _
New FileInfo("D:\WebSites\LeerArchivosPlanosVB\Archivos\jason.csv")
Dim tabla As New DataTable
tabla = Utilerias.LeerArchivoPlano(archivo, True, TipoDeArchivoPlano.Delimited)
If tabla.Rows.Count > 0 Then
miGridView.DataSource = tabla
miGridView.DataBind()
Else
Response.Write("No hay datos para mostrar.")
End If
End If
End Sub
End Class
El resultado de correr la página:
Whew! Funcionó
Enjoy. ![]()
PD. Puedes descargar el código de este ejemplo del sitio de la Comunidad .NET de Cd. Juárez.
Por RSS o Atom


Hola, muy bueno tu codigo lo encontre excelente, pero te quisiera hacer una consulta, como se puede hacer cuando el archivo no esta delimiado por comas, si no que por algun otro caracter, como punta y coma (;) o tabulado, etc. Es posible decirle al FTM el caracter delimitador. O en su defecto antes de leer el archivo, cambiar o reemplazar el caracter que tenga, ya sea ; o tab, por comas para asi poder leer bien el archivo.
Sí es posible. Para un archivo delimitado por ";" creo que puedes hacerlo utilizando un archivo schema.ini (de manera similar a como se hizo con el de posiciones fijas en el artículo original).
El contenido del archivo schema.ini podría ser algo como esto:
[miarchivodelimitadoporpuntoycoma.txt]
ColNameHeader=True
Format=Delimited(;)
Col1=Producto Char Width 40
Col2=Cantidad Long
Col3=Precio Double
No sé si poniendo FMT=Delimited(;) en el string de conexión también funcione.
Espero te sirva
Hola muchas gracias por el artículo. ¿¿Sería posible que al escribir "una,palabra,entre,comillas" evitara el delimitador??
Anónimo--
No necesitas nada especial para que evite el delimitador cuando el texto está entre comillas.
Por ejemplo, si tu archivo .CSV tiene este contenido:
Cantidad,Producto,Precio
1,"Sierra electrica",250
1,"Máscara, de, hockey",15.50
5,"Machete",2.70
1,"Detergente para ropa con, quita-manchas",10
2,"Delantal",7.25
3,"Afilador",5
La rutina lo lee perfectamente (al menos en las pruebas que yo hice).
Si de plano se te pone muy rebelde, podrías utilizar un archivo schema.ini para "forzar" que lo lea como un CSV delimitado. El schema.ini podría verse así:
[miarchivo.csv]
ColNameHeader=True
Format=CSVDelimited
Y si se sigue poniendo necio, pues entonces ya te sugeriría cambiar el caracter delimitador (usando, por ejemplo ";" como mencioné en uno de los comentarios anteriores).
Espero te sirva.
Cordial Saludo, estoy probando tu ejemplo y esta excelente pero a mi me sale con un pequeño error que todos los datos del archivo ya sea csv o plano salen todos en una columna......
Las broncas de que no te traiga correctamente los datos (especialmente cuando contienen muchas columnas) las he visto porque las columnas de texto contienen comas como parte de los datos. Lo mismo se hacen pelotas el Excel o Access (ambos usan el mismo driver de OleDb que el ejemplo del artículo, detrás de las cámaras). En este caso lo que debes asegurarte es que las columnas de texto estén delimitado por comillas.
Agregar un schema.ini también ayuda mucho a asegurar que se lea el tipo de dato correcto por cada columna.
Espero te ayude
Para los que están teniendo el problema de que sus datos aparecen en una sola columna:
Parece que Diego Bernal ya le atinó con algunas cosas para resolverlo. Yo le hice el comentario que si tienes campos tipo fecha a veces son latosos (porque en "español" y en "inglés" se leen distinto, p.ej. 05/06/2008 es 6 de mayo en EE.UU. pero es 5 de junio en países hispanos). En fin, les copio aquí su mensaje:
"Carlos Cordial Saludo. Escribo para decir que ya pude llenar el dataset completamente con columnas y todo, gracias a tus consejos me puse a indagar profundamente en archivos txt, csv, y schemas.ini. En síntesis mi problema era con el idioma de mi sistema operativo , las comillas me sirvieron en muchos campos pero implicaba hacer un trabajo extra pero el ( ; ) sirvió perfectamente .Me tope con un excelente articulo el cual me llevo por otros caminos en cuanto al trabajar con archivos de este tipo y me encontré con muchas características tales como se ven en este articulo:
http://www.mvp-access.es/softjaen/articulos/texto/jet_text_isam.htm#Index21
De pronto hace una simbiosis perfecta con tu articulo y puede ayudar a mucha gente que tiene mi problema de pronto si quieres hacer un síntesis y complementar tu gran articulo que me sirvió bastante para realizar mi aplicación.
De Nuevo Gracias por la atención y la ayuda .
Diego Fernando Bernal B.
Desde Colombia."
PD. También pudiera serles útil la página de referencia sobre schema.ini en MSDN (parece que cambió desde que escribí el artículo)
Espero les ayude