Editor de code snippets para C# y VS2005

martes 28 de noviembre de 2006 | categorías: , , , | 0 comentarios -- da clic aquí para dejar el tuyo

Hace rato había platicado de la chidez de los code snippets en Visual Studio 2005.

Hoy se me ofreció hacer uno rápidamente. Y aunque es relativamente sencillo hacerlo a pata, en realidad no tenía tiempo de echarme la documentación para hacerlo. Necesitaba un "editor" para sinppets, pero el único que hasta hoy conocía es para Visual Basic 8.

Afortunadamente, este vato se creó un programita llamado Snippy. Puedes descargarlo de aquí.

El programita te genera el archivo .snippet; lo grabas en un directorio debajo de My Documents/Visual Studio 2005/Code Snippets/Visual C# y listo. Ni siquiera tienes que reiniciar Visual Studio.

Writely ya funciona con Blogger Beta

sábado 11 de noviembre de 2006 | categorías: | 0 comentarios -- da clic aquí para dejar el tuyo

Hoy me di cuenta después de postear que Writely (Google Docs pues) ya funciona con Blogger Beta. Demonios, de haberlo notado antes lo hubiera usado para el último artículo.

¿Cómo era ese (bleep) connection string?

| categorías: , | 0 comentarios -- da clic aquí para dejar el tuyo

Una de las cosas que más panzonas me caen de acceder a datos, es que para cada tipo de base de datos los strings de conexión siempre son distintos. Oracle, SQLServer y Access (por mencionar algunos) utilizan cada uno su sintaxis... y siempre se me olvida. ¿Cómo era? ¿DataSource? ¿Database? ¿Initial Catalog? (maldición)

Por eso ConnectionStrings.com se me hizo tan chida. En una sola página encuentras cómo conectarte a un montón de bases de datos. ¿Quieres conectarte a una AS/400 con el OLEDB Provider de .NET? Ahí viene. ¿A SQL Server 2005 con MARS habilitado? También viene.

Échale un ojo. Probablemente acabarás bookmarkeando el sitio como yo.

Cómo leer archivos planos con ADO.NET

| categorías: , , , | 38 comentarios -- da clic aquí para dejar el tuyo

(Antes que me la rieguen, sí, ya sé que son "archivos de texto sencillo" pero este blog está en pocho, ¿no? Digo, no hay archivos de computadora planos, o cúbicos o esféricos, que yo sepa, pero así les dicen muchos desarrolladores)

Aunque hoy en día ya todo mundo debería de estar utilizando (según yo) XML para el intercambio de información, sigue siendo muy comun que para mandar información de un sistema a otro se haga a través de archivos "planos" de texto.

Si alguna vez has lideado con sistemas legacy o en plataformas chiples (mainframe, or SAP anyone?) estoy seguro que sabes de lo que hablo. Otro caso común es cuando requieres que tu usuario genere algún archivo para cargar esos datos en tu aplicación. Harta cantidad de gerentoides y chalanes no saben ni (bleep) de sistemas o de computadoras, pero eso sí, son masters sensai del Excel, así que es fácil decirles que le den un "Save As... CSV" a un archivo para subir sus datos.

Ahora, ¿cómo le harías para leer esos archivos con .NET? Si eres entusiasta probablemente luego luego te las ingeniarías para usar un FileStream y parsear el contenido línea por línea, dar 3 maromas... qué se yo. Sin embargo, existe un truco sencillo que puede ahorrarte broncas: utilizar el OLEDB Provider de ADO.NET para hacerlo. Esta técnica funciona bastante bien para leer archivos CSV o archivos de texto con columnas en posiciones fijas (si son secuenciales, ya valiste cake).

Leyendo un archivo CSV

Por ejemplo, imagina que eres achichincle del Jason (el de las películas de terror) y te manda a hacer sus compras, de lo contrario terminarás con tu cabeza y cuerpo en diferentes sectores de la ciudad. El vato hace su "chopin list" en Excel y lo guarda en el siguiente archivo llamado jason.csv:

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

Entonces, como buen dotnetero, podrías leerlo con una rutina como esta:

// asumiendo que tenemos
// using System.Data.OleDb;
// using System.Data;
 
// en este connection string:
//     HDR=Yes       : indica que el primer registro contiene los encabezados 
//                     (nombres) de las columnas, no datos.
//     FMT=Delimited : indica que el los campos están delimitados por un caracter
//                     (coma por default).
string connectionString =
    @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\DirectorioDeArchivosCSV;" +
    "Extended Properties='text;HDR=Yes;FMT=Delimited'";
 
DataTable dt = new DataTable("miTabla");
using (OleDbConnection conn = new OleDbConnection(connectionString))
using (OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM jason.csv", conn))
{
    da.Fill(dt);
}
 
// hacer algo con los datos en el DataTable

El código es bastante sencillo, es el patrón estándar para usar un DataAdapter. Lo único de especial que tiene es que utiliza el OLEDB Data Provider, y que en el connection string le especificamos el directorio donde se encuentra el archivo, así como el formato que tiene. Nota que emites un SELECT de SQL común y corriente, por lo cual podrías agregar una cláusula WHERE si así lo quisieras.

En fin, para comprobar que en realidad funcionara el código, puse un breakpoint e invoqué el DataSet Visualizer desde Visual Studio. El resultado:

Pero, ¿qué tan inteligente es el OLEDB Provider? ¿Adivinó correctamente el tipo de mis datos?

Leyendo un archivo de texto con posiciones fijas

Ahora, asume que el méndigo Jason te la puso más difícil y en lugar de darte un archivo CSV, te da un archivo de texto sencillo como este (jason.txt):

El código sería muy similar al anterior:

// asumiendo que tenemos
// using System.Data.OleDb;
// using System.Data;
 
// en este connection string:
//     HDR=Yes   : indica que el primer registro contiene los encabezados 
//                 (nombres) de las columnas, no datos.
//     FMT=Fixed : indica que el los campos están en posiciones fijas y el tamaño
//                 de cada campo se especifican con un archivo SCHEMA.INI
//                 en el mismo directorio donde está el archivo a leer.
string connectionString =
    @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\DirectorioDeArchivosTXT;" +
    "Extended Properties='text;HDR=Yes;FMT=Fixed'";
 
DataTable dt = new DataTable("miTabla");
using (OleDbConnection conn = new OleDbConnection(connectionString))
using (OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM jason.txt", conn))
{
    da.Fill(dt);
}
 
// hacer algo con los datos en el DataTable


De hecho, lo único que cambió fue el parámetro FMT en el connectionString, el nombre del archivo y el directorio donde localizarlo. Sin embargo, para que esto funcione con archivos de posiciones fijas es necesario un paso adicional: especificar el tamaño (y tipo) de las columnas en el archivo.

Esto se hace mediante un archivo schema.ini que debe estar en el mismo directorio que el archivo que vas a leer. Consulta esta página para saber todas las opciones disponibles. En nuestro caso un archivo como el siguiente sería suficiente:

[jason.txt]
Format=FixedLength
Col1=Producto Char Width 40
Col2=Cantidad Long Width 10
Col3=Precio Double Width 10


Factorizando código

Si generalizamos el código un poco, podemos extraer una función sencilla que pueda ser reutilizada en varios de nuestros programas. Esa rutina podría ser como esta, en donde le pasas como parámetros el tipo y archivo a leer y te regresa un DataTable poblado ya con los datos:

// asumiendo que tenemos 
// using System.Data.OleDb;
// using System.Data;
// using System.IO;
 
public enum TipoDeArchivoPlano { Delimited, Fixed }
 
public static DataTable LeerArchivoPlano(
    FileInfo archivo, bool tieneEncabezado, TipoDeArchivoPlano tipoDeArchivo )
{
    if (!archivo.Exists)
        throw new FileNotFoundException(
            "No se encontró el archivo especificado");
 
    string conEncabezado = tieneEncabezado ? "YES" : "NO";
 
    string connectionString = String.Format(
        @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};" +
        "Extended Properties='text;HDR={1};FMT={2}'",
        archivo.DirectoryName, conEncabezado, tipoDeArchivo.ToString());
 
    DataTable dt = new DataTable("miTabla");
    using (OleDbConnection conn = new OleDbConnection(connectionString))
    using (OleDbDataAdapter da =
        new OleDbDataAdapter("SELECT * FROM " + archivo.Name, conn))
    {
        da.Fill(dt);
    }
 
    return dt;
}


De manera que pueda ser llamado así:

DataTable dt = LeerArchivoPlano(
    new FileInfo(@"C:\DirectorioDeArchivosCSV\jason.csv"),
    true, TipoDeArchivoPlano.Delimited);


En fin, la idea es esa.

Enjoy.


Actualización, 13 diciembre 2007:

Gracias a los comentarios de fredy, publiqué otro artículo con el código en Visual Basic 2005, para aquellos que les interese.

¿Qué lenguaje de programación eres?

viernes 10 de noviembre de 2006 | categorías: | 1 comentarios -- da clic aquí para dejar el tuyo

You are C. You do what you're told, even if you know the result will be bad.

Which Programming Language are You?

Finalmente, .NET Framework 3.0 está aquí

martes 7 de noviembre de 2006 | categorías: , | 0 comentarios -- da clic aquí para dejar el tuyo

Probablemente ya te habrás enterado que el ya se liberó la versión de producción del .NET Framework 3.0 ¿No? ¿Pos en qué cueva andas metido?

www.netfx3.com es el sitio para descargarlo.