Importar archivo Excel a VFP 9.0

2,727 views
Skip to first unread message

integral

unread,
Dec 1, 2014, 1:06:42 PM12/1/14
to publice...@googlegroups.com
Estimados Amigos :

Tengo el siguiente codigo para impoortar desde EXCEL un archivo y pasarlo a una tabla...

LOCAL lcXlsArchivo    
lcXlsArchivo = GETFILE('xls','Nombre:','Abrir',0 ,'Abrir Archivo de Planilla de Excel'

**--Si cancelamos la apertura 
IF EMPTY(lcXlsArchivo)
    RETURN .F.
ENDIF
    

USE D:\SISCARGA\REPORTE.DBF
SELECT Reporte
*SELECT personaltemp
APPEND FROM (lcXlsArchivo) TYPE XL5

Me indica un eror que muesdtro en vla imagen adjunta.

Agradezco vuestra ayuda.

Saludos,

INTEGRAL

Error Excel.jpg

Héctor Bernal

unread,
Dec 1, 2014, 1:57:51 PM12/1/14
to publice...@googlegroups.com
Integral,

Buenas tardes. Hace tiempo encontré la siguiente función para importar desde excel de una forma bastante rápida. El único detalle que tienes que checar es el archivo resultante, pues la mayoria de los campos te los genera como MEMO, cosa que puedes resolver creando una función que recorra el cursor haciendo las conversiones necesarias.

Lee el contenido de la primera hoja del archivo excel, parámetro que puedes pasar como lcNombreHoja, punto que modifiqué para evitar que siempre sea Hoja1$.

Espero te sea de ayuda.


Ejemplo de uso:

lcArchivo = GETFILE('xls,xlsx')
IF !EMPTY(lcArchivo)
   SELECT xlResults
   SCAN
      *!*
      *!* Aquí va el código necesario para procesar los datos del archivo.
      *!*
   ENDSCAN
ENDIF

*-----------------------------------
* AUTHOR: Trevor Hancock
* CREATED: 02/15/08 04:55:31 PM
* ABSTRACT: Code demonstrates how to connect to
* and extract data from an Excel 2007 Workbook
* using the "Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)"
* from the 2007 Office System Driver: Data Connectivity Components
*-----------------------------------
FUNCTION ImportarDesdeXls_Xlsx
PARAMETERS lcXLBook, lcNombreHoja

LOCAL loExcel, lcArchio AS STRING, lnSQLHand AS INTEGER, lcSQLCmd AS STRING, lnSuccess AS INTEGER, lcConnstr AS STRING

IF USED('xlResults')
   USE IN xlResults
ENDIF

llError = .f.
TRY
   loExcel = CreateObject([Excel.Application])
CATCH
   llError = .t.
ENDTRY

IF !llError AND VARTYPE(loExcel)="O"
   llError = .f.
   TRY 
      loLibro = loExcel.Workbooks.Open(lcXLBook)
   CATCH
      llError = .t.
   ENDTRY
   
   IF !llError
      loHoja = loLibro.ActiveSheet
      lcNombreHoja = loHoja.Name
      loLibro.Close
      loExcel.Quit
      
      *!*
      *!* Driver XLS
      *!*
      lcConnstr = [Driver=] + [{Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};] + [DBQ=] + lcXLBook
      IF !FILE( lcXLBook )
          MESSAGEBOX('No se encontró el archivo '+ALLTRIM(lcXLBook)+'.', 16, 'Atención')
          RETURN .F.
      ENDIF
      lcArchivo = JUSTSTEM(lcXLBook)
      
      *-- Attempt a connection to the .XLSX WorkBook.
      *-- NOTE: If the specified workbook is not found,
      *-- it will be created by this driver! You cannot rely on a
      *-- connection failure - it will never fail. Ergo, success
      *-- is not checked here. Used FILE() instead.
      lnSQLHand = SQLSTRINGCONNECT( lcConnstr )
      
      *-- Connect successful if we are here. Extract data...
      lcSQLCmd = [Select * FROM "]+lcNombreHoja+[$"]
      lnSuccess = SQLEXEC( lnSQLHand, lcSQLCmd, [xlResults] )
      IF lnSuccess<0
         lcSQLCmd = [Select * FROM "Hoja1$"]
         lnSuccess = SQLEXEC( lnSQLHand, lcSQLCmd, [xlResults] )
      ENDIF
      
      SQLDISCONNECT( lnSQLHand )
      IF lnSuccess < 0
          LOCAL ARRAY laErr[1]
          AERROR( laErr )
          MESSAGEBOX(laErr(3), 16, 'Atención')
          
          RETURN .F.
      ELSE
         RETURN .T.
      ENDIF
   ENDIF 
ENDIF

RETURN .f.




Saludos desde México, D.F.

integral

unread,
Dec 1, 2014, 4:14:06 PM12/1/14
to publice...@googlegroups.com
Amigo BERNAL :

Gracias por el ejemplo, en verdad buscando en mis archivos encontré un código similar que importa el archivo en EXCEL a una tabla

Pero tiene el mismo problema genera los campos de tipo carácter a  campos tipo Memo... 

TRY
arnuevo = GETFILE()
numeroerror = 0
LOCAL lcXLBook AS STRING, lnSQLHand AS INTEGER, ;
   lcSQLCmd AS STRING, lnSuccess AS INTEGER, ;
   lcConnstr AS STRING
lcXLBook = arnuevo
*--Comprobando el nombre de la hoja activa
sname = createobject("excel.application")
with sname
sname.DisplayAlerts = .F. && prevent Excel from pushing any dialog boxes
sname.workbooks.Open(arnuevo, .F., .T.) && readonly
*sname.APPLICATION.activeworkbook.SAVE
sname.QUIT
RELEASE sname

endwith
lcConnstr = [Driver=] + ;
   [{Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};] + ;
   [DBQ=] + lcXLBook

IF !FILE( lcXLBook )
   MESSAGEBOX ([Archivo excel no encontrado],31,"AVISO")
ENDIF
lnSQLHand = SQLSTRINGCONNECT( lcConnstr )
IF lnSQLHand <0
MESSAGEBOX('Error al conectar a la hoja xls, comunique este error.',48,'')
RETURN
endi
lcSQLCmd = 'Select * FROM "'+nomhoja+'$"'
lnSuccess = SQLEXEC( lnSQLHand, lcSQLCmd, [xlResults] )
IF lnSuccess < 0
   LOCAL ARRAY laErr[1]
   AERROR( laErr )
   SQLDISCONNECT( lnSQLHand )
ENDIF
*--Hasta aqui la importacion del xlsx
*-- Mostrar Resultados
SELECT xlResults
brow
SQLDISCONNECT( lnSQLHand )
CATCH TO oException
numeroerror = oException.errorno
ENDTRY
if numeroerror = 1426
messagebox("El archivo: ' &arnuevo ' esta en uso, se necesita abrir en modo exclusivo; cierrelo.", 0+48,'')
RETURN
endif
if numeroerror != 0
messagebox("Error Nº: "+ALLTRIM(STR(numeroerror )),"Errores en el proceso")
return
ENDIF
release errnuevo

Algún colega que conozca alguna solucion.

atte.,

INTEGRAL 

edgar suarez kummers

unread,
Dec 1, 2014, 5:15:19 PM12/1/14
to publice...@googlegroups.com
Eso que quieres hacer lo logras con WZIMPORT.APP aunque no sé si está permitido que lo incorpores a tus aplicativos comerciales.
 

Héctor Bernal

unread,
Dec 1, 2014, 5:44:24 PM12/1/14
to publice...@googlegroups.com
Edgar,

Buenas tardes. Por lo que he hecho con el WZIMPORT, solo lee archivo excel hasta 2003 por lo que tendría que guardarlos con ese formato (los 2007, 2010, etc) para poder leer desde excel. Por lo que entiendo del compañero Integral, es que quiere hacer una importación directa.



Saludos desde México, D.F.

Víctor Hugo Espínola Domínguez

unread,
Dec 1, 2014, 6:04:54 PM12/1/14
to publice...@googlegroups.com
Hola Integral

Una vez que tengas creado el cursor XlResults puedes insertar en la tabla Reporte.dbf

Insert Into Reporte (Campo1, Campo2, ...) ;
      (Select Campo1, Campo2 ... From XlResults)

Saludos,
Víctor.
Lambaré - Paraguay.

integral

unread,
Dec 2, 2014, 3:20:40 PM12/2/14
to publice...@googlegroups.com
Que tal Amigos :

Gracias por sus comentarios y sugerencias...

Lo que parecia algo simple y rápido pues resulto ser un poco mas complicado de lo parecía

He probado con diferentes comandos y ninguno me da el resultado correcto, IMPORT, APPEND FROM, OBDC...etc...

Tengo un codigo que copia directamente desde la hoja de calculo cada columna a una Tabla...

Pero acabo de descubrir que la hoja de calculo que envian para el proceso viene con Filtros  y columnas ocultas en total consta de 60 columnas y de las cuales 40 estan ocultas y 20 son las visibles. que se deben copiar a la tabla

Al hacer una prueba con el codigo que estoy implementando me di con la sorpresa de ello ya que comienza a copiar desde la columna A 

Alguien conoce alguna solucion...

Atte.,

INTEGRAL

El lunes, 1 de diciembre de 2014 13:06:42 UTC-5, integral escribió:

Jorge Kiernan

unread,
Dec 2, 2014, 4:48:44 PM12/2/14
to publicesvfoxpro
en las interfaces con excel que tengo (y son muchas) primero defino un cursor a la medida de la planilla (si tiene 60 columnas, tendra 60 campos) para luego hacer un append from.(lcfile) type xl5 a lo que se agrega eventualmente una clausula for si quiere levantar solo ciertas filas.
Para evitar sorpresas con el formato de la planilla, ya que puede venir en cualquier formato excel, antes de usarla la abro con el excel y la guardo como otra planilla en formato 5.0, y la importación de la información la hago contra esta otra planilla.
Limitación: la cantidad de filas que maneja esa version de excel, pero siendo que hablamos de interfaces, nunca hay problemas.
En definitiva, muy similar a tu código original, salvo que trabajo no con una tabla pre existente, sino con un 
create cursor micursor (campo1 c(20, campo2 c(20..... tantos campo como haga falta, tipo caracter o numerico según sea (a veces las fechas se empacan un poco) 
¿como guardar el excel en formato 5.0?
abrir la planilla con automatizacion ole, y 
  .ActiveWorkbook.SaveAs(TCPLANILLA2, 39 , "", "", .f., .f.)
donde TCPLANILLA2 en el nuevo nombre que le estas dando, y 39 es el formato en 5.0
Suerte

Enrique Martinez

unread,
Dec 2, 2014, 5:28:03 PM12/2/14
to Comunidad de Visual Foxpro en Español
ArchivoIMP =GETFILE('xls','Archivo de Excel','Abrir',1,'Abrir Archivo de Planilla de Excel') 
varchivo = JUSTFNAME(ArchivoIMP)
APPEND FROM (ArchivoIMP) TYPE XLS 

integral

unread,
Dec 2, 2014, 6:33:46 PM12/2/14
to publice...@googlegroups.com

Gracais a todos por sus comentarios y sugerencias...

Efectivamente de todos el que mejor funciona es utilizando el APPEND FROM , inicialmente no me percate que el archivo de EXCEL tenia varias columnas ocultas y cuando importaba pues los campos eran diferentes utilizando el codigo que adjunto es que me di cuenta de ello. 

Ahora  se debe de tener en cuenta los siguientes puntos.
 
1.  Debemos tener en cuenta que el archivo de EXCEL debe estar guardado en formato 5.0. Para esto, escogemos la opcion 
Libro de Microsoft EXCEL 5.0/95 (*.xls)

2.  Debemos tener en cuenta tambien que la estructura de la hoja de calculo debe ser similar a la de la tabla.. 

Solo faltaría hacer de forma automatizada copiar solo las celdas que están visibles, por ahora los he realizado manualmente pero los usuarios que no conocen el EXCEL van a pedir que con un Click se realice todo el proceso.

PD : ADJUNTO UN CODIGO QUE ENCONTRE Y LO ESTUVE MODIFICANDO...PERO FALTA HACERLE ALGUNOS PEQUEÑOS AJUSTES

Saludos,

INTEGRAL
 

El lunes, 1 de diciembre de 2014 13:06:42 UTC-5, integral escribió:
Importar.txt

integral

unread,
Dec 4, 2014, 4:38:24 PM12/4/14
to publice...@googlegroups.com
Amigos :

Siguiendo con el tema de la importación ahora estoy tratando de importar desde un archivo en Excel que tiene 4 hojas y la 4ta. hoja ces la debo importar...

Estoy utilizando el siguiente codigo :

APPEND FROM (ArchivoIMP) TYPE XLS SHEET "Input"

Pero me indica error de sintaxis.

Alguna sugerencia como correcion.

atte.,

INTEGRAL

El lunes, 1 de diciembre de 2014 13:06:42 UTC-5, integral escribió:
Excel_Sheet_4.jpg

Víctor Hugo Espínola Domínguez

unread,
Dec 4, 2014, 5:11:48 PM12/4/14
to publice...@googlegroups.com
Hola Integral
APPEND FROM FileName | ?[FIELDS FieldList] [FOR lExpression]
   [[TYPE] [DELIMITED [WITH Delimiter | WITH BLANK | WITH TAB
      | WITH CHARACTER Delimiter] | DIF | FW2 | MOD | PDOX | RPD |
      SDF | SYLK | WK1 | WK3 | WKS | WR1 | WRK | CSV | XLS | XL5 
      [SHEET cSheetName] | XL8 [SHEET cSheetName]]] [AS nCodePage]
SHEET se puede usar solo con XL5 o XL8

Saludos,
Víctor.
Lambaré - Paraguay.

integral

unread,
Dec 5, 2014, 11:52:31 AM12/5/14
to publice...@googlegroups.com
Gracias Amigo Victor :

Estabas en lo correcto... Funciono correctamente.

Saludos,

INTEGRAL 

El lunes, 1 de diciembre de 2014 13:06:42 UTC-5, integral escribió:
Reply all
Reply to author
Forward
0 new messages