Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Importar datos de un excell delphi (https://www.clubdelphi.com/foros/showthread.php?t=81972)

Anusky 10-01-2013 13:06:05

Importar datos de un excell delphi
 
Hola a todos,
estoy haciendo un programa que importa los datos de un fichero excell con el componente TexcellApplication, uso Delphi 7, y no consigo sacarle punta. Aquí os dejo el fallo que me está volviendo loca:

El programa lee las casillas del fichero excell una a una, va leyendo todas las filas de una columna y luego pasa a la siguiente columna y hace lo mismo, así hasta el final del fichero, la casilla que lee el componente es un dato 'variant' (lo obtengo con la función value2 del componente), y por último los meto en un TstringList.
código:
var
hoja: _Worksheet;
x: variant;
listaContenidoExcell: TStringList;
begin
(**Aquí primero asigno a hoja la pestaña uno del fichero y todas las cosas que hacen falta,
voy leyendo todas las filas de cada columna con un bucle**)
x := hoja.Range[sLetraColumna + IntToStr(i), sLetraColumna + IntToStr(i)].Value2;
listaContenidoExcell.Add(VarToStr(x));
end;

problema
Las columnas que son fechas las trae en juliano, en lugar de la fecha (dd/mm/aaaa) que yo veo en el fichero excell me trae un número.

Intentos de solucionar el problema que no han funcionado
1. Intentar descubrir cuando una columna es fecha y modificar el dato que trae definiéndolo como fecha. No funciona porque la columna fecha la trae como varDouble (igual que otras columnas que si que son números). He empezado por detectar las columnas que son double pero esto hace que al hacer
listaContenidoExcell.Add(DateToStr(TVarData(x).VDate))
en algunas columnas que son datos numéricos de verdad me traiga los valores en formato fecha.

2.Formateo de la columna fecha en el archivo excell. No funciona porque al ponerla como texto me convierte automáticamente los valores de las fechas a juliano, así que tengo el mismo problema. Además formatear la columna como formato fecha no sirve para nada, el componente sigue detectando como varDouble el valor de la casilla.

3. Detectando las columnas que son double (como en el intento 1), con un try intentar comprobar que la conversión a fecha da un resultado válido y sino tratarlo como que no es fecha. No funciona porque hay valores en columnas de tipo varDouble que son números y que al pasarlos a fecha da una fecha correcta.

A ver si alguien me puede dar un poquillo de luz al problema, o por lo menos alguna idea de como afrontarlo. Muchas gracias a todos!! :)

Casimiro Noteví 10-01-2013 14:14:16

Recuerda poner los tags al código fuente, ejemplo:



Gracias :)

Faust 10-01-2013 17:06:35

Checa este enlace

http://www.djpate.freeserve.co.uk/AutoExcl.htm

Para saber sobre los objetos disponibles en excel para trabajar con un documento te recomiendo buscar también sobre macros, en el ftp del club encontrarás un manualillo viejón pero buenón :D ;)

Al González 10-01-2013 19:14:33

Veo que usas automatización, de los tiempos en que los documentos de Office eran de formato cerrado. Pero a partir de Office 2007 el formato de los libros y hojas de Excel es XML (OpenXML). El año pasado desarrollé unas clases para trabajar con ese tipo de documento, precisamente para importar información Excel desde Delphi.

En caso de que tus documentos sean de dicho formato (extensión .xlsx), más tarde pondré por aquí un ejemplo de uso. :)

Saludos.

Al González.

nlsgarcia 10-01-2013 22:47:34

Anusky,

Cita:

Empezado por Anusky
Problema:
Las columnas que son fechas las trae en juliano, en lugar de la fecha (dd/mm/aaaa) que yo veo en el fichero excell me trae un número.

Cita:

Empezado por Anusky
A ver si alguien me puede dar un poquillo de luz al problema, o por lo menos alguna idea de como afrontarlo.

Revisa esta Imagen:



La imagen anterior es un ejemplo de Automatización de Excel 2010 con Delphi 7.

Revisa este código:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
   Excel, WrkS, WrkB : OLEVariant;
   Row, Col : Integer;
   Rows, Cols : Integer;

begin

   Excel := CreateOleObject('Excel.Application');
   Excel.Workbooks.Open(GetCurrentDir+'\TestData.xlsx');

   WrkS := Excel.Worksheets[1];
   Cols := WrkS.UsedRange.Columns.Count;
   Rows := WrkS.UsedRange.Rows.Count;

   for Row:= 1 to StringGrid1.RowCount do
         StringGrid1.Rows[Row].Clear;

   StringGrid1.FixedRows := 1;
   StringGrid1.FixedCols := 1;
   StringGrid1.RowCount := Rows + 1;
   StringGrid1.ColCount := Cols + 1;

   for Row:= 1 to StringGrid1.RowCount do
      for Col:= 1 to StringGrid1.ColCount  do
         StringGrid1.Cells[Col,Row]:= Excel.ActiveSheet.Cells[Row,Col].Value;

   Excel.Quit;    

end;
El código anterior lee por medio de la Automatización de Excel 2010 con Delphi 7 una hoja de cálculo sin alterar el contenido de la data obtenida y carga la misma en un control TStringGrid.

Revisa este link:
Cita:

Delphi 3 - Delphi and Microsoft Office: Automating Excel and Word
http://edn.embarcadero.com/article/10126
Espero sea útil :)

Nelson.

nlsgarcia 10-01-2013 23:07:37

Al González,

Cita:

Empezado por Al González
El año pasado desarrollé unas clases para trabajar con ese tipo de documento, precisamente para importar información Excel desde Delphi.

Cita:

Empezado por Al González
En caso de que tus documentos sean de dicho formato (extensión .xlsx), más tarde pondré por aquí un ejemplo de uso

Excelente :)

Nelson.

Al González 10-01-2013 23:17:30

Para evitar alguna posible confusión, creo que me faltó decir que el mecanismo tradicional de automatización sigue siendo vigente, aún con los nuevos formatos de Microsoft Office. Por tanto podría ser suficiente aplicar un código como el que ha puesto Nelson. :) ^\||/

Viene dándose la idea de dejar de lado la automatización ahora que podemos acceder al contenido de los documentos de forma directa. Sin embargo, eso no quita que puedan resolverse muchos casos mediante automatización, sobre todo aquellos donde la velocidad de procesamiento no sea algo crítico.

Saludos.

nlsgarcia 11-01-2013 04:55:40

Al González,

Cita:

Empezado por Al González
Viene dándose la idea de dejar de lado la automatización ahora que podemos acceder al contenido de los documentos de forma directa. Sin embargo, eso no quita que puedan resolverse muchos casos mediante automatización.

Es correcto, sin embargo seria muy interesante poder contar con las Clases para Importar Información de Excel que comentastes y que permitirían un mejor performance en procesos críticos, al permitir acceder a la data de Excel en formato XML de forma directa sin depender de los procesos de Automatización :)

Nelson.

Al González 11-01-2013 06:18:46

Claro, Nelson.

No sé si recuerdas que hace un par de semanas subí al FTP del club un paquete de clases y funciones llamado GH Freebrary:

Cita:

Empezado por Al González (Mensaje 452170)
Asimismo, toda colaboración técnica para mejorar esta pequeña obra es bienvenida. De momento lo que podría hacer falta es que se ponga a prueba, contiene algunas clases de distintos propósitos y funciones para variedad de asuntos. Entre las clases podemos encontrar las que estaban en Magia Data, además de otras como las siguientes:

TghXMLDoc.- Para crear, leer y escribir documentos XML.

TghOpenXMLSpreadsheet, TghOpenXMLSpreadsheetBook y TghOpenXMLSpreadsheetStrs.- Para abrir y leer libros Excel de formato 2007 o superior (OpenXML).

[...]

Algún moderador tuvo la gentileza de poner ese hilo como adherido para que todo el mundo lo viera más fácilmente. Incluso recuerdo un comentario de agradecimiento de tu parte. :)

Hoy, por falta de tiempo, no pude preparar el ejemplo. Pero esas clases están ahí para quien desee descargarlas y "trastear" con ellas, son tal cuales las usé en dos pequeños proyectos que desarrollé en 2012.

Una vez que descomprimes un archivo .xlsx de Excel, que en realidad es un ZIP (con algún componente descompresor como Abbrevia o similar), puedes entonces crear una instancia de TghOpenXMLSpreadsheet para acceder a alguna de las hojas del libro o TghOpenXMLSpreadsheetBook para acceder al libro entero si el documento tiene varias hojas.

Anímate a echarle un vistazo en lo que me doy un poco de tiempo para preparar algo más ilustrativo. :)

Saludos cordiales.

Al.

nlsgarcia 11-01-2013 06:52:21

Al González,

Pensé que eran otras Clases diferentes a GH Freebrary las que comentabas.

Mil gracias nuevamente :)

Nelson.

Anusky 11-01-2013 09:50:39

Mil gracias por toda la información, me está siendo super útil :). Un saludo a todos!!

Anusky 11-01-2013 10:48:23

Un saludo a todos de nuevo,
después de leer la información he probado el código y me salta un 'OLE error 800A03EC' al leer el valor de la casilla. Según he leído la automatización funciona a partir de excel 2007 con formato .xlsx, pero mi programa debe funcionar con archivos .xls, que son los que yo uso para las pruebas. Dejo aquí el código por si no fuese problema de la extensión del archivo:

Código Delphi [-]
procedure TMuestraArchivoForm.procesarArchivo;
var
  p: integer;
  x: String;
  listaContenidoExcell: TStringList;
  Excel, WrkS, WrkB: OLEVariant;
  Row, Col: Integer;
  Rows, Cols: Integer;
begin
  //Variable de control
  p := 0;

  //--------------
  Excel := CreateOleObject('Excel.Application');
  Excel.Workbooks.Open(FRutaArchivo);

  WrkS := Excel.Worksheets[1];
  Cols := WrkS.UsedRange.Columns.Count;
  Rows := WrkS.UsedRange.Rows.Count;
  //-------------


  repeat
    listaContenidoExcell := TStringList.Create;

    for Row := 1 to Rows + 1 do
    begin
      x := Excel.ActiveSheet.Cells[Row, Col].Value;
      if x <> EmptyStr then
        listaContenidoExcell.Add(x);
    end;

//----Aquí hay código de lo que hago con el stringlist de meterlo en casillas y tal---//

    inc(p);
    FreeAndNil(listaContenidoExcell);
  until p = Cols + 1; 
  
  Excel.Quit;

end;

El fallo me da en la línea 'x := Excel.ActiveSheet.Cells[Row, Col].Value;'
Muchas gracias de nuevo por todo, seguiré haciendo pruebas.

Anusky 11-01-2013 11:34:17

Solucionado, empezaba a leer la columna 0 y por eso saltaba el fallo. Muchas gracias por todo el código está hecho y funcionando perfectamente. Un saludo! :)


La franja horaria es GMT +2. Ahora son las 19:51:54.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi