Importar una planilla de excel

144 views
Skip to first unread message

Carlos R. Veron

unread,
Sep 21, 2015, 3:55:55 PM9/21/15
to Comunidad de Visual Foxpro en Español
Hola grupo, estoy leyendo un planilla de Excel y quiero convertirla a dbf
pero tengo el problema que todas las columnas que son texto me las
pasa al cursor como campos memo. Yo algo lei sobre esto pero no
puedo volver a encontrar esa información. Alguna solución o articulo
para buscar.

Gracias

Este el es código, lo copie desde el portalfox cuando estaba activo.

Local lcXLBook As String, lnSQLHand As Integer, ;
lcSQLCmd As String, lnSuccess As Integer, ;
lcConnstr As String
lcXLBook=thisform.text1.value
*lcXLBook = Getfile('xls, xlsx, xlsm, xlsb', 'Archivo:', 'Aceptar', 0, 'Seleccione una hoja de cálculo')
If Empty(lcXLBook)
Return .F.
Endif

If !File(lcXLBook)
Messagebox("Archivo no encontrado", 16)
Return .F.
Endif

Local oExcel As Excel.Application
m.oExcel = Createobject("Excel.application")

If Vartype(oExcel,.T.)!='O'
Messagebox("No se puede procesar el archivo porque no tiene la aplicación" ;
+ Chr(13) + "Microsoft Excel instalada en su computador.", 16)
m.oExcel = Null
Release oExcel
Return .F.
Endif

m.oExcel.Workbooks.Open(m.lcXLBook)
m.oExcel.Sheets(1).Select

Local oSheet As Object, lcSheet As String
m.oSheet = m.oExcel.ActiveSheet
m.lcSheet = m.oSheet.Name

m.oExcel.Quit()
m.oExcel = Null
Release oSheet, oExcel

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

lcSQLCmd = [Select * FROM "] + m.lcSheet + [$"]
lnSuccess = SQLExec( lnSQLHand, lcSQLCmd, [xlResults] )

If lnSuccess < 0
Local Array laErr[1]
Aerror( laErr ) 
Messagebox(laErr(3), 16)
SQLDisconnect( lnSQLHand )
Return .F.
Endif

Select xlResults
COPY TO resultados.dbf
SQLDisconnect(lnSQLHand)

Jose Ramon Veliz Martinez

unread,
Sep 25, 2015, 10:30:42 PM9/25/15
to Comunidad de Visual Foxpro en Español
Quieres tenerlo en un programa listo para convertir esa misma plantilla o solo es recuperar la informacion.

Si es la misma plantilla siempre, lo que hice fue combinar EXCEL con Acces, en Acces en Datos Externos selecciono vincular los datos a la hoja de Excel. Luego creo una Vista en el proyecto de Vfp que esta conectado siempre a esta hoja de Excel y asi siempre tengo los datos en cualquier momento.

Si es el punto de solo recuperar imformacion puedes salvar la hoja de Excel en version 5.0, luego en VFP creas un cursor con los campos iguales  a la hoja de Excel y simple y sencillamente le das un append from al nombre del archivo Excel.

Saludos

Víctor Hugo Espínola Domínguez

unread,
Sep 26, 2015, 12:14:45 AM9/26/15
to publice...@googlegroups.com
Hola Carlos

>Select xlResults
>COPY TO resultados.dbf

Select xlResults
lnCampos = Afields(laCampos)
For lnCampo = 1 To m.lnCampos
    If m.laCampos[m.lnCampo, 2] == "M"
        Select  Max(Len(Evaluate(m.laCampos[m.lnCampo, 1]))) ;
            From xlResults                                   ;
            Into Array laLen
        laCampos[m.lnCampo, 2] = "C"
        laCampos[m.lnCampo, 3] = m.laLen[1]
    Endif
Endfor

Create Table Resultados.Dbf From Array m.laCampos
Insert Into Resultados Select * From xlResults



Saludos,
Víctor.
Lambaré - Paraguay.

Carton Jeston (9.0.0.7423)

unread,
Sep 26, 2015, 1:59:30 PM9/26/15
to Comunidad de Visual Foxpro en Español
Hace unas semanas estuve mirando diferentes codigos y este era uno de los mas sencillos. Aun no tenia cerrada la "investigacion" y este hilo me viene bien y de paso a ver si hacemos algo definitivo.

Le vi dos problemas, uno era el campo memo que tan brillantemente ha solucionado victor y el otro es que pone .NULL. en campos vacios, por ejemplo en una direccion vacia o en valores numericos que alterarian el resultado una simple suma.

Quizas hay un metodo mas sencillo (siempre lo hay en fox) pero aqui esta una rutina adaptada a lo que ha hecho victor y se añadiria a continuacion de su codigo. Por defecto SET NULL esta OFF pero si por cualquier motivo necesitas tener los datos con null, solo pones set null on antes de la importacion para que la rutina no tenga efecto.


Create Table Resultados.Dbf From Array m.laCampos
Insert Into Resultados Select * From xlResults

If Set("NULL",1)="OFF" && Eliminar .NULL. de la tabla si SET NULL OFF
For lnCampo = 1 To m.
lnCampos
 lcCampo
=m.laCampos[m.lnCampo, 1]
   
If m.laCampos[m.lnCampo, 2] == "N"
     
Replace All  &lcCampo WITH 0 FOR ISNULL(Evaluate(lcCampo))
   
Else
     
Replace All  &lcCampo WITH "" FOR ISNULL(Evaluate(lcCampo))
   
Endif
Endfor
Endif

Lo he puesto para que si es numero ponga un cero y al resto de tipos de campos ponga la cadena vacia. No lo he probado, pero si diera problemas con campos tipo fecha o cualquier otro, simplemente hay que ampliar la rutina cambiando el if por un do case, pero para que hacerlo si ahora vendra algun compañero con un parametro que desconozco y hara obsoleta toda la rutina :)

El ultimo problema que puede presentar este codigo, es que parece que funciona con el driver excel del 2007, mucho mas completo que el 2003. El tema esta es si tienes office 2003 instalado te da un error.

He cambiado esto....

lcConnstr = [Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=] + lcXLBook
por esto otro...
lcConnstr = [Driver={Microsoft Excel Driver (*.xls)};DriverId=790;Dbq=] + lcXLBook

Para mi lo ideal seria no cambiarlo, sino instalar un driver universal (la 790 que usa el codigo) de manera transparente si no existe en el inicio del programa. Otra solucion seria al comprobar si efectivamente esta instalado, ver que version es y poner una u otra cadena. Me imagino que driverid es parte de la solucion, pero por hoy ya no me da tiempo a mirar mas.

un saludo



Reply all
Reply to author
Forward
0 new messages