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.

18 comentarios:

goooooood girl dijo...

your blog is feel good......

Anónimo dijo...

impresionante blog sobre delphi, felizidades

Alejandro dijo...

muy interesante el post, si quiero hacer lo mismo pero con delphi.net, sabes como hacerlo?
gracias
saludos

Administrador dijo...

Que yo sepa, la versión para .NET no tiene la pestaña de componentes Servers donde se encuentra el que necesitamos: TExcelApplication.

Con el tiempo que lleva Delphi para .NET supongo que habrá algún componente de terceros (libre o de pago) que cumpla el mismo cometido.

Saludos.

Armormi dijo...

hola he estado leyendo el post. y como no pude encontrar el codigo para delphi.net decidi pasarme a delphi 6.
pero me dio error.

podrias colocar el codigo para ver como es que va colocado.. soy nueva en delphi
gracias

Armormi dijo...

hola he estado leyendo el post. y como no pude encontrar el codigo para delphi.net decidi pasarme a delphi 6.
pero me dio error.

podrias colocar el codigo para ver como es que va colocado.. soy nueva en delphi
gracias

Administrador dijo...

El código es precisamente el que aparece en este post. Lo que podría ocurrirte es que no tienes la versión de Office compatible con los componentes de Delphi 6.

Por ello recomiendo de Delphi 7 en adelante. Lo que hacen estos componentes es llamar a Excel directamente. Y si puedes, utiliza Office XP.

Saludos.

Jose Aantonio dijo...

tengo delphi 7 y pongo tu codigo y me da este error [Error] main.pas(152): Undeclared identifier: 'VarType'

que hago?? gracias

Jose Aantonio dijo...

[Error] main.pas(152): Undeclared identifier: 'VarType' me da este error que hago???

Administrador dijo...

Incluye en el apartado "uses" la unidad Variant.

Saludos.

Alex dijo...

Ha oido un programa interesante - reparar archivos xlsx en el Internet. La utiliza me ha gustado y yo he cargado de el Internet. El instrumento ha determinado mis problemas con xls files. Luego el programa tengo muchos posibilidades y gratis como recordo.

elarys dijo...

necesito modificar un archivo excel ya creado, pero que no fue guardado en disco... osea esta temporalmente en la memoria... hay alguna forma de hacer esto.

Javier dijo...

Hola:
he seguido las instrucciones al pie de la letra pero no se me muestra nada en el listview, pero ejecuto el programa paso a paso y va realizando todas las instrucciones, pero no muestra nada.¿Hay que modificar algo en el listview apartde de añadirle las columnas?
Un saludo y enhorabuena por el blog

Javier dijo...

Hola:
he seguido los pasos del post y no me muestra nada en el listview. Ejecuto el programa paso a paso y la verdad es que realiza todas las instrucciones pero no me muestra nada en el listview. ¿Hay algo mas que configurar en el listview a parte de crearle las columnas?
Utilizo delphi 7.
Un saludo y enhorabuena por el blog

Administrador dijo...

Comprueba si en el ListView tienes la propiedad ViewStyle con el valor vsReport.

Saludos.

The Ingenier dijo...

Como puedo saber la edición del office?
ya que esos parametros solo se pueden utilizar para office anteriores al 2007, en el office 2007 en adelante no funciona así.

Administrador dijo...

Ese es uno de los problemas que no se como resolver, porque ya de manera predeterminada tienes que utilizar unos componentes para Office según su versión (2000, XP, etc.).

Es algo que en Delphi siempre he visto como algo chapucero.

Saludos.

Yusmel González Hernández dijo...

Muchas gracias, la verdad que me ha sido de gran ayuda. Muy buen trabajo.

Publicidad