28 noviembre 2008

Leyendo datos de hojas de cálculo de Microsoft Excel

Si hay algo que nos piden frecuentemente a los programadores de gestión es poder recoger o enviar datos a los programas ofimáticos más populares: Microsoft Word, Microsoft Excel y Microsoft Access.

Lo más común suele ser leer datos de una hoja de cálculo y guardarlos en nuestra base de datos, aunque también tenemos la posibilidad de enviarle la información para que Excel nos haga una gráfica espectacular.

Una hoja de cálculo es realmente un libro que puede contener una o más hojas de cálculo:


A su vez, Microsoft Excel puede abrir varios libros a la vez.

EL COMPONENTE TEXCELAPPLICATION

En la paleta de componentes tenemos el componente de la clase TExcelApplication que se encuentra en la sección Servers:


Lo insertamos en el formulario donde vamos a hacer la importación y lo llamamos Excel para simplificar:


Supongamos que queremos leer esta hoja de cálculo:


Primero abrimos la hora de cálculo:

Excel.Workbooks.Open( ExtractFilePath( Application.ExeName ) + 'Hoja.xls',
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, 0 );

Hay que reconocer que la cantidad de parámetros que tiene el método Open es impresionante:


Aunque no hay que asustarse porque lo que necesitamos realmente es el primer parámetro (el nombre del archivo excel a abrir). Los demás son para elegir si queremos abrirlo en modo sólo lectura, introducir una contraseña, etc.

Una vez que hemos abierto la hora de cálculo tenemos que situarnos en la Hoja1. Para ello creamos las siguientes variables:

var
i: Integer;
si: String;
Hoja: _WorkSheet;

Las variables i y si son para recorrer las celdas de la hoja de cálculo y la variable Hoja va a apuntar a una hoja en concreto. En nuestro caso la primera:

Hoja := Excel.Worksheets.Item[1] as _WorkSheet;

Para leer información de las celdas de la hoja de cálculo tenemos que conocer las coordenadas horizontales (A,B,C,…) y las verticales (1,2,3,…). Cuando lea la información la voy a volcar a un componente ListView configurado con estas columnas:


Ahora sólo queda ir recorriendo cada fila hasta que encontremos una fila vacía:

i := 2;
si := IntToStr( i );
repeat
with ListView.Items.Add do
begin
SubItems.Add( Hoja.Range['A'+si,'A'+si].Value2 ); // Código
SubItems.Add( Hoja.Range['B'+si,'B'+si].Value2 ); // Nombre
SubItems.Add( Hoja.Range['C'+si,'C'+si].Value2 ); // CIF
SubItems.Add( Hoja.Range['D'+si,'D'+si].Value2 ); // Saldo
end;

Inc( i );
si := IntToStr( i );
until ( VarType( Excel.Range['A'+si,'A'+si].Value2 ) = VarEmpty );

La propiedad Value2 de cada celda devuelve un tipo Variant, por ello utilizo la función VarType para comprobar si lo que hay en la celda esta vacío (VarEmpty). De ese modo sabemos cuando hemos terminado de leer datos.

Por último cerramos la hoja de cálculo con:

Excel.Workbooks.Close( 0 );

Con esto ya hemos conseguido traernos la información de la hoja de cálculo:


Igualmente podemos escribir datos en cualquier celda de la hoja de cálculo con total naturalidad:

Hoja.Range['B2','B2'].Value2 := ‘TRANSPORTES GARCIA, S.L.’;

De esta manera podemos crear nuestras plantillas de hojas de cálculo con gráficas incluidas y desde Delphi le enviamos la información.

Pruebas realizadas en RAD Studio 2007.

Publicidad