XLSX para curiosos

lunes, 26 de febrero de 2007

Con la aparición de Microsoft Office 2007, se cambia el formato default de los archivos y nace un nuevo formato Abierto basado en XML (Open XML format) que se distingue con la aparición de nuevas extensiones (DOCX, XLSX y PPTX) para las aplicaciones Word, Excel y PowerPoint 2007 respectivamente.

Estos archivos son en realidad un ZIP el cual contiene varias carpetas y múltiples archivos XML que definen al documento y sus datos, esto en contraste con las versiones anteriores que permitían generar XML pero dejaban toda la información en un archivo solo.

Esto tiene algunas ventajas importantes:
  • No necesitamos mirar el archivo entero para buscar información específica.
  • Las imágenes, y archivos específicos contenidos se encuentran guardados en sus formatos originales.

  • Al estar comprimidos son más pequeños.
  • Podemos acceder a la información sin necesitar el modelo de objetos de Excel por ejemplo.
La idea es empezar a conocer cómo es este nuevo formato, en particular vamos a hablar de los archivos de EXCEL ya que, en general, son los que más necesitamos generar nosotros los programadores en nuestras aplicaciones.

XLSX por dentro

Los archivos Open XML ZIP son denominados PACKAGE, y los archivos contenidos dentro de estos PARTS, cada una de estas PARTS se auto definen, y pueden describir cualquier tipo de archivo (XMLs, imágenes, sonido, video, o cualquier objeto binario).

Estas PARTS se encuentran relacionadas dentro de un archivo especial con extensión RELS, que también es un XML dentro del mismo ZIP.

Pero ¿dóne están los datos?

Para esto veamos cómo estan compuestos estos archivos, si descomprimimos uno con cualquier herramienta de descompresión ZIP, vemos que se crean una serie de carpetas y archivos.


El archivo “[Content_Types].xml” describe todas las partes que definen al documento, en este ejemplo tenemos un para de imágenes insertadas, un gráfico y algunos datitos sueltos.


Por último tres carpetas:

_rels: Esta carpeta contiene uno o más archivos RELS, que definen relaciones.
docProps: Declarada información referida al archivo XLSX, como el número de versión de Excel, datos del creador, etc.
xl: Contiene todo lo referido al documento, datos, archivos externos, relaciones, etc.

Siguiendo con la búsqueda de los datos, entramos en la carpeta xl:



Acá vamos a ver una estructura de carpetas variable dependiendo de la información del documento, carpetas para almacenar las imágenes, carpetas para los gráficos, etc. y algunos documentos XML sueltos sharedString.xml donde estan definidos todos los strings que tengamos como dato, styles.xml describen los formatos utilizados, workbook.xml contiene una referencia a las hojas que contiene el documento, y algunos archivos más dependiendo del contenido del mismo.

Siguiendo por la carpeta worksheets, en ella tenemos un XML por cada hoja (sheet) que tengamos, en este caso tenemos tres sheets, con sus nombres, sheet1, sheet2 y sheet3.

Si editamos estos archivo vamos a ver que toda la información (data) de la hoja, se encuentra dentro de un elemento llamado sheetdata, por cada fila hay un elemento row, dentro un elemento por cada celda, y más abajo un elemento mas con su valor.


Por razones de performance, los strings se guardan en una tabla única dentro del archivo sharedStrings.xml, por eso desde aquí se marca una referencia al mismo y se indica que es un string con el atributo t=”s”.

En este caso las celdas A1 y A2 contienen texto que está definido en el archivo sharedString.xml, que básicamente contiene una tabla con todos los textos del documento completo.

En resumen

Con lo que vimos acá claro esta que no vamos a poder desarrollar una herramienta para editar estos archivos, ni tampoco creo que esa sea la idea, pero si tener una noción básica de cómo son internamente estos archivos, para saciar un poco la curiosidad.

Acá dejo un par de links de interés sobre el tema.

Detalles sobre la nueva versión de office:

http://office.microsoft.com/es-es/default.aspx

Importante

Para poder leer estos archivos desde versiones anteriores de office, es necesario instalar un paquete de compatibilidad que se puede bajar desde aquí:

http://www.microsoft.com/downloads/details.aspx?FamilyID=941b3470-3ae9-4aee-8f43-c6bb74cd1466&DisplayLang=es

Leer más...

Propiedades útiles en datasets tipados

viernes, 23 de febrero de 2007

Repaso en este artículo un par de propiedades muchas veces olvidadas en la definición de campos en un dataset tipado, que permiten escribir “menos y mejor código” en las aplicaciones que los usan.


Para evitar comprobaciones innecesarias, usar la propiedad NullValue

Propiedades de campos en datasetEsta propiedad, que solo puede utilizarse en campos de tipo String, permite definir el resultado obtenido al acceder al “campo” (en realidad, a la variable tipada que lo representa) cuando el mismo tiene valor null en los datos de origen.

El comportamiento predeterminado (Throw exception) es bien conocido como fuente de errores en tiempo de ejecución, y hace que el desarrollador se acostumbre a codificar de esta forma:

if (!row.IsObservacionesNull())

obs = row.Observaciones;

else

obs = “”;

Lo cual, si bien es correcto y evita los errores, requiere mucho código para una tarea simple.

Más eficiente, e igualmente seguro, sería asignar la propiedad NullValue = (Empty) , o bien (Null) si ese es el valor deseado, en la definición del campo en el dataset. De esa manera todo el código anterior se reemplaza por

obs = row.Observaciones;


Para facilitar el agregado de filas, especificar un DefaultValue

Aunque parezca trivial, esta práctica no siempre aplicada permite que, al preparar los valores de inserción de una nueva fila, baste con especificar los campos significativos. Es decir:
DSActivEtapa.ActivEtapaRow row = ds.ActivEtapa.NewActivEtapaRow();

row.IdEtapa = idEtapa;

row.Fecha = fecha;

en lugar de:
DSActivEtapa.ActivEtapaRow row = ds.ActivEtapa.NewActivEtapaRow();

row.IdEtapa =idEtapa;

row.Fecha = fecha;

row.CantEjecuciones = 0;

row.YaCompletada = false;

row.Anulada = false;

...etc.

Importante: esta propiedad (DefaultValue) no sirve para reemplazar un valor nulo por otra cosa, al leer los campos desde una base de datos. Se aplica exclusivamente a la inserción de nuevas filas en el dataset.
Leer más...

sábado, 17 de febrero de 2007

“Snapshots” qué es y cuándo es utilizable


Una de las nuevas ventajas que tiene SQL 2005 es la posible utilización de “Snapshots”.

Esta nueva herramienta, que sólo se encuentra en SQL Server 2005 Enterprise Edition, permiten hacer copias de la base de datos, en formato sólo lectura, la cual se puede usar para, entre otros fines:

  • Reportes.
  • Auditorías.
  • Backups.


Actualmente esto se podía hacer utilizando las herramientas de backup, pero ahora se agiliza ampliamente con la utilización de estos “Snapshots”.

Cómo trabaja

El primer pensamiento es que esta herramienta hace una copia total de la base de datos, pero esto no es así, ya que si este fuera el caso, no ofrecería ninguna ventaja sobre los backups de las versiones anteriores de SQL Server.

En realidad trabajan en forma un tanto distinta. Cuando se genera, SQL realiza una marca en el archivo original de la base de datos y se genera un archivo separado completamente vacío que será utilizado para almacenar los datos antes de que estos sean modificaos en el archivo original. En el proceso se realizan dos pasos,

  • Actualización del snapshot, se copia la información que será modificada al archivo de backup para su resguardo.
  • Actualización de la base de datos, se ejecuta la acción deseada sobre la base de datos original..


    Para ejemplificar la agilidad de este método supongamos el siguiente ejemplo, hicimos un “Snapshot” y sólo se modificó el 10% de la información almacenada por la base de datos, en este caso si quisiéramos volver al de partida, el proceso soló implicaría la copia del 10% de la información y no de la totalidad como en versiones anteriores de SQL Server.

    A continuación vemos un gráfico que muestra la relación existente entre la información almacenada en uno y otro archivo.

Ventajas del proceso

  • Partiendo de la base de que sólo necesita trabajar con porciones de datos que sufrieron alteraciones, la creación y los procesos realizados sobre “Snapshots” serán mucho más rápidos que el anterior manejo de Backups.
  • Como los datos escritos en el archivo separado son sólo las porciones de datos que sufrieron modificaciones, el tamaño de disco utilizado, no es necesariamente el mismo que la base de datos original, permitiendo la creación de varios “Snapshots” utilizando muchísimo memos espacio en disco.
  • La escasa utilización de espacio en disco nos permitiría repetir el proceso con el fin de agilizar auditorias sobre la información.
  • Es considerablemente mas fácil de trabajar y mucho mas rápido que los anteriores Backups.
  • Posibilidad de generar reportes rápidos y con mínimo esfuerzo.
  • Datos corruptos o borrados pueden ser reparados o copiados desde el “Snapshot”.


Desventajas del proceso

  • Como los “Snapshots” siguen utilizando los archivos primarios de la base de datos y por este motivo, el utilizar un “Snapshot” no mejorará los tiempos necesarios en la realización de reportes, ya que los usuarios y UD utilizarán los mismos archivos.
  • Los “Snapshots” siguen atadas a la base de datos primaria, por lo que no se puede deshabilitar la base de datos. Si la base de datos no está online no se podrá acceder tampoco a los “Snapshots” que de esta dependan.
  • Sólo es una propiedad que tiene la versión “Enterprise Edition”.
  • Si los datos cambian rápidamente no se obtendrán los beneficios de “Snapshots” sobre backups.
  • Los “Snapshots” no soportan índices de texto completo.

Cómo se utiliza

Para crear un “Snapshot” no hay una sentencia determinada que sea soportada por el “Management Studio” de SQL 2005, la sentencia para crear una foto es la siguiente

CREATE DATABASE nombreDelSnapShot ON
( NAME = baseDeDatos,
FILENAME = ‘path destino’) AS SNAPSHOT OF baseDeDatos

La utilización de “Snapshots”, es esencialmente igual a la utilización de cualquier otra base de datos de nuestro servidor, sólo hay que recordar que es imposible rPublicarealizar modificaciones sobre dos datos que se encuentran almacenados en ella.

La eliminación es equivalente a las demás bases de datos de nuestro sistema, mientras que restaurar la base de datos al momento de creación del “Snapshot” es muy simple y rápido mediante la ejecución del siguiente comando
RESTORE DATABASE BaseDeDatos FROM DATABASE_SNAPSHOT = ‘nombreDelSnapShot’


Conclusiones



Como pudimos ver esta propiedad es muy sencilla de implementar y utilizar. Es posible crear una instancia, hacer algunas consultas sobre la misma y eliminarla en un par de minutos sin necesidad de trabajo arduo ni complicado.
No intenta reemplazar al Backup, son herramientas completamente diferentes para casos y escenarios distintos, solo que los “Snapshots” agilizan trabajos que antes requerían pesados Backups.

Leer más...

Crystal Clear, una forma de trabajo

miércoles, 14 de febrero de 2007

Más allá de las capacidades técnicas que tenga un equipo, el desafío más importante es encontrar una dinámica de trabajo que lo haga más eficiente. La experiencia, en nuestro caso, nos llevó a adoptar decididamente Metodologías Agiles en el proceso de desarrollo, para lo cual, fuimos (y continuamos) experimentando distintas posibilidades.
Una de las guías que nos ha dado buenos resultados fue Crystal Clear, que descubrimos hace un par de años en el libro “Crystal Clear – A human powered methodology for small teams, de Alistair Cockburn.

Aquí, algunas de sus características:


Qué es Crystal Clear ?

Crystal Clear no es una metodología en si misma sino una familia de metodologías con un “código genético” común.
La idea es poder armar distintas metodologías para distintos tipos de proyectos. Cada proyecto y organización usará este código genético para generar su propia metodología.
El nombre Crystal deriva de la caracterización de los proyectos según 2 dimensiones, tamaño y complejidad (como en los minerales, color y dureza).
Por ejemplo, Clear es para equipos de hasta 8 personas, Amarillo para equipos entre 10 – 20 miembros, Naranja para 20 a 25 personas, etc.



El Código Genético


El código genético consiste en:

1. Un “modelo de juegos cooperativos

Este modelo ve al desarrollo de software como una serie de partidos que consisten en inventar y comunicar. Cada partido es diferente y tiene como objetivo entregar software y prepararse para el siguiente juego. Esto permite al equipo trabajar concentrado y en forma efectiva con un objetivo claro cada vez.


2. Prioridades

Crystal Clear establece un conjunto de prioridades y principios que sirven de guía para la toma de decisiones


  • Eficiencia en el desarrollo: para hacer que los proyectos sean económicamente rentables
  • Seguridad en lo que se entrega
  • Habitabilidad: hacer que todos los miembros del equipo adopten y sigan las convenciones de trabajo establecidas por el equipo mismo.



3. Propiedades

  • Frecuencia en las entregas: entregar al usuario funcionalidad "usable" con una frecuencia de entre 2 semanas y no más de un mes.
  • Comunicación: Crystal Clear toma como uno de sus pilares a la comunicación. Promueve prácticas como el uso de pizarrones, pizarras y espacios destinados a que todos (miembros del equipo y visitas) puedan ver claramente el progreso del trabajo
  • Crecimiento reflexivo : es necesario que el equipo lleve a cabo reuniones periódicas de reflexión que permitan crecer y hacernos más eficientes.

    Estas tres propiedades son "obligatorias" para Crystal Clear, las siguientes pueden agregarse en la medida de las necesidades de cada grupo y proyecto

  • Seguridad personal: lograr que cada miembro del team pueda sentirse cómodo con el trabajo y el entorno
  • Concentración: las entregas frecuentes permiten que cada desarrollador puede enfocar de a un problema por vez evitando dispersiones.
  • Fácil acceso a usuarios clave: tratar de hacer que el usuario sea una parte más del equipo es fundamental para ir depurando errores de manera temprana.
  • Entorno técnico con: i - Testing automatizado (incorporación, por ejemplo, de UnitTest) - ii. Integración frecuente (uso de herramientas específicas como Cruise Control)

4. Principios

  • El grado de detalle necesario en documentar requerimientos, diseño, planeamiento, etc, varía según el proyecto
  • Es imposible eliminar toda documentación pero puede ser reducida logrando un modo de comunicación más accesible, informal y preciso que pueda ser accedido por todos los miembros del equipo.
  • El equipo ajusta constamente su forma de trabajo para lograr que cada personalidad encaje con los otros miembros, con el entorno y las particularidades de cada asignación


5. Estrategias

Ni las estrategias ni las técnicas son mandatorias para Crystal Clear. Pero es bueno tener en cuenta algunas de ellas al momento de empezar a trabajar.

Tres de las estrategias que están más relacionadas son las de apuntar a tener "Victorias Tempranas", arrancar el desarrollo de lo que se denomina un "Esqueleto que Camine" y pensar siempre en hacer "Rearquitectura Incremental" van de la mano.
El poder arrancar el proceso a partir de un esqueleto sobre el cual se irá agregando funcionalidad en cada una de las entregas ayuda a que se vean los avances desde el comienzo (aunque sea una simple pantalla de ABM que se conecta con la base de datos y muestra un solo dato). A medida que se avanza en el proceso, la rearquitectura permitirá ir agregando más "cuerpo" al esqueleto inicial.

Todas describen una forma de tomar ventaja del desarrollo incremental para establecer valor desde el principio.





6. Técnicas

Igual que con las estrategias, hay una lista de técnicas propuestas por Crystal Clear, de las cuales se pueden ir tomando las más convenientes según el momento en que se encuentra el proceso de desarrollo del proyecto.

Las reuniones diarias (introducidas por la metodología Scrum) acompañan el seguimiento y mantienen el foco en el próximo paso a seguir, y también permiten la discusión productiva de líneas a seguir.

Las reuniones de reflexión periódicas son fundamentales para que los miembros del equipo se expresen abiertamente, para revisar el trabajo hecho y evaluar qué cosas dan resultado y cuáles no o de empezar a trabajar.

Todo esto permite ir armando una metodología de trabajo que se adecue al equipo, el proyecto y los tiempos que se manejen.



En Resumen


La guía de trabajo que presenta Crystal Clear es altamente recomendable para equipos pequeños. Da flexibilidad y prioriza la parte humana (como todas las Metodologías Agiles), apuntando a lograr eficiencia, habitabilidad y confianza en los miembros del equipo.
Presta especial importancia a la ubicación física del grupo, donde la comunicación cumple el principal rol. La entrega frecuente de código confiable y "funcionando" mantiene el foco y evita distracciones.

El equipo es el que elige qué técnicas aplicar según lo que consideren apropiado en cada proyecto.

Para ver más sobre Crystal Clear:

http://alistair.cockburn.us/index.php/Crystal_methodologies_main_foyer

Leer más...

Operadores Checked y Unchecked

jueves, 1 de febrero de 2007

Existen en C# gran cantidad de tipos predefinidos numéricos sbyte, byte, short, ushort, int, uint, long, ulong, etc.

Cuando uno mira código en general no es tan común ver estos tipos de datos, la mayoría de nosotros definimos nuestras variables del tipo int.

Esto tiene sus implicancias por un lado el tipo int abarca valores desde -2,147,483,648 hasta 2,147,483,647 (32 bits) esto en general nos mantiene cubiertos para contadores comunes, pero estamos reservando mucho espacio de memoria inútilmente, si por ejemplo queremos contar quizás hasta 100.

Ahora bien siendo conscientes de esto, uno podría optar por pensar un poco mas, que tipo de dato utilizar para definir nuestras variables, pero ¿sabemos que es lo que pasa si nos pasamos del rango que cada tipo de dato tiene como limite?, uno tendería a pensar que nos daría un error, pero atención no es así!

Existen dos operadores que habitualmente no utilizamos que nos permiten verificar este tipo de casos, estos son checked y unchecked.

El operador checked, permite chequear si tenemos overflow cuando realizamos operaciones como (++ -- -(unary) + - * / ) o alguna conversión explícita entre tipos, ejemplo pasar de int a byte.

El unchecked hace lo contrario, es decir ignora el overflow y trunca el valor.

Vamos a mostrar un ejemplo:
byte val = 250;
for (int i = 1; i < 15; i++)
{
val++;
}
El tipo de dato byte soporta un rango de valores entre 0 y 255, en esta caso en particular al terminar este ciclo la variable val queda con valor 8 y no da ningún error, lo que esta pasando es que se pasa de su limite, llega al máximo valor soportado por este tipo de dato 255, y vuelve a empezar de cero, si esta variable fuera del tipo int y nos pasáramos de su limite, volvería a empezar desde -2,147,483,648 ya que es un tipo de dato con signo.

Esto claro es un problema si no lo tenemos en cuenta, porque podría darnos resultados inesperados.

Para que esto no ocurra tenemos tres opciones, una es incluir la opción /checked cuando compilamos el proyecto, en cuyo caso se realizaría este tipo de chequeo en toda nuestra aplicación, otra es encerrar este bloque de código con el operador checked y la última es "asegurarnos" que nuestra variable no de overflow.

Vamos a ver el mismo ejemplo pero con chequeo habilitado:
byte val = 250;
checked
{
for (int i = 1; i < 15; i++)
{
val++;
}
}
En este caso el codigo lanza una Exception, del tipo OverflowException.

Es importante tener en cuenta que este tipo de Overflows se puede dar tambien en la conversion explicita de un tipo a otro ejemplo:
int intVal = 256;
byte val = (byte)intVal;
En este caso en particular la variable val queda con valor 0.

El operador unchecked es útil si necesitamos dentro de un bloque checked, dejar parte del código sin chequear.

Conclusión:

La verdad no creo que estos operadores sean muy utilizados, pero lo que creo que es importante tener en cuenta es que si nos excedemos en el rango permitido por una variable numérica, por defecto no se lanza una Exception, que es lo que quizás uno se hubiese imaginado, y por otro lado creo que vale la pena tomarnos un minuto para elegir mejor que tipo de dato vamos a utilizar en cada caso para optimizar nuestras aplicaciones.
Leer más...